You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/10/22 10:08:56 UTC

[2/2] olingo-odata4 git commit: [OLINGO-801] better enum and alias support in technical service

[OLINGO-801] better enum and alias support in technical service


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/23fb86a8
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/23fb86a8
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/23fb86a8

Branch: refs/heads/master
Commit: 23fb86a870ce1c85b2a41ea6612a5749385e8fe2
Parents: 4134b2e8
Author: Michael Bolz <mi...@sap.com>
Authored: Thu Oct 22 10:04:49 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Oct 22 10:04:49 2015 +0200

----------------------------------------------------------------------
 .../tecsvc/client/FilterSystemQueryITCase.java  |  8 ++-
 .../processor/TechnicalEntityProcessor.java     | 18 +++---
 .../ExpandSystemQueryOptionHandler.java         | 29 +++++-----
 .../expression/ExpressionVisitorImpl.java       | 44 ++++++++++-----
 .../expression/operand/TypedOperand.java        | 59 +++++++++++---------
 .../expression/operand/UntypedOperand.java      | 33 +++++++----
 .../expression/operand/VisitorOperand.java      |  2 +-
 .../expression/operation/BinaryOperator.java    | 17 ++++--
 .../queryoptions/options/FilterHandler.java     | 27 ++++-----
 .../queryoptions/options/OrderByHandler.java    | 27 ++++-----
 10 files changed, 156 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
index 2045802..aa22966 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.fit.tecsvc.client;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.net.URI;
 import java.util.LinkedHashMap;
@@ -41,6 +42,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
   private static final String ES_COMP_ALL_PRIM = "ESCompAllPrim";
   private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
   private static final String ES_ALL_PRIM = "ESAllPrim";
+  private static final String ES_MIX_ENUM_DEF_COLL_COMP = "ESMixEnumDefCollComp";
 
   @Test
   public void timeOfDayLiteral() {
@@ -184,6 +186,9 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
     clientEntity = result.getBody().getEntities().get(1);
     assertShortOrInt(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
     assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue());
+
+    result = sendRequest(ES_MIX_ENUM_DEF_COLL_COMP, "PropertyEnumString has Namespace1_Alias.ENString'String1'");
+    assertTrue(result.getBody().getEntities().isEmpty());
   }
 
   @Test
@@ -994,7 +999,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
     result = sendRequest(ES_ALL_PRIM, "'Test1' ne 'Test'");
     assertEquals(3, result.getBody().getEntities().size());
   }
-  
+
   @Test
   public void castException() {
     fail("ESAllPrim", "PropertyInt16 eq '1'", HttpStatusCode.BAD_REQUEST);
@@ -1004,7 +1009,6 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
     fail("ESAllPrim", "PropertyInt16 eq duration'PT4S'", HttpStatusCode.BAD_REQUEST);
   }
 
-  
   @Test
   public void stringFunctionWithoutStringParameters() {
     fail("ESServerSidePaging", "contains(PropertyInt16, 3) eq 'hallo'", HttpStatusCode.BAD_REQUEST);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 95bcdc7..74cdd51 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -91,15 +91,15 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
   }
 
   @Override
-  public void countEntityCollection(final ODataRequest request, final ODataResponse response, final UriInfo
-      uriInfo) throws ODataApplicationException, ODataLibraryException {
+  public void countEntityCollection(final ODataRequest request, final ODataResponse response,
+      final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
     validateOptions(uriInfo.asUriInfoResource());
-    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo); // including checks
+    getEdmEntitySet(uriInfo); // including checks
     final EntityCollection entitySetInitial = readEntityCollection(uriInfo);
     EntityCollection entitySet = new EntityCollection();
 
     entitySet.getEntities().addAll(entitySetInitial.getEntities());
-    FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
+    FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, uriInfo, serviceMetadata.getEdm());
     response.setContent(odata.createFixedFormatSerializer().count(
         entitySet.getEntities().size()));
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
@@ -430,7 +430,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
 
     final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
     final Entity entitySerialization = expandHandler.transformEntityGraphToTree(entity, edmEntitySet, expand);
-    expandHandler.applyExpandQueryOptions(entitySerialization, edmEntitySet, expand);
+    expandHandler.applyExpandQueryOptions(entitySerialization, edmEntitySet, expand, uriInfo,
+        serviceMetadata.getEdm());
 
     final SerializerResult serializerResult = isReference ?
         serializeReference(entity, edmEntitySet, requestedFormat) :
@@ -480,9 +481,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     entitySet.getEntities().addAll(entitySetInitial.getEntities());
 
     // Apply system query options
-    FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
+    FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, uriInfo, serviceMetadata.getEdm());
     CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
-    OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, edmEntitySet);
+    OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, uriInfo, serviceMetadata.getEdm());
     SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
     TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
 
@@ -505,7 +506,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     final EntityCollection entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
         edmEntitySet,
         expand);
-    expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
+    expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand, uriInfo,
+        serviceMetadata.getEdm());
     final CountOption countOption = uriInfo.getCountOption();
 
     String id;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
index e0faf41..4cc88f8 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
@@ -27,6 +27,7 @@ import java.util.Set;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
 import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmBindingTarget;
 import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
@@ -35,6 +36,7 @@ import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriInfoResource;
 import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.queryoption.CountOption;
@@ -53,29 +55,28 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler
 public class ExpandSystemQueryOptionHandler {
 
   public void applyExpandQueryOptions(final EntityCollection entitySet, final EdmEntitySet edmEntitySet,
-      final ExpandOption expandOption) throws ODataApplicationException {
+      final ExpandOption expandOption, final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
     if (expandOption == null) {
       return;
     }
 
     for (final Entity entity : entitySet.getEntities()) {
-      applyExpandOptionToEntity(entity, edmEntitySet, expandOption);
+      applyExpandOptionToEntity(entity, edmEntitySet, expandOption, uriInfo, edm);
     }
   }
 
   public void applyExpandQueryOptions(final Entity entity, final EdmEntitySet edmEntitySet,
-      final ExpandOption expandOption)
-      throws ODataApplicationException {
+      final ExpandOption expandOption, final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
     if (expandOption == null) {
       return;
     }
 
-    applyExpandOptionToEntity(entity, edmEntitySet, expandOption);
+    applyExpandOptionToEntity(entity, edmEntitySet, expandOption, uriInfo, edm);
   }
 
   private void applyExpandOptionToEntity(final Entity entity, final EdmBindingTarget edmBindingTarget,
-      final ExpandOption expandOption) throws ODataApplicationException {
-    
+      final ExpandOption expandOption, final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
+
     final EdmEntityType entityType = edmBindingTarget.getEntityType();
 
     for (ExpandItem item : expandOption.getExpandItems()) {
@@ -103,7 +104,7 @@ public class ExpandSystemQueryOptionHandler {
         }
       }
 
-      for(EdmNavigationProperty navigationProperty: navigationProperties) {
+      for (EdmNavigationProperty navigationProperty: navigationProperties) {
         final String navPropertyName = navigationProperty.getName();
         final EdmBindingTarget targetEdmEntitySet = edmBindingTarget.getRelatedBindingTarget(navPropertyName);
 
@@ -116,7 +117,8 @@ public class ExpandSystemQueryOptionHandler {
               item.getCountOption(),
               item.getSkipOption(),
               item.getTopOption(),
-              item.getExpandOption());
+              item.getExpandOption(),
+              uriInfo, edm);
         }
       }
     }
@@ -125,11 +127,12 @@ public class ExpandSystemQueryOptionHandler {
   private void applyOptionsToEntityCollection(final EntityCollection entitySet,
       final EdmBindingTarget edmBindingTarget,
       final FilterOption filterOption, final OrderByOption orderByOption, final CountOption countOption,
-      final SkipOption skipOption, final TopOption topOption, final ExpandOption expandOption)
+      final SkipOption skipOption, final TopOption topOption, final ExpandOption expandOption,
+      final UriInfoResource uriInfo, final Edm edm)
       throws ODataApplicationException {
 
-    FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmBindingTarget);
-    OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmBindingTarget);
+    FilterHandler.applyFilterSystemQuery(filterOption, entitySet, uriInfo, edm);
+    OrderByHandler.applyOrderByOption(orderByOption, entitySet, uriInfo, edm);
     CountHandler.applyCountSystemQueryOption(countOption, entitySet);
     SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet);
     TopHandler.applyTopSystemQueryOption(topOption, entitySet);
@@ -137,7 +140,7 @@ public class ExpandSystemQueryOptionHandler {
     // Apply nested expand system query options to remaining entities
     if (expandOption != null) {
       for (final Entity entity : entitySet.getEntities()) {
-        applyExpandOptionToEntity(entity, edmBindingTarget, expandOption);
+        applyExpandOptionToEntity(entity, edmBindingTarget, expandOption, uriInfo, edm);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
index 969a754..b362456 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
@@ -23,8 +23,9 @@ import java.util.Locale;
 
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.EdmBindingTarget;
+import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
@@ -48,16 +49,19 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operati
 
 public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> {
 
-  final private Entity entity;
+  private final Entity entity;
+  private final UriInfoResource uriInfo;
+  private final Edm edm;
 
-  public ExpressionVisitorImpl(final Entity entity, final EdmBindingTarget bindingTarget) {
+  public ExpressionVisitorImpl(final Entity entity, final UriInfoResource uriInfo, final Edm edm) {
     this.entity = entity;
+    this.uriInfo = uriInfo;
+    this.edm = edm;
   }
 
   @Override
   public VisitorOperand visitBinaryOperator(final BinaryOperatorKind operator, final VisitorOperand left,
-      final VisitorOperand right)
-      throws ExpressionVisitException, ODataApplicationException {
+      final VisitorOperand right) throws ExpressionVisitException, ODataApplicationException {
 
     final BinaryOperator binaryOperator = new BinaryOperator(left, right);
 
@@ -84,6 +88,9 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
     case DIV:
     case MOD:
       return binaryOperator.arithmeticOperator(operator);
+    case HAS:
+      return binaryOperator.hasOperator();
+
     default:
       return throwNotImplemented();
     }
@@ -161,15 +168,13 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
 
   @Override
   public VisitorOperand visitLambdaExpression(final String lambdaFunction, final String lambdaVariable,
-      final Expression expression)
-      throws ExpressionVisitException, ODataApplicationException {
-
+      final Expression expression) throws ExpressionVisitException, ODataApplicationException {
     return throwNotImplemented();
   }
 
   @Override
   public VisitorOperand visitLiteral(final Literal literal) throws ExpressionVisitException, ODataApplicationException {
-    return new UntypedOperand(literal.getText());
+    return new UntypedOperand(literal.getText(), edm);
   }
 
   @Override
@@ -204,12 +209,12 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
 
   @Override
   public VisitorOperand visitAlias(final String aliasName) throws ExpressionVisitException, ODataApplicationException {
-    return throwNotImplemented();
+    return new UntypedOperand(uriInfo.getValueForAlias(aliasName), edm);
   }
 
   @Override
-  public VisitorOperand visitTypeLiteral(final EdmType type) throws ExpressionVisitException, 
-      ODataApplicationException {
+  public VisitorOperand visitTypeLiteral(final EdmType type)
+      throws ExpressionVisitException, ODataApplicationException {
     return throwNotImplemented();
   }
 
@@ -221,9 +226,18 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
 
   @Override
   public VisitorOperand visitEnum(final EdmEnumType type, final List<String> enumValues)
-      throws ExpressionVisitException,
-      ODataApplicationException {
-    return throwNotImplemented();
+      throws ExpressionVisitException, ODataApplicationException {
+    Long result = null;
+    try {
+      for (final String enumValue : enumValues) {
+        final Long value = type.valueOfString(enumValue, null, null, null, null, null, Long.class);
+        result = result == null ? value : result | value;
+      }
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataApplicationException("Illegal enum value.",
+          HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT, e);
+    }
+    return new TypedOperand(result, type);
   }
 
   private VisitorOperand throwNotImplemented() throws ODataApplicationException {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/TypedOperand.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/TypedOperand.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/TypedOperand.java
index 11cf3ab..fc36f96 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/TypedOperand.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/TypedOperand.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand;
 
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.Locale;
 
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
@@ -54,38 +55,44 @@ public class TypedOperand extends VisitorOperand {
   }
 
   @Override
-  public TypedOperand asTypedOperand(final EdmPrimitiveType... asTypes) throws ODataApplicationException {
+  public TypedOperand asTypedOperand(final EdmPrimitiveType asType) throws ODataApplicationException {
     if (is(primNull)) {
       return this;
     } else if (isNull()) {
-      return new TypedOperand(null, asTypes[0]);
+      return new TypedOperand(null, asType);
     }
 
     Object newValue = null;
-    for (EdmPrimitiveType asType : asTypes) {
-      // Use BigDecimal for unlimited precision
-      if (asType.equals(primDouble) || asType.equals(primSingle) || asType.equals(primDecimal)) {
-
-        try {
-          newValue = new BigDecimal(value.toString());
-        } catch (NumberFormatException e) {
-          // Nothing to do
-        }
-      } else {
-        // Use type conversion of EdmPrimitive types
-        try {
-          final String literal = getLiteral(value);
-          newValue = tryCast(literal, asType);
-        } catch (EdmPrimitiveTypeException e) {
-          // Nothing to do
-        }
+    // Use BigInteger for arbitrarily large whole numbers.
+    if (asType.equals(primSByte) || asType.equals(primByte)
+        || asType.equals(primInt16) || asType.equals(primInt32) || asType.equals(primInt64)) {
+      if (value instanceof BigInteger) {
+        newValue = value;
+      } else if (value instanceof Byte || value instanceof Short
+          || value instanceof Integer || value instanceof Long) {
+        newValue = BigInteger.valueOf(((Number) value).longValue());
       }
-
-      if (newValue != null) {
-        return new TypedOperand(newValue, asType);
+    // Use BigDecimal for unlimited precision.
+    } else if (asType.equals(primDouble) || asType.equals(primSingle) || asType.equals(primDecimal)) {
+      try {
+        newValue = new BigDecimal(value.toString());
+      } catch (NumberFormatException e) {
+        // Nothing to do
+      }
+    } else {
+      // Use type conversion of EdmPrimitive types
+      try {
+        final String literal = getLiteral(value);
+        newValue = tryCast(literal, asType);
+      } catch (EdmPrimitiveTypeException e) {
+        // Nothing to do
       }
     }
 
+    if (newValue != null) {
+      return new TypedOperand(newValue, asType);
+    }
+
     throw new ODataApplicationException("Cast failed", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
   }
 
@@ -93,11 +100,9 @@ public class TypedOperand extends VisitorOperand {
     final TypedOperand other = otherOperand.asTypedOperand();
     final EdmType oType = other.getType();
     
-    // In case of numberic values make sure that the EDM type is equals, check also the java type.
-    // So it is possible, that there is an conversation even if the same
-    // EdmType is provided.
-    // For example consider an Edm16 (internal Integer) and Edm16(internal
-    // Short)
+    // In case of numberic values make sure that the EDM type is equal, check also the java type.
+    // It is possible that there is an conversion even if the same EdmType is provided.
+    // For example consider an Edm.Int32 (internal Integer) and an Edm.Int16 (internal Short) value:
     // shortInstance.equals(intInstance) will always be false!
     if (type == oType && value != null && other.getValue() != null
         && value.getClass() == other.getValue().getClass()) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/UntypedOperand.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/UntypedOperand.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/UntypedOperand.java
index ffc4a62..755d8d1 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/UntypedOperand.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/UntypedOperand.java
@@ -20,15 +20,21 @@ package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operan
 
 import java.util.Locale;
 
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmEnumType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmSchema;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.api.ODataApplicationException;
 
 public class UntypedOperand extends VisitorOperand {
 
-  public UntypedOperand(final String literal) {
+  private final Edm edm;
+
+  public UntypedOperand(final String literal, final Edm edm) {
     super(literal);
+    this.edm = edm;
   }
 
   @Override
@@ -37,22 +43,18 @@ public class UntypedOperand extends VisitorOperand {
   }
 
   @Override
-  public TypedOperand asTypedOperand(final EdmPrimitiveType... types) throws ODataApplicationException {
+  public TypedOperand asTypedOperand(final EdmPrimitiveType type) throws ODataApplicationException {
     final String literal = (String) value;
     Object newValue = null;
 
-    // First try the null literal
+    // First try the null literal.
     if ((newValue = tryCast(literal, primNull)) != null) {
       return new TypedOperand(newValue, primNull);
     }
 
-    // Than try the given types
-    for (EdmPrimitiveType type : types) {
-      newValue = tryCast(literal, type);
-
-      if (newValue != null) {
-        return new TypedOperand(newValue, type);
-      }
+    // Then try the given type.
+    if ((newValue = tryCast(literal, type)) != null) {
+      return new TypedOperand(newValue, type);
     }
 
     throw new ODataApplicationException("Cast failed", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(),
@@ -130,6 +132,17 @@ public class UntypedOperand extends VisitorOperand {
       return new TypedOperand(newValue, primDouble);
     }
 
+    // Enum
+    final EdmSchema schema = edm.getSchema(edm.getEntityContainer().getNamespace());
+    final String enumValue = schema.getAlias() != null && literal.startsWith(schema.getAlias()) ?
+        literal.replace(schema.getAlias(), schema.getNamespace()) :
+        literal;
+    for (final EdmEnumType enumType : schema.getEnumTypes()) {
+      if ((newValue = tryCast(enumValue, enumType)) != null) {
+        return new TypedOperand(newValue, enumType);
+      }        
+    }
+
     throw new ODataApplicationException("Could not determine type for literal " + literal,
         HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/VisitorOperand.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/VisitorOperand.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/VisitorOperand.java
index bc4bfd5..c06b6bb 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/VisitorOperand.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operand/VisitorOperand.java
@@ -85,7 +85,7 @@ public abstract class VisitorOperand {
 
   public abstract TypedOperand asTypedOperand() throws ODataApplicationException;
 
-  public abstract TypedOperand asTypedOperand(EdmPrimitiveType... types) throws ODataApplicationException;
+  public abstract TypedOperand asTypedOperand(EdmPrimitiveType type) throws ODataApplicationException;
 
   public abstract EdmProperty getEdmProperty();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/BinaryOperator.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/BinaryOperator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/BinaryOperator.java
index 9ff1bc2..5c24127 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/BinaryOperator.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/BinaryOperator.java
@@ -168,7 +168,15 @@ public class BinaryOperator {
     return new TypedOperand(result, primBoolean);
   }
 
-  @SuppressWarnings({ "rawtypes", "unchecked" })
+  public VisitorOperand hasOperator() throws ODataApplicationException {
+    final boolean result = isBinaryComparisonNecessary()
+        && !left.getTypedValue(BigInteger.class).equals(BigInteger.ZERO)
+        && left.getTypedValue(BigInteger.class).and(BigInteger.valueOf(right.getTypedValue(Number.class).longValue()))
+            .equals(BigInteger.valueOf(right.getTypedValue(Number.class).longValue()));
+    return new TypedOperand(result, primBoolean);
+  }
+
+  @SuppressWarnings("unchecked")
   private boolean binaryComparison(final int... expect) {
     int result;
 
@@ -180,13 +188,14 @@ public class BinaryOperator {
         result = left.getTypedValue(BigInteger.class).compareTo(right.getTypedValue(BigInteger.class));
       } else if (left.isDecimalType()) {
         result = left.getTypedValue(BigDecimal.class).compareTo(right.getTypedValue(BigDecimal.class));
-      } else if(left.getValue().getClass() == right.getValue().getClass() && left.getValue() instanceof Comparable) {
-        result = ((Comparable)left.getValue()).compareTo(right.getValue());
+      } else if(left.getValue().getClass() == right.getValue().getClass()
+          && left.getValue() instanceof Comparable<?>) {
+        result = ((Comparable<Object>) left.getValue()).compareTo(right.getValue());
       } else {
         result = left.getValue().equals(right.getValue()) ? 0 : 1;
       }
     } 
-    
+
     for (int expectedValue : expect) {
       if (expectedValue == result) {
         return true;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
index 5f5c9df..b2bd405 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
@@ -23,12 +23,13 @@ import java.util.Locale;
 
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.edm.EdmBindingTarget;
+import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriInfoResource;
 import org.apache.olingo.server.api.uri.queryoption.FilterOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
 import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.ExpressionVisitorImpl;
@@ -37,16 +38,11 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand
 
 public class FilterHandler {
 
-  protected static final OData oData;
-  protected static final EdmPrimitiveType primBoolean;
-
-  static {
-    oData = OData.newInstance();
-    primBoolean = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean);
-  }
+  protected static final EdmPrimitiveType primBoolean =
+      OData.newInstance().createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean);
 
   public static void applyFilterSystemQuery(final FilterOption filterOption, final EntityCollection entitySet,
-      final EdmBindingTarget edmEntitySet) throws ODataApplicationException {
+      final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
 
     if (filterOption == null) {
       return;
@@ -57,16 +53,17 @@ public class FilterHandler {
 
       while (iter.hasNext()) {
         final VisitorOperand operand = filterOption.getExpression()
-            .accept(new ExpressionVisitorImpl(iter.next(), edmEntitySet));
+            .accept(new ExpressionVisitorImpl(iter.next(), uriInfo, edm));
         final TypedOperand typedOperand = operand.asTypedOperand();
-        
-        if(typedOperand.is(primBoolean)) {
-          if(Boolean.FALSE.equals(typedOperand.getTypedValue(Boolean.class))) {
+
+        if (typedOperand.is(primBoolean)) {
+          if (Boolean.FALSE.equals(typedOperand.getTypedValue(Boolean.class))) {
             iter.remove();
           }
         } else {
-          throw new ODataApplicationException("Invalid filter expression. Filter expressions must return a value of " 
-                + "type Edm.Boolean", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
+          throw new ODataApplicationException(
+              "Invalid filter expression. Filter expressions must return a value of type Edm.Boolean",
+              HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
         }
       }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/23fb86a8/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
index ce472ba..ad1d2d5 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
@@ -24,9 +24,10 @@ import java.util.Locale;
 
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.edm.EdmBindingTarget;
+import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriInfoResource;
 import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
 import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
@@ -35,43 +36,43 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand
 
 public class OrderByHandler {
   public static void applyOrderByOption(final OrderByOption orderByOption, final EntityCollection entitySet,
-      final EdmBindingTarget edmBindingTarget) throws ODataApplicationException {
+      final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
 
     if (orderByOption == null) {
       return;
     }
 
     try {
-      applyOrderByOptionInternal(orderByOption, entitySet, edmBindingTarget);
+      applyOrderByOptionInternal(orderByOption, entitySet, uriInfo, edm);
     } catch (SystemQueryOptionsRuntimeException e) {
       if (e.getCause() instanceof ODataApplicationException) {
         // Throw the nested exception, to send the correct HTTP status code in the HTTP response
         throw (ODataApplicationException) e.getCause();
       } else {
-        throw new ODataApplicationException("Exception in orderBy evaluation", HttpStatusCode.INTERNAL_SERVER_ERROR
-            .getStatusCode(), Locale.ROOT);
+        throw new ODataApplicationException("Exception in orderBy evaluation",
+            HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
       }
     }
   }
 
   private static void applyOrderByOptionInternal(final OrderByOption orderByOption, final EntityCollection entitySet,
-      final EdmBindingTarget edmBindingTarget) throws ODataApplicationException {
+      final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
     Collections.sort(entitySet.getEntities(), new Comparator<Entity>() {
       @Override
-      @SuppressWarnings({ "unchecked", "rawtypes" })
+      @SuppressWarnings("unchecked")
       public int compare(final Entity e1, final Entity e2) {
-        // Evaluate the first order option for both entity
-        // If and only if the result of the previous order option is equals to 0
-        // evaluate the next order option until all options are evaluated or they are not equals
+        // Evaluate the first order option for both entities.
+        // If and only if the result of the previous order option is equal to 0
+        // evaluate the next order option until all options are evaluated or they are not equal.
         int result = 0;
 
         for (int i = 0; i < orderByOption.getOrders().size() && result == 0; i++) {
           try {
             final OrderByItem item = orderByOption.getOrders().get(i);
             final TypedOperand op1 =
-                item.getExpression().accept(new ExpressionVisitorImpl(e1, edmBindingTarget)).asTypedOperand();
+                item.getExpression().accept(new ExpressionVisitorImpl(e1, uriInfo, edm)).asTypedOperand();
             final TypedOperand op2 =
-                item.getExpression().accept(new ExpressionVisitorImpl(e2, edmBindingTarget)).asTypedOperand();
+                item.getExpression().accept(new ExpressionVisitorImpl(e2, uriInfo, edm)).asTypedOperand();
 
             if (op1.isNull() || op2.isNull()) {
               if (op1.isNull() && op2.isNull()) {
@@ -84,7 +85,7 @@ public class OrderByHandler {
               Object o2 = op2.getValue();
 
               if (o1.getClass() == o2.getClass() && o1 instanceof Comparable) {
-                result = ((Comparable) o1).compareTo(o2);
+                result = ((Comparable<Object>) o1).compareTo(o2);
               } else {
                 result = 0;
               }