[OLINGO-821] Optimize alias handling in enum types
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/0c100df4 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/0c100df4 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/0c100df4 Branch: refs/heads/OLINGO-568_SearchParser_Draft Commit: 0c100df480fc396ae9b4e53ace0e79f186686545 Parents: c7838a6 Author: Christian Amend <[email protected]> Authored: Tue Nov 10 10:52:33 2015 +0100 Committer: Christian Amend <[email protected]> Committed: Tue Nov 10 10:52:33 2015 +0100 ---------------------------------------------------------------------- .../commons/core/edm/EdmEnumTypeImpl.java | 53 ++++++++++++-------- .../server/core/edm/provider/EdmEnumTest.java | 4 +- .../expression/ExpressionVisitorImpl.java | 9 ++-- .../expression/operand/UntypedOperand.java | 19 +------ .../queryoptions/options/FilterHandler.java | 2 +- .../queryoptions/options/OrderByHandler.java | 4 +- 6 files changed, 41 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0c100df4/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java index 1f7f070..ea28c16 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java @@ -44,7 +44,6 @@ public class EdmEnumTypeImpl extends EdmTypeImpl implements EdmEnumType { private final EdmPrimitiveType underlyingType; private final CsdlEnumType enumType; private final FullQualifiedName enumName; - private final String uriSuffix; private List<String> memberNames; private Map<String, EdmMember> membersMap; @@ -68,7 +67,6 @@ public class EdmEnumTypeImpl extends EdmTypeImpl implements EdmEnumType { this.enumType = enumType; this.enumName = enumName; - uriSuffix = "'"; } @Override @@ -228,32 +226,43 @@ public class EdmEnumTypeImpl extends EdmTypeImpl implements EdmEnumType { @Override public String toUriLiteral(final String literal) { - return literal == null ? null : enumName.getFullQualifiedNameAsString() + "'" + literal + uriSuffix; + return literal == null ? null : enumName.getFullQualifiedNameAsString() + "'" + literal + "'"; } @Override public String fromUriLiteral(final String literal) throws EdmPrimitiveTypeException { if (literal == null) { return null; - } - - if (literal.endsWith(uriSuffix)) { - String[] splitLiteral = literal.split("'"); - if (splitLiteral.length != 2) { - throw new EdmPrimitiveTypeException("The literal '" + literal - + "' must be of format FullQuallifiedTypeName'literal'"); - } - // First part must be the FullQualifiedName - FullQualifiedName typeFqn = null; - try { - typeFqn = new FullQualifiedName(splitLiteral[0]); - } catch (IllegalArgumentException e) { - throw new EdmPrimitiveTypeException("The literal '" + literal + "' has illegal content.", e); - } - // Get itself. This will also resolve a possible alias - EdmEnumType prospect = edm.getEnumType(typeFqn); - if (prospect != null && enumName.equals(prospect.getFullQualifiedName())) { - return splitLiteral[1]; + } else { + String uriPrefix = enumName.getFullQualifiedNameAsString() + "'"; + String uriSuffix = "'"; + if (literal.length() >= uriPrefix.length() + uriSuffix.length() + && literal.startsWith(uriPrefix) && literal.endsWith(uriSuffix)) { + // This is the positive case where the literal is prefixed with the full qualified name of the enum type + return literal.substring(uriPrefix.length(), literal.length() - uriSuffix.length()); + } else { + // This case will be called if the prefix might be an alias + if (literal.endsWith(uriSuffix)) { + int indexSingleQuote = literal.indexOf('\''); + String fqn = literal.substring(0, indexSingleQuote); + FullQualifiedName typeFqn = null; + try { + typeFqn = new FullQualifiedName(fqn); + } catch (IllegalArgumentException e) { + throw new EdmPrimitiveTypeException("The literal '" + literal + "' has illegal content.", e); + } + /* + * Get itself. This will also resolve a possible alias. If we had an easier way to query the edm for an alias + * we could use this here. But since there is no such method we try to get the enum type based on a possible + * alias qualified name. This way the edm will resolve the alias for us. Also in a positive case the type is + * already cached so the EdmProvider should not be called. + */ + EdmEnumType prospect = edm.getEnumType(typeFqn); + if (prospect != null && enumName.equals(prospect.getFullQualifiedName()) + && literal.length() >= fqn.length() + 2) { + return literal.substring(fqn.length() + 1, literal.length() - 1); + } + } } } throw new EdmPrimitiveTypeException("The literal '" + literal + "' has illegal content."); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0c100df4/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEnumTest.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEnumTest.java b/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEnumTest.java index dbcda3a..04be8ae 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEnumTest.java +++ b/lib/commons-core/src/test/java/org/apache/olingo/server/core/edm/provider/EdmEnumTest.java @@ -179,12 +179,14 @@ public class EdmEnumTest { assertEquals("first", instance.fromUriLiteral("alias.name'first'")); expectErrorInFromUriLiteral(instance, "", null); + expectErrorInFromUriLiteral(instance, "'", null); + expectErrorInFromUriLiteral(instance, "''", null); expectErrorInFromUriLiteral(instance, "name'first'", null); + expectErrorInFromUriLiteral(instance, "namespace.name'", null); expectErrorInFromUriLiteral(instance, "namespace.name'first", null); expectErrorInFromUriLiteral(instance, "namespace.namespace'first", null); expectErrorInFromUriLiteral(instance, "namespace.namespace'fi'rst", null); expectErrorInFromUriLiteral(instance, "namespace.namespace'first'", null); - expectErrorInFromUriLiteral(instance, "namespace.name'fir'st'", "must be of format"); } @Test http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0c100df4/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 b362456..95343fd 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,7 +23,6 @@ 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.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; @@ -51,12 +50,10 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> private final Entity entity; private final UriInfoResource uriInfo; - private final Edm edm; - public ExpressionVisitorImpl(final Entity entity, final UriInfoResource uriInfo, final Edm edm) { + public ExpressionVisitorImpl(final Entity entity, final UriInfoResource uriInfo) { this.entity = entity; this.uriInfo = uriInfo; - this.edm = edm; } @Override @@ -174,7 +171,7 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> @Override public VisitorOperand visitLiteral(final Literal literal) throws ExpressionVisitException, ODataApplicationException { - return new UntypedOperand(literal.getText(), edm); + return new UntypedOperand(literal.getText()); } @Override @@ -209,7 +206,7 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> @Override public VisitorOperand visitAlias(final String aliasName) throws ExpressionVisitException, ODataApplicationException { - return new UntypedOperand(uriInfo.getValueForAlias(aliasName), edm); + return new UntypedOperand(uriInfo.getValueForAlias(aliasName)); } @Override http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0c100df4/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 755d8d1..dba114b 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,21 +20,15 @@ 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 { - private final Edm edm; - - public UntypedOperand(final String literal, final Edm edm) { + public UntypedOperand(final String literal) { super(literal); - this.edm = edm; } @Override @@ -132,17 +126,6 @@ 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/0c100df4/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 b2bd405..1a19016 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 @@ -53,7 +53,7 @@ public class FilterHandler { while (iter.hasNext()) { final VisitorOperand operand = filterOption.getExpression() - .accept(new ExpressionVisitorImpl(iter.next(), uriInfo, edm)); + .accept(new ExpressionVisitorImpl(iter.next(), uriInfo)); final TypedOperand typedOperand = operand.asTypedOperand(); if (typedOperand.is(primBoolean)) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/0c100df4/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 ad1d2d5..ddcf0af 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 @@ -70,9 +70,9 @@ public class OrderByHandler { try { final OrderByItem item = orderByOption.getOrders().get(i); final TypedOperand op1 = - item.getExpression().accept(new ExpressionVisitorImpl(e1, uriInfo, edm)).asTypedOperand(); + item.getExpression().accept(new ExpressionVisitorImpl(e1, uriInfo)).asTypedOperand(); final TypedOperand op2 = - item.getExpression().accept(new ExpressionVisitorImpl(e2, uriInfo, edm)).asTypedOperand(); + item.getExpression().accept(new ExpressionVisitorImpl(e2, uriInfo)).asTypedOperand(); if (op1.isNull() || op2.isNull()) { if (op1.isNull() && op2.isNull()) {
