You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ar...@apache.org on 2018/12/04 10:48:15 UTC

olingo-odata2 git commit: [OLINGO-1183, 1118, 1309, 1313]Multiple JPA issues

Repository: olingo-odata2
Updated Branches:
  refs/heads/master 962d787cc -> 39e00568c


[OLINGO-1183,1118,1309,1313]Multiple JPA issues


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/39e00568
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/39e00568
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/39e00568

Branch: refs/heads/master
Commit: 39e00568c13b5decc124256ecf8a83fa155f496a
Parents: 962d787
Author: Archana Rai <ar...@sap.com>
Authored: Tue Dec 4 16:18:00 2018 +0530
Committer: Archana Rai <ar...@sap.com>
Committed: Tue Dec 4 16:18:00 2018 +0530

----------------------------------------------------------------------
 .../processor/core/ODataExpressionParser.java   |  10 +-
 .../core/ODataJPAResponseBuilderDefault.java    |  36 ++-
 .../processor/core/access/data/JPAEntity.java   |   6 +-
 .../jpa/processor/core/access/data/JPAPage.java |   4 +-
 .../core/access/data/JPAProcessorImpl.java      |  11 +-
 .../core/access/data/JPAQueryBuilder.java       |  46 ++++
 .../processor/core/jpql/JPQLSelectContext.java  |   6 +-
 .../core/ODataJPAResponseBuilderTest.java       |   8 +-
 .../core/access/data/JPAProcessorImplTest.java  | 239 ++++++++++++++++++-
 .../core/access/data/JPAQueryBuilderTest.java   | 125 +++++++++-
 .../core/mock/ODataJPAContextMock.java          |   5 +
 .../ref/listeners/CustomerQueryExtension.java   |  24 +-
 .../core/batch/BatchChangeSetPartImpl.java      |   2 +-
 .../olingo/odata2/core/batch/BatchHelper.java   |   4 +-
 .../odata2/core/debug/DebugInfoRuntime.java     |   4 +-
 .../odata2/core/uri/expression/InfoMethod.java  |   8 +-
 .../core/uri/expression/ParameterSet.java       |   2 +-
 .../uri/expression/ParameterSetCombination.java |   2 +-
 .../helper/ODataMessageTextVerifier.java        |   2 +-
 19 files changed, 495 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
index 78d04ee..25b4f9f 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
@@ -167,9 +167,11 @@ public class ODataExpressionParser {
       case EQ:
         EdmSimpleType type = (EdmSimpleType)((BinaryExpression)whereExpression).getLeftOperand().getEdmType();
         if(EdmSimpleTypeKind.String.getEdmSimpleTypeInstance().isCompatible(type)){
-          return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
+          if(edmMapping== null || (edmMapping!=null && !(((JPAEdmMappingImpl)edmMapping).getJPAType()).isEnum())){
+            return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
               + (!"null".equals(right) ? JPQLStatement.Operator.LIKE : "IS") + JPQLStatement.DELIMITER.SPACE + right
               + ("null".equals(right) ? "" : " ESCAPE '\\'") + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
+          }
         }
         return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
             + (!"null".equals(right) ? JPQLStatement.Operator.EQ : "IS") + JPQLStatement.DELIMITER.SPACE + right
@@ -272,6 +274,8 @@ public class ODataExpressionParser {
         }
       case TOLOWER:
         return String.format("LOWER(%s)", first);
+      case TOUPPER:
+        return String.format("UPPER(%s)", first);
       case STARTSWITH:
         return String.format("%s LIKE CONCAT(%s,'%%') ESCAPE '\\'", first, second);
       case ENDSWITH:
@@ -633,6 +637,10 @@ public class ODataExpressionParser {
       positionalParameters.put(index, (Character)uriLiteral.charAt(0));
     }else if(edmMappedType.equals(UUID.class)){
       positionalParameters.put(index, UUID.fromString(uriLiteral));
+    }else if (edmMappedType.isEnum()) {
+      Class enCl = (Class<? extends Enum>)edmMappedType;
+      positionalParameters.put(index, Enum.valueOf(enCl, 
+          (String) uriLiteral));
     }else {
       positionalParameters.put(index, String.valueOf(uriLiteral));
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
index b8ac74f..693453b 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
@@ -62,6 +62,7 @@ import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAResponseBuilder;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext;
@@ -73,6 +74,7 @@ import org.apache.olingo.odata2.jpa.processor.core.callback.JPATombstoneCallBack
 
 public final class ODataJPAResponseBuilderDefault implements ODataJPAResponseBuilder {
 
+  private static final String COUNT = "count";
   private final ODataJPAContext oDataJPAContext;
 
   public ODataJPAResponseBuilderDefault(final ODataJPAContext context) {
@@ -482,13 +484,7 @@ public final class ODataJPAResponseBuilderDefault implements ODataJPAResponseBui
 
     Integer count = null;
     if (resultsView.getInlineCount() != null) {
-      if ((resultsView.getSkip() != null || resultsView.getTop() != null)) {
-        // when $skip and/or $top is present with $inlinecount
-        count = getInlineCountForNonFilterQueryEntitySet(edmEntityList, resultsView);
-      } else {
-        // In all other cases
-        count = resultsView.getInlineCount() == InlineCount.ALLPAGES ? edmEntityList.size() : null;
-      }
+       count = getInlineCountForNonFilterQueryEntitySet(edmEntityList, resultsView);
     }
 
     try {
@@ -542,6 +538,10 @@ public final class ODataJPAResponseBuilderDefault implements ODataJPAResponseBui
         .replaceAll("\\$skip=.+?(?:&|$)", "")
         .replaceFirst("(?:\\?|&)$", ""); // Remove potentially trailing "?" or "&" left over from remove actions
   }
+  
+  public static boolean isNumeric(String strNum) {
+    return strNum.matches("-?\\d+(\\.\\d+)?");
+}
 
   /*
    * This method handles $inlinecount request. It also modifies the list of results in case of
@@ -552,21 +552,15 @@ public final class ODataJPAResponseBuilderDefault implements ODataJPAResponseBui
     // when $skip and/or $top is present with $inlinecount, first get the total count
     Integer count = null;
     if (resultsView.getInlineCount() == InlineCount.ALLPAGES) {
-      if (resultsView.getSkip() != null || resultsView.getTop() != null) {
-        count = edmEntityList.size();
-        // Now update the list
-        if (resultsView.getSkip() != null) {
-          // Index checks to avoid IndexOutOfBoundsException
-          if (resultsView.getSkip() > edmEntityList.size()) {
-            edmEntityList.clear();
-            return count;
+      count = edmEntityList.size();
+      if (resultsView.getCustomQueryOptions() != null) {
+        String countValue = resultsView.getCustomQueryOptions().get(COUNT);
+        if (countValue != null && isNumeric(countValue)) {
+          count = Integer.parseInt(countValue);
+          resultsView.getCustomQueryOptions().remove(COUNT);
+          if (resultsView.getCustomQueryOptions().size() == 0) {
+            ((UriInfoImpl) resultsView).setCustomQueryOptions(null);
           }
-          edmEntityList.subList(0, resultsView.getSkip()).clear();
-        }
-        if (resultsView.getTop() != null && resultsView.getTop() >= 0 && resultsView.getTop() < edmEntityList.size()) {
-          final List<Map<String, Object>> edmEntitySubList =
-              new ArrayList<Map<String, Object>>(edmEntityList.subList(0, resultsView.getTop()));
-          edmEntityList.retainAll(edmEntitySubList);
         }
       }
     }// Inlinecount of None is handled by default - null

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
index d278e4c..a3f5495 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
@@ -68,7 +68,7 @@ public class JPAEntity {
   private ODataJPAContext oDataJPAContext;
   private OnJPAWriteContent onJPAWriteContent = null;
   private List<String> relatedJPAEntityLink = new ArrayList<String>();
-  public HashMap<String, List<Object>> relatedJPAEntityMap = null;
+  private HashMap<String, List<Object>> relatedJPAEntityMap = null;
   private EdmNavigationProperty viaNavigationProperty;
 
   public JPAEntity(final EdmEntityType oDataEntityType, final EdmEntitySet oDataEntitySet,
@@ -553,6 +553,10 @@ public class JPAEntity {
         java.sql.Time t = entityPropertyValue != null ? 
             new java.sql.Time(((Calendar) entityPropertyValue).getTimeInMillis()) : null;
         method.invoke(entity, t);
+      } else if (parameterType.equals(byte.class)) {
+        byte b = entityPropertyValue != null ? 
+             Byte.parseByte(entityPropertyValue.toString()) : 0;
+        method.invoke(entity, b);
       } else {
         method.invoke(entity, entityPropertyValue);
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
index 4effd5b..4f95e51 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAPage.java
@@ -72,8 +72,8 @@ public class JPAPage implements JPAPaging {
     private List<Object> pagedEntities;
 
     private static class TopSkip {
-      public Integer top;
-      public Integer skip;
+      private Integer top;
+      private Integer skip;
     }
 
     public JPAPageBuilder() {}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
index f2caceb..e8f3070 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
@@ -168,6 +168,9 @@ public class JPAProcessorImpl implements JPAProcessor {
       if (listener != null && listener.isTombstoneSupported()) {
         ODataJPATombstoneContext.setDeltaToken(listener.generateDeltaToken((List<Object>) result, query));
       }
+      if(InlineCount.ALLPAGES.equals(uriParserResultView.getInlineCount())){
+        queryBuilder.getCount(uriParserResultView);
+      }
       return result == null ? new ArrayList<Object>() : result;
     } catch (EdmException e) {
       throw ODataJPARuntimeException.throwException(
@@ -420,11 +423,11 @@ public class JPAProcessorImpl implements JPAProcessor {
         .skipToken(uriParserResultView.getSkipToken());
 
     // $top/$skip with $inlinecount case handled in response builder to avoid multiple DB call
-    if (uriParserResultView.getSkip() != null && uriParserResultView.getInlineCount() == null) {
+    if (uriParserResultView.getSkip() != null) {
       pageBuilder.skip(uriParserResultView.getSkip().intValue());
     }
 
-    if (uriParserResultView.getTop() != null && uriParserResultView.getInlineCount() == null) {
+    if (uriParserResultView.getTop() != null) {
       pageBuilder.top(uriParserResultView.getTop().intValue());
     }
 
@@ -442,11 +445,11 @@ public class JPAProcessorImpl implements JPAProcessor {
         .skipToken(uriParserResultView.getSkipToken());
 
     // $top/$skip with $inlinecount case handled in response builder to avoid multiple DB call
-    if (uriParserResultView.getSkip() != null && uriParserResultView.getInlineCount() == null) {
+    if (uriParserResultView.getSkip() != null) {
       pageBuilder.skip(uriParserResultView.getSkip().intValue());
     }
 
-    if (uriParserResultView.getTop() != null && uriParserResultView.getInlineCount() == null) {
+    if (uriParserResultView.getTop() != null) {
       pageBuilder.top(uriParserResultView.getTop().intValue());
     }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
index d4b8c07..24290bf 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
@@ -22,6 +22,7 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -42,6 +43,7 @@ import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAQueryExtensionEntityListener;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
@@ -102,6 +104,50 @@ public class JPAQueryBuilder {
     return queryInfo;
   }
 
+
+  public void getCount(GetEntitySetUriInfo uriInfo) throws ODataJPARuntimeException {
+    JPAQueryInfo queryInfo = new JPAQueryInfo();
+    Query query = null;
+    UriInfoImpl info = (UriInfoImpl)uriInfo;
+    boolean count = info.isCount();
+    info.setCount(true);
+    try {
+      ODataJPAQueryExtensionEntityListener listener = getODataJPAQueryEntityListener((UriInfo) uriInfo);
+      if (listener != null) {
+        query = listener.getQuery((GetEntitySetCountUriInfo)uriInfo, em);
+        if(query != null){
+          JPQLContextType contextType = determineJPQLContextType(info, UriInfoType.GetEntitySetCount);
+          JPQLContext jpqlContext = buildJPQLContext(contextType, info);
+          JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext).build();
+          jpqlContext.setJPQLStatement(jpqlStatement.toString());
+          query = getParameterizedQueryForListeners(jpqlContext, query);
+        }
+      }
+      if (query == null) {
+        query = buildQuery((UriInfo) uriInfo, UriInfoType.GetEntitySetCount);
+      } else {
+        queryInfo.setTombstoneQuery(true);
+      }
+    } catch (Exception e) {
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+    } finally {
+      JPQLContext.removeJPQLContext();
+      ODataExpressionParser.removePositionalParametersThreadLocal();
+    }
+    queryInfo.setQuery(query);
+    Query countQuery = queryInfo.getQuery();
+    List<Object> countList = countQuery.getResultList();
+    info.setCount(count);
+    if(countList!= null && !countList.isEmpty()){
+      String countNumber = countList.get(0).toString();
+      Map<String, String> customQueryOptions = new HashMap<String, String>();
+      customQueryOptions.put("count", countNumber);
+      info.setCustomQueryOptions(customQueryOptions);
+    }
+  }
+
+
   public Query build(GetEntityUriInfo uriInfo) throws ODataJPARuntimeException {
     Query query = null;
     try {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java
index aa0d98d..d071105 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java
@@ -153,12 +153,12 @@ public class JPQLSelectContext extends JPQLContext implements JPQLSelectContextV
      */
     protected String generateOrderByFileds() throws ODataJPARuntimeException, EdmException {
 
-      if (entitySetView.getOrderBy() != null) {
+      if (entitySetView.getOrderBy() != null  && !isCountOnly) {
 
         return ODataExpressionParser.parseToJPAOrderByExpression(entitySetView.getOrderBy(), getJPAEntityAlias());
 
-      } else if (entitySetView.getTop() != null || entitySetView.getSkip() != null ||
-          pagingRequested == true) {
+      } else if ((entitySetView.getTop() != null || entitySetView.getSkip() != null ||
+          pagingRequested) && !isCountOnly) {
 
         return ODataExpressionParser.parseKeyPropertiesToJPAOrderByExpression(entitySetView.getTargetEntitySet()
             .getEntityType().getKeyProperties(), getJPAEntityAlias());

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
index ebf268f..09f9cc1 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
@@ -57,6 +57,7 @@ import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.api.uri.SelectItem;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAResponseBuilder;
 import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging;
@@ -570,12 +571,17 @@ public class ODataJPAResponseBuilderTest extends JPAEdmTestModelView {
     navigationPropertyList.add(navigationPropertySegment);
     expandList.add(navigationPropertyList);
     // Mocking EntityUriInfo
-    GetEntitySetUriInfo entitySetUriInfo = EasyMock.createMock(GetEntitySetUriInfo.class);
+    UriInfoImpl entitySetUriInfo = EasyMock.createMock(UriInfoImpl.class);
     EasyMock.expect(entitySetUriInfo.getSelect()).andStubReturn(selectItemList);
     EasyMock.expect(entitySetUriInfo.getExpand()).andStubReturn(expandList);
     EasyMock.expect(entitySetUriInfo.getInlineCount()).andStubReturn(InlineCount.ALLPAGES);
     EasyMock.expect(entitySetUriInfo.getSkip()).andStubReturn(new Integer(1));
     EasyMock.expect(entitySetUriInfo.getTop()).andStubReturn(new Integer(2));
+    Map<String, String> customQuery = new HashMap<String, String>();
+    customQuery.put("count", "5");
+    entitySetUriInfo.setCustomQueryOptions(null);
+    EasyMock.expectLastCall().times(1);
+    EasyMock.expect(entitySetUriInfo.getCustomQueryOptions()).andStubReturn(customQuery );
     EasyMock.replay(entitySetUriInfo);
     return entitySetUriInfo;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
index 7e8fccd..297ee02 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
@@ -25,6 +25,7 @@ import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,8 +40,6 @@ import javax.persistence.Query;
 import javax.persistence.TemporalType;
 import javax.persistence.metamodel.Metamodel;
 
-import junit.framework.Assert;
-
 import org.apache.olingo.odata2.api.commons.InlineCount;
 import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
 import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
@@ -48,6 +47,7 @@ import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.edm.EdmEntityType;
 import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
 import org.apache.olingo.odata2.api.edm.EdmMapping;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
 import org.apache.olingo.odata2.api.edm.EdmType;
@@ -64,19 +64,31 @@ import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
 import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
 import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAQueryExtensionEntityListener;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPATransaction;
 import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.SalesOrderHeader;
 import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
 
+import junit.framework.Assert;
+
 public class JPAProcessorImplTest {
 
   // -------------------------------- Common Start ------------------------------------common in
@@ -127,6 +139,48 @@ public class JPAProcessorImplTest {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
     }
   }
+  
+  @Test
+  public void testProcessGetEntitySetUriInfoWithListener() throws EdmException {
+    try {
+      Assert.assertNotNull(objJPAProcessorImpl.process((GetEntitySetUriInfo)mockURIInfoWithTopSkipInlineListener()));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+  
+  @Test
+  public void testProcessGetEntityLinkUriInfo() {
+    try {
+      Assert.assertNotNull(objJPAProcessorImpl.process(getEntityLinkUriInfo()));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+  
+  @Test
+  public void testProcessGetEntitySetLinksUriInfo() {
+    try {
+      Assert.assertNotNull(objJPAProcessorImpl.process(getEntitySetLinksUriInfo()));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+  
+  @Test(expected = ODataJPARuntimeException.class)
+  public void testProcessFunctionImportUriInfo() throws ODataJPARuntimeException {
+    try {
+     objJPAProcessorImpl.process(getFunctionImportUriInfo());
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } 
+  }
 
   @Test
   public void testProcessDeleteUriInfo() {
@@ -184,6 +238,14 @@ public class JPAProcessorImplTest {
   private GetEntityCountUriInfo getEntityCountUriInfo() {
     return getLocalUriInfo();
   }
+  
+  private GetFunctionImportUriInfo getFunctionImportUriInfo() {
+
+    GetFunctionImportUriInfo objUriInfo = EasyMock.createMock(UriInfo.class);
+    EasyMock.expect(objUriInfo.getFunctionImport()).andStubReturn(getLocalEdmFunctionImport());
+    EasyMock.replay(objUriInfo);
+    return objUriInfo;
+  }
 
   private GetEntitySetUriInfo getEntitySetUriInfo() {
 
@@ -203,6 +265,54 @@ public class JPAProcessorImplTest {
     EasyMock.replay(objUriInfo);
     return objUriInfo;
   }
+  
+  private GetEntityLinkUriInfo getEntityLinkUriInfo () {
+
+    UriInfo objUriInfo = EasyMock.createMock(UriInfo.class);
+    EasyMock.expect(objUriInfo.getStartEntitySet()).andStubReturn(getLocalEdmEntitySet());
+    EasyMock.expect(objUriInfo.getTargetEntitySet()).andStubReturn(getLocalEdmEntitySet());
+    EasyMock.expect(objUriInfo.getSelect()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.getOrderBy()).andStubReturn(getOrderByExpression());
+    EasyMock.expect(objUriInfo.getTop()).andStubReturn(getTop());
+    EasyMock.expect(objUriInfo.getSkip()).andStubReturn(getSkip());
+    EasyMock.expect(objUriInfo.getKeyPredicates()).andReturn(getKeyPredicates());
+    EasyMock.expect(objUriInfo.getInlineCount()).andStubReturn(getInlineCount());
+    EasyMock.expect(objUriInfo.getFilter()).andStubReturn(getFilter());
+    EasyMock.expect(objUriInfo.getFunctionImport()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.getCustomQueryOptions()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.getNavigationSegments()).andStubReturn(new ArrayList<NavigationSegment>());
+    EasyMock.replay(objUriInfo);
+    return objUriInfo;
+  }
+  
+  private GetEntitySetLinksUriInfo getEntitySetLinksUriInfo () {
+
+    UriInfoImpl objUriInfo = EasyMock.createMock(UriInfoImpl.class);
+    EasyMock.expect(objUriInfo.getStartEntitySet()).andStubReturn(getLocalEdmEntitySet());
+    EasyMock.expect(objUriInfo.getTargetEntitySet()).andStubReturn(getLocalEdmEntitySet());
+    EasyMock.expect(objUriInfo.getSelect()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.getOrderBy()).andStubReturn(getOrderByExpression());
+    EasyMock.expect(objUriInfo.getTop()).andStubReturn(2);
+    EasyMock.expect(objUriInfo.getSkip()).andStubReturn(1);
+    EasyMock.expect(objUriInfo.getSkipToken()).andReturn("5");
+    EasyMock.expect(objUriInfo.getInlineCount()).andStubReturn(InlineCount.ALLPAGES);
+    EasyMock.expect(objUriInfo.getFilter()).andStubReturn(getFilter());
+    EasyMock.expect(objUriInfo.getFunctionImport()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.isCount()).andStubReturn(false);
+    EasyMock.expect(objUriInfo.getCustomQueryOptions()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.getNavigationSegments()).andStubReturn(new ArrayList<NavigationSegment>());
+    objUriInfo.setCount(true);
+    EasyMock.expectLastCall().times(1);
+    objUriInfo.setCount(false);
+    EasyMock.expectLastCall().times(1);
+    Map<String, String> data = new HashMap<String, String>();
+    data.put("count", "11");
+    objUriInfo.setCustomQueryOptions(data );
+    EasyMock.expectLastCall().times(1);
+    EasyMock.expect(objUriInfo.getCustomQueryOptions()).andStubReturn(data);
+    EasyMock.replay(objUriInfo);
+    return objUriInfo;
+  }
 
   /**
    * @return
@@ -221,6 +331,31 @@ public class JPAProcessorImplTest {
     EasyMock.replay(objUriInfo);
     return objUriInfo;
   }
+  
+  /**
+   * @return
+   * @throws EdmException
+   */
+  private EdmFunctionImport getLocalEdmFunctionImport() {
+    EdmFunctionImport edmFunction = EasyMock.createMock(EdmFunctionImport.class);
+    try {
+      EasyMock.expect(edmFunction.getName()).andStubReturn(SALES_ORDER_HEADERS);
+      EasyMock.expect(edmFunction.getEntityContainer()).andStubReturn(getLocalEdmEntityContainer());
+      EasyMock.expect(edmFunction.getReturnType()).andStubReturn(null);
+      EasyMock.expect(edmFunction.getHttpMethod()).andStubReturn("GET");
+      EasyMock.expect(edmFunction.getParameterNames()).andStubReturn(new ArrayList<String>());
+      JPAEdmMappingImpl mockedEdmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
+    //  ((Mapping) mockedEdmMapping).setInternalName(SALES_ORDER_HEADERS);
+      EasyMock.expect(edmFunction.getMapping()).andStubReturn(mockedEdmMapping);
+      EasyMock.expect(mockedEdmMapping.getInternalName()).andStubReturn(SALES_ORDER_HEADERS);
+      EasyMock.<Class<?>> expect(mockedEdmMapping.getJPAType()).andReturn(SalesOrderHeader.class);
+      EasyMock.replay(mockedEdmMapping);
+      EasyMock.replay(edmFunction);
+    } catch (EdmException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    return edmFunction;
+  }
 
   /**
    * @return
@@ -643,5 +778,105 @@ public class JPAProcessorImplTest {
   }
 
   // -------------------------------- Common End ------------------------------------
+  private UriInfo mockURIInfoWithTopSkipInlineListener() throws EdmException {
+
+    UriInfoImpl objUriInfo = EasyMock.createMock(UriInfoImpl.class);
+    EdmEntityType edmEntityType = EasyMock.createMock(EdmEntityType.class);
+    EasyMock.expect(edmEntityType.getMapping()).andStubReturn((EdmMapping) mockEdmMapping());
+    EdmEntitySet edmEntitySet = EasyMock.createMock(EdmEntitySet.class);
+    EasyMock.expect(edmEntitySet.getEntityType()).andStubReturn(edmEntityType);
+    EasyMock.expect(edmEntityType.getKeyProperties()).andStubReturn(new ArrayList<EdmProperty>());
+    EasyMock.expect(objUriInfo.getStartEntitySet()).andStubReturn(edmEntitySet);
+    EasyMock.expect(objUriInfo.getTargetEntitySet()).andStubReturn(edmEntitySet);
+    EasyMock.expect(objUriInfo.getSelect()).andStubReturn(null);
+    EasyMock.expect(objUriInfo.getOrderBy()).andStubReturn(getOrderByExpression());
+    EasyMock.expect(objUriInfo.getTop()).andStubReturn(1);
+    EasyMock.expect(objUriInfo.getSkip()).andStubReturn(1);
+    EasyMock.expect(objUriInfo.getSkipToken()).andReturn("5");
+    EasyMock.expect(objUriInfo.getFilter()).andStubReturn(getFilter());
+    EasyMock.expect(objUriInfo.getFunctionImport()).andStubReturn(null);
+    Map<String, String> delta = new HashMap<String, String>();
+    delta.put("!deltatoken", "!deltatoken");
+    EasyMock.expect(objUriInfo.getCustomQueryOptions()).andStubReturn(delta );
+    EasyMock.expect(objUriInfo.isCount()).andReturn(false);
+    EasyMock.expect(objUriInfo.getNavigationSegments()).andStubReturn(new ArrayList<NavigationSegment>());
+    EasyMock.expect(objUriInfo.getInlineCount()).andStubReturn(InlineCount.ALLPAGES);
+    objUriInfo.setCount(true);
+    EasyMock.expectLastCall().times(1);
+    objUriInfo.setCount(false);
+    EasyMock.expectLastCall().times(1);
+    Map<String, String> data = new HashMap<String, String>();
+    data.put("count", "11");
+    objUriInfo.setCustomQueryOptions(data );
+    EasyMock.expectLastCall().times(1);
+    EasyMock.replay(edmEntityType, edmEntitySet, objUriInfo);
+    return objUriInfo;
+
+  }
+  
+  private JPAEdmMapping mockEdmMapping() {
+    JPATombstoneExtensionMock tombstone = new JPATombstoneExtensionMock();
+    tombstone.handleDelta(new String("delta"));
+    JPAEdmMappingImpl mockedEdmMapping = new JPAEdmMappingImpl();
+    mockedEdmMapping.setODataJPATombstoneEntityListener(JPAQueryExtensionMock.class);
+    mockedEdmMapping.setODataJPATombstoneEntityListener(JPATombstoneExtensionMock.class);
+    mockedEdmMapping.setInternalName(SALES_ORDER_HEADERS);
+    return mockedEdmMapping;
+  }
+  
+  public static final class JPATombstoneExtensionMock extends ODataJPATombstoneEntityListener {
+    
+    public void handleDelta(final Object entity) {
+      addToDelta(entity, SALES_ORDER_HEADERS);
+    }
 
+    @Override
+    public Query getQuery(GetEntitySetUriInfo resultsView, EntityManager em) throws ODataJPARuntimeException {
+      return null;
+    }
+
+    @Override
+    public String generateDeltaToken(List<Object> deltas, Query query) {
+      return null;
+    }
+    
+  }
+  public static final class JPAQueryExtensionMock extends ODataJPAQueryExtensionEntityListener {
+    Query query = EasyMock.createMock(Query.class);
+
+    @Override
+    public Query getQuery(GetEntityUriInfo uriInfo, EntityManager em) {
+      return query;
+    }
+
+    @Override
+    public Query getQuery(GetEntitySetUriInfo uriInfo, EntityManager em) {
+      return null;
+    }
+
+    @Override
+    public Query getQuery(GetEntitySetCountUriInfo uriInfo, EntityManager em) {
+      return query;
+    }
+
+    @Override
+    public Query getQuery(DeleteUriInfo uriInfo, EntityManager em) {
+      return query;
+    }
+
+    @Override
+    public Query getQuery(GetEntityCountUriInfo uriInfo, EntityManager em) {
+      return query;
+    }
+
+    @Override
+    public Query getQuery(PutMergePatchUriInfo uriInfo, EntityManager em) {
+      return query;
+    }
+
+    @Override
+    public boolean isTombstoneSupported() {
+      return true;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
index e8a7192..27bdc63 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
@@ -24,13 +24,16 @@ import static org.junit.Assert.fail;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
 
+import org.apache.olingo.odata2.api.commons.InlineCount;
 import org.apache.olingo.odata2.api.edm.EdmAssociation;
 import org.apache.olingo.odata2.api.edm.EdmAssociationEnd;
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
@@ -64,6 +67,7 @@ import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAQueryExtensionEntityListener;
 import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
@@ -440,8 +444,30 @@ public class JPAQueryBuilderTest {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
     }
   }
+
+  @Test
+  public void buildQueryGetEntitySetTestWithNormalizationWithtoUpper() {
+    EdmMapping mapping = (EdmMapping) mockNormalizedMapping();
+    try {
+      assertNotNull(builder.build((GetEntitySetUriInfo) 
+          mockURIInfoForEntitySetWithBinaryFilterExpression(mapping, "toUpper")));
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
   
   @Test
+  public void buildQueryGetEntitySetTestWithNoNormalizationWithtoUpper() {
+    EdmMapping mapping = (EdmMapping) mockNormalizedValueMapping();
+    try {
+      assertNotNull(builder.build((GetEntitySetUriInfo) 
+          mockURIInfoForEntitySetWithBinaryFilterExpression(mapping, "toUpper")));
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+    
+  @Test
   public void buildQueryGetEntitySetTestWithNormalizationWithSubstringof1() {
     EdmMapping mapping = (EdmMapping) mockNormalizedMapping1();
     try {
@@ -513,6 +539,28 @@ public class JPAQueryBuilderTest {
   }
   
   @Test
+  public void buildQueryWithTopSkipInline() {
+    EdmMapping mapping = (EdmMapping) mockMapping();
+    try {
+      GetEntitySetUriInfo uriInfo = (GetEntitySetUriInfo) mockURIInfoWithTopSkipInline(mapping);
+      builder.getCount(uriInfo);
+      assertNotNull(uriInfo.getCustomQueryOptions().get("count"));
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void buildQueryWithTopSkipInlineWithListener() {
+    try {
+      GetEntitySetUriInfo uriInfo = (GetEntitySetUriInfo)mockURIInfoWithTopSkipInlineListener();
+      builder.getCount(uriInfo);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+  
+  @Test
   public void buildQueryWithKeyNavSegmentAndFilter() {
     EdmMapping mapping = (EdmMapping) mockMapping();
     try {
@@ -544,7 +592,71 @@ public class JPAQueryBuilderTest {
     EasyMock.replay(edmEntityType, edmEntitySet, uriInfo, keyPreds, edmProperty);
     return uriInfo;
   }
+  
+  @SuppressWarnings("unchecked")
+  private GetEntityUriInfo mockURIInfoWithTopSkipInline(EdmMapping mapping) throws EdmException {
+    UriInfoImpl uriInfo = EasyMock.createMock(UriInfoImpl.class);
+    List<NavigationSegment> navSegments = new ArrayList<NavigationSegment>();
+    EasyMock.expect(uriInfo.getNavigationSegments()).andStubReturn(navSegments);
+    EdmEntityType edmEntityType = EasyMock.createMock(EdmEntityType.class);
+    EasyMock.expect(edmEntityType.getMapping()).andStubReturn(mapping);
+    EdmEntitySet edmEntitySet = EasyMock.createMock(EdmEntitySet.class);
+    EasyMock.expect(edmEntitySet.getEntityType()).andStubReturn(edmEntityType);
+    EasyMock.expect(uriInfo.getTargetEntitySet()).andStubReturn(edmEntitySet);
+    List<KeyPredicate> keyPreds = EasyMock.createMock(ArrayList.class);
+    EasyMock.expect(uriInfo.getKeyPredicates()).andStubReturn(keyPreds); 
+    EasyMock.expect(uriInfo.getOrderBy()).andStubReturn(null);
+    EasyMock.expect(uriInfo.getTop()).andStubReturn(1);
+    EasyMock.expect(uriInfo.getSkip()).andStubReturn(2);
+    EasyMock.expect(uriInfo.isCount()).andStubReturn(false);
+    EasyMock.expect(uriInfo.getInlineCount()).andStubReturn(InlineCount.ALLPAGES);
+    EdmProperty edmProperty = EasyMock.createMock(EdmProperty.class);
+    EasyMock.expect(edmProperty.getMapping()).andStubReturn(mapping);
+    EasyMock.expect(edmEntityType.getKeyProperties()).andStubReturn(Arrays.asList(edmProperty));
+    EasyMock.expect(uriInfo.getFilter()).andStubReturn(null);
+    uriInfo.setCount(true);
+    EasyMock.expectLastCall().times(1);
+    uriInfo.setCount(false);
+    EasyMock.expectLastCall().times(1);
+    Map<String, String> data = new HashMap<String, String>();
+    data.put("count", "5");
+    uriInfo.setCustomQueryOptions(data );
+    EasyMock.expectLastCall().times(1);
+    EasyMock.expect(uriInfo.getCustomQueryOptions()).andStubReturn(data);
+    EasyMock.replay(edmEntityType, edmEntitySet, uriInfo, keyPreds, edmProperty);
+    return uriInfo;
+  }
 
+  
+  private UriInfo mockURIInfoWithTopSkipInlineListener() throws EdmException {
+    UriInfoImpl uriInfo = EasyMock.createMock(UriInfoImpl.class);
+    EdmEntityType edmEntityType = EasyMock.createMock(EdmEntityType.class);
+    EasyMock.expect(edmEntityType.getMapping()).andStubReturn((EdmMapping) mockEdmMapping());
+    EdmEntitySet edmEntitySet = EasyMock.createMock(EdmEntitySet.class);
+    EasyMock.expect(edmEntitySet.getEntityType()).andStubReturn(edmEntityType);
+    EasyMock.expect(uriInfo.getTargetEntitySet()).andStubReturn(edmEntitySet);
+    EasyMock.expect(uriInfo.getNavigationSegments()).andReturn(null);
+    EasyMock.expect(uriInfo.getKeyPredicates()).andStubReturn(null);
+    EasyMock.expect(uriInfo.getStartEntitySet()).andStubReturn(edmEntitySet);
+    EasyMock.expect(uriInfo.getOrderBy()).andStubReturn(null);
+    EasyMock.expect(uriInfo.isCount()).andStubReturn(false);
+    EasyMock.expect(uriInfo.getFilter()).andStubReturn(null);
+    EasyMock.expect(uriInfo.getTop()).andStubReturn(1);
+    EasyMock.expect(uriInfo.getSkip()).andStubReturn(1);
+    EasyMock.expect(uriInfo.getInlineCount()).andStubReturn(InlineCount.ALLPAGES);
+    uriInfo.setCount(true);
+    EasyMock.expectLastCall().times(1);
+    uriInfo.setCount(false);
+    EasyMock.expectLastCall().times(1);
+    Map<String, String> data = new HashMap<String, String>();
+    data.put("count", "5");
+    uriInfo.setCustomQueryOptions(data );
+    EasyMock.expectLastCall().times(1);
+    EasyMock.replay(edmEntityType, edmEntitySet, uriInfo);
+    return uriInfo;
+
+  }
+  
   private UriInfo mockURIInfoWithListener(boolean isNavigationEnabled) throws EdmException {
     UriInfo uriInfo = EasyMock.createMock(UriInfo.class);
     if (isNavigationEnabled) {
@@ -760,7 +872,8 @@ public class JPAQueryBuilderTest {
     EdmProperty edmProperty = mockEdmProperty(mapping, "String");
     keyPreds.add(mockKeyPredicate(edmProperty, "Id"));
     EasyMock.expect(uriInfo.getKeyPredicates()).andStubReturn(keyPreds); 
-    
+    EasyMock.expect(uriInfo.getTop()).andStubReturn(null); 
+    EasyMock.expect(uriInfo.getSkip()).andStubReturn(null); 
     OrderByExpression orderbyExpression = mockOrderByExpressions(uriInfo);
     EasyMock.replay(edmEntityType, edmEntitySet, uriInfo,  
         navEntitySet, orderbyExpression);
@@ -794,6 +907,8 @@ public class JPAQueryBuilderTest {
     List<KeyPredicate> keyPreds =EasyMock.createMock(ArrayList.class);
     EasyMock.expect(uriInfo.getKeyPredicates()).andStubReturn(keyPreds); 
     OrderByExpression orderbyExpression = mockOrderByExpressions(uriInfo);
+    EasyMock.expect(uriInfo.getTop()).andStubReturn(null); 
+    EasyMock.expect(uriInfo.getSkip()).andStubReturn(null); 
     EasyMock.replay(edmEntityType, edmEntitySet, uriInfo, keyPreds,orderbyExpression);
     return uriInfo;
 
@@ -953,6 +1068,14 @@ public class JPAQueryBuilderTest {
       EasyMock.expect(propExp.getKind()).andStubReturn(ExpressionKind.PROPERTY);
       parameterList.add(propExp);
       EasyMock.expect(methodExp.getParameters()).andStubReturn(parameterList);
+    } else if ("toUpper".equals(methodName)) {
+      EasyMock.expect(methodExp.getMethod()).andStubReturn(MethodOperator.TOUPPER);
+      EasyMock.expect(methodExp.getKind()).andStubReturn(ExpressionKind.METHOD);
+      EasyMock.expect(methodExp.getParameterCount()).andStubReturn(1);
+      EasyMock.expect(propExp.getEdmProperty()).andStubReturn(edmProperty);
+      EasyMock.expect(propExp.getKind()).andStubReturn(ExpressionKind.PROPERTY);
+      parameterList.add(propExp);
+      EasyMock.expect(methodExp.getParameters()).andStubReturn(parameterList);
     }
     EasyMock.expect(filterExpression.getExpression()).andStubReturn(commonExpression);
     EasyMock.expect(filterExpression.getKind()).andStubReturn(ExpressionKind.FILTER);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
index 69980e6..95b125f 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
@@ -19,8 +19,10 @@
 package org.apache.olingo.odata2.jpa.processor.core.mock;
 
 import java.sql.Time;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.persistence.EntityManager;
@@ -85,6 +87,9 @@ public abstract class ODataJPAContextMock {
         EasyMock.anyObject(TemporalType.TIMESTAMP.getClass()))).andReturn(jpqlquery).anyTimes();
     EasyMock.expect(jpqlquery.setParameter(EasyMock.anyInt(), (Time) EasyMock.anyObject(), 
         EasyMock.anyObject(TemporalType.TIME.getClass()))).andReturn(jpqlquery).anyTimes();
+    List<Object> result = new ArrayList<Object>();
+    result.add(5);
+    EasyMock.expect(jpqlquery.getResultList()).andReturn(result).anyTimes();
     EasyMock.replay(em, mm, jpqlquery);
     return em;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/CustomerQueryExtension.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/CustomerQueryExtension.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/CustomerQueryExtension.java
index 1babccd..9e05772 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/CustomerQueryExtension.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/listeners/CustomerQueryExtension.java
@@ -24,6 +24,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.Query;
 
 import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAQueryExtensionEntityListener;
@@ -45,6 +46,27 @@ public class CustomerQueryExtension extends ODataJPAQueryExtensionEntityListener
   }
 
   @Override
+  public Query getQuery(GetEntitySetCountUriInfo uriInfo, EntityManager em) throws ODataJPARuntimeException {
+    Query query = null;
+    JPQLContextType contextType = null;
+    if (uriInfo.getNavigationSegments().size() > 0) {
+      contextType = JPQLContextType.JOIN_SINGLE;
+    } else {
+      contextType = JPQLContextType.SELECT_COUNT;
+    }
+    JPQLContext jpqlContext;
+    try {
+      jpqlContext = JPQLContext.createBuilder(contextType, uriInfo).build();
+      query = em.createQuery(JPQLStatement.createBuilder(jpqlContext).build().toString());
+    } catch (ODataJPAModelException e) {
+      // Log and return null query object;
+    } catch (ODataJPARuntimeException e) {
+      // Log and return null query object;
+    }
+    return query;
+  }
+  
+  @Override
   public Query getQuery(GetEntityUriInfo uriInfo, EntityManager em) {
     Query query = null;
     JPQLContextType contextType = null;
@@ -62,7 +84,7 @@ public class CustomerQueryExtension extends ODataJPAQueryExtensionEntityListener
     } catch (ODataJPARuntimeException e) {
       // Log and return null query object;
     }
-    return null;
+    return query;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchChangeSetPartImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchChangeSetPartImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchChangeSetPartImpl.java
index 3df9884..be88a0b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchChangeSetPartImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchChangeSetPartImpl.java
@@ -30,7 +30,7 @@ public class BatchChangeSetPartImpl extends BatchChangeSetPart {
   private Map<String, String> headers = new HashMap<String, String>();
   private Object body;
   private String uri;
-  public String cntId;
+  private String cntId;
   private static final String CHANGE_METHODS = "(PUT|POST|DELETE|MERGE|PATCH)";
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHelper.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHelper.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHelper.java
index 42cd445..3d2b78f 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHelper.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHelper.java
@@ -42,13 +42,13 @@ public class BatchHelper {
   public static final String BINARY_ENCODING = "binary";
   public static final String UTF8_ENCODING = "UTF-8";
   public static final String ISO_ENCODING = "ISO-8859-1";
-  public static String DEFAULT_ENCODING = "ISO-8859-1";
+  private static String DEFAULT_ENCODING = "ISO-8859-1";
   public static final String HTTP_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
   public static final String HTTP_CONTENT_ID = "Content-Id";
   public static final String MIME_HEADER_CONTENT_ID = "MimeHeader-ContentId";
   public static final String REQUEST_HEADER_CONTENT_ID = "RequestHeader-ContentId";
 
-  public static Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_ENCODING);
+  protected static Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_ENCODING);
 
   protected static String generateBoundary(final String value) {
     return value + "_" + UUID.randomUUID().toString();

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoRuntime.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoRuntime.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoRuntime.java
index 90fdd37..e0a9ca3 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoRuntime.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoRuntime.java
@@ -38,8 +38,8 @@ public class DebugInfoRuntime implements DebugInfo {
     protected long timeStarted;
     protected long timeStopped;
     protected List<RuntimeNode> children = new ArrayList<RuntimeNode>();
-    public long memoryStarted;
-    public long memoryStopped;
+    protected long memoryStarted;
+    protected long memoryStopped;
 
     protected RuntimeNode() {
       timeStarted = 0;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/InfoMethod.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/InfoMethod.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/InfoMethod.java
index 400cbd0..4969aca 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/InfoMethod.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/InfoMethod.java
@@ -29,10 +29,10 @@ import org.apache.olingo.odata2.api.uri.expression.MethodOperator;
  */
 class InfoMethod {
 
-  public MethodOperator method;
-  public String syntax;
-  public int minParameter;
-  public int maxParameter;
+  private MethodOperator method;
+  private String syntax;
+  private int minParameter;
+  private int maxParameter;
   ParameterSetCombination combination;
 
   public InfoMethod(final MethodOperator method, final ParameterSetCombination combination) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
index b9ce742..1a375ee 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
@@ -36,7 +36,7 @@ import org.apache.olingo.odata2.api.edm.EdmTypeKind;
 @SuppressWarnings("javadoc")
 public class ParameterSet {
   private EdmType returnType = null;
-  public ArrayList<EdmSimpleType> types = new ArrayList<EdmSimpleType>();
+  private ArrayList<EdmSimpleType> types = new ArrayList<EdmSimpleType>();
   private EdmSimpleType furtherType = null;
 
   public ParameterSet(final EdmType returnType, final EdmSimpleType type1) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
index 72c8b54..9a6d05c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
@@ -34,7 +34,7 @@ public interface ParameterSetCombination {
   EdmType getReturnType();
 
   public static class PSCflex implements ParameterSetCombination {
-    public List<ParameterSet> combinations = new ArrayList<ParameterSet>();
+    private List<ParameterSet> combinations = new ArrayList<ParameterSet>();
 
     @Override
     public void add(final ParameterSet parameterSet) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e00568/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/ODataMessageTextVerifier.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/ODataMessageTextVerifier.java b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/ODataMessageTextVerifier.java
index 2f510bc..e78d6f0 100644
--- a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/ODataMessageTextVerifier.java
+++ b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/helper/ODataMessageTextVerifier.java
@@ -47,7 +47,7 @@ public class ODataMessageTextVerifier {
   private static final String BUNDLE_NAME = "i18n"; //$NON-NLS-1$
   private static final Locale locale = Locale.ROOT;
 
-  public ResourceBundle resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME, locale);
+  private ResourceBundle resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME, locale);
   private final List<Throwable> errorCollector;
 
   public ODataMessageTextVerifier() {