[OLINGO-834] ExpressionParser parses path expressions Signed-off-by: Christian Amend <[email protected]>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/a8091658 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/a8091658 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/a8091658 Branch: refs/heads/OLINGO-834_Filter_Parser Commit: a809165896e8315a04b566e11bd1637c26044c7d Parents: 104ecf4 Author: Klaus Straubinger <[email protected]> Authored: Fri Dec 18 16:42:51 2015 +0100 Committer: Christian Amend <[email protected]> Committed: Mon Dec 21 10:10:35 2015 +0100 ---------------------------------------------------------------------- .../deserializer/helper/ExpandTreeBuilder.java | 14 +- .../server/core/uri/UriResourceActionImpl.java | 44 +- .../uri/UriResourceComplexPropertyImpl.java | 18 +- .../server/core/uri/UriResourceCountImpl.java | 10 +- .../core/uri/UriResourceEntitySetImpl.java | 19 +- .../core/uri/UriResourceFunctionImpl.java | 48 +- .../olingo/server/core/uri/UriResourceImpl.java | 6 +- .../server/core/uri/UriResourceItImpl.java | 31 +- .../core/uri/UriResourceLambdaAllImpl.java | 26 +- .../core/uri/UriResourceLambdaAnyImpl.java | 25 +- .../core/uri/UriResourceLambdaVarImpl.java | 32 +- .../uri/UriResourceNavigationPropertyImpl.java | 21 +- .../uri/UriResourcePrimitivePropertyImpl.java | 20 +- .../server/core/uri/UriResourceRefImpl.java | 10 +- .../server/core/uri/UriResourceRootImpl.java | 31 +- .../core/uri/UriResourceSingletonImpl.java | 21 +- .../uri/UriResourceStartingTypeFilterImpl.java | 33 +- .../server/core/uri/UriResourceTypedImpl.java | 11 +- .../server/core/uri/UriResourceValueImpl.java | 9 +- .../core/uri/parser/ExpressionParser.java | 560 ++++++++++- .../server/core/uri/parser/FilterParser.java | 49 + .../server/core/uri/parser/OrderByParser.java | 61 ++ .../olingo/server/core/uri/parser/Parser.java | 123 +-- .../server/core/uri/parser/ParserHelper.java | 335 ++++++- .../core/uri/parser/ResourcePathParser.java | 323 +----- .../server/core/uri/parser/SelectParser.java | 10 +- .../server/core/uri/parser/UriContext.java | 7 +- .../core/uri/parser/UriParseTreeVisitor.java | 124 +-- .../server/core/uri/parser/UriTokenizer.java | 36 +- .../uri/queryoption/expression/MemberImpl.java | 5 + .../olingo/server/core/uri/UriInfoImplTest.java | 10 +- .../core/uri/parser/ExpressionParserTest.java | 21 +- .../core/uri/parser/UriTokenizerTest.java | 31 +- .../server/core/uri/UriResourceImplTest.java | 156 ++- .../core/uri/antlr/TestFullResourcePath.java | 979 +++++++++---------- .../core/uri/antlr/TestUriParserImpl.java | 36 +- .../queryoption/expression/ExpressionTest.java | 12 +- 37 files changed, 1816 insertions(+), 1491 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java index 549cf33..7577e7b 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java @@ -27,14 +27,8 @@ public abstract class ExpandTreeBuilder { public abstract ExpandTreeBuilder expand(EdmNavigationProperty edmNavigationProperty); protected ExpandItemImpl buildExpandItem(final EdmNavigationProperty edmNavigationProperty) { - final ExpandItemImpl expandItem = new ExpandItemImpl(); - final UriInfoImpl uriInfo = new UriInfoImpl(); - final UriResourceNavigationPropertyImpl resourceNavigation = new UriResourceNavigationPropertyImpl(); - - resourceNavigation.setNavigationProperty(edmNavigationProperty); - uriInfo.addResourcePart(resourceNavigation); - expandItem.setResourcePath(uriInfo); - - return expandItem; + return new ExpandItemImpl() + .setResourcePath(new UriInfoImpl() + .addResourcePart(new UriResourceNavigationPropertyImpl(edmNavigationProperty))); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java index 4126110..1853942 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java @@ -31,11 +31,19 @@ import org.apache.olingo.server.api.uri.UriResourceKind; */ public class UriResourceActionImpl extends UriResourceImpl implements UriResourceAction { - protected EdmAction action; - protected EdmActionImport actionImport; + private final EdmActionImport actionImport; + private final EdmAction action; - public UriResourceActionImpl() { + public UriResourceActionImpl(final EdmActionImport actionImport) { super(UriResourceKind.action); + this.actionImport = actionImport; + this.action = actionImport.getUnboundAction(); + } + + public UriResourceActionImpl(final EdmAction action) { + super(UriResourceKind.action); + this.actionImport = null; + this.action = action; } @Override @@ -43,38 +51,21 @@ public class UriResourceActionImpl extends UriResourceImpl implements UriResourc return action; } - public UriResourceActionImpl setAction(final EdmAction action) { - this.action = action; - return this; - } - @Override public EdmActionImport getActionImport() { return actionImport; } - public UriResourceActionImpl setActionImport(final EdmActionImport actionImport) { - this.actionImport = actionImport; - setAction(actionImport.getUnboundAction()); - return this; - } - @Override public boolean isCollection() { - if (action.getReturnType() != null) { - return action.getReturnType().isCollection(); - } - return false; + return action.getReturnType() != null && action.getReturnType().isCollection(); } @Override public EdmType getType() { - if (action.getReturnType() != null) { - return action.getReturnType().getType(); - } - return null; + return action.getReturnType() == null ? null : action.getReturnType().getType(); } - + @Override public String getSegmentValue(final boolean includeFilters) { return actionImport == null ? (action == null ? "" : action.getName()) : actionImport.getName(); @@ -84,14 +75,9 @@ public class UriResourceActionImpl extends UriResourceImpl implements UriResourc public String getSegmentValue() { return getSegmentValue(false); } - + @Override public String toString(final boolean includeFilters) { return getSegmentValue(includeFilters); } - - @Override - public String toString() { - return getSegmentValue(); - } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java index 63db69c..9c83f24 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java @@ -26,10 +26,11 @@ import org.apache.olingo.server.api.uri.UriResourceKind; public class UriResourceComplexPropertyImpl extends UriResourceTypedImpl implements UriResourceComplexProperty { - protected EdmProperty property; + private final EdmProperty property; - public UriResourceComplexPropertyImpl() { + public UriResourceComplexPropertyImpl(final EdmProperty property) { super(UriResourceKind.complexProperty); + this.property = property; } @Override @@ -37,11 +38,6 @@ public class UriResourceComplexPropertyImpl extends UriResourceTypedImpl impleme return property; } - public UriResourceComplexPropertyImpl setProperty(final EdmProperty property) { - this.property = property; - return this; - } - @Override public EdmComplexType getComplexType() { return (EdmComplexType) getType(); @@ -63,13 +59,7 @@ public class UriResourceComplexPropertyImpl extends UriResourceTypedImpl impleme } @Override - public String getSegmentValue(){ + public String getSegmentValue() { return property.getName(); } - - @Override - public String toString() { - return getSegmentValue(); - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java index e1859a6..90dc4f5 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java @@ -26,15 +26,9 @@ public class UriResourceCountImpl extends UriResourceImpl implements UriResource public UriResourceCountImpl() { super(UriResourceKind.count); } - - @Override - public String getSegmentValue(){ - return "$count"; - } @Override - public String toString() { - return getSegmentValue(); + public String getSegmentValue() { + return "$count"; } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java index 4675964..ea21fe5 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java @@ -25,10 +25,12 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.apache.olingo.server.api.uri.UriResourceKind; public class UriResourceEntitySetImpl extends UriResourceWithKeysImpl implements UriResourceEntitySet { - protected EdmEntitySet edmEntitySet = null; - public UriResourceEntitySetImpl() { + private final EdmEntitySet edmEntitySet; + + public UriResourceEntitySetImpl(final EdmEntitySet edmEntitySet) { super(UriResourceKind.entitySet); + this.edmEntitySet = edmEntitySet; } @Override @@ -36,11 +38,6 @@ public class UriResourceEntitySetImpl extends UriResourceWithKeysImpl implements return edmEntitySet; } - public UriResourceEntitySetImpl setEntitSet(final EdmEntitySet edmES) { - edmEntitySet = edmES; - return this; - } - @Override public EdmEntityType getEntityType() { return edmEntitySet.getEntityType(); @@ -57,13 +54,7 @@ public class UriResourceEntitySetImpl extends UriResourceWithKeysImpl implements } @Override - public String getSegmentValue(){ + public String getSegmentValue() { return edmEntitySet.getName(); } - - - @Override - public String toString() { - return getSegmentValue(); - } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java index a47a6ab..7784062 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java @@ -33,13 +33,16 @@ import org.apache.olingo.server.api.uri.UriResourceKind; */ public class UriResourceFunctionImpl extends UriResourceWithKeysImpl implements UriResourceFunction { - protected List<UriParameter> parameters; - protected EdmFunction function; - protected EdmFunctionImport functionImport; - private boolean isParameterListFilled = false; + private final EdmFunctionImport functionImport; + private final EdmFunction function; + private final List<UriParameter> parameters; - public UriResourceFunctionImpl() { + public UriResourceFunctionImpl(final EdmFunctionImport edmFunctionImport, final EdmFunction function, + final List<UriParameter> parameters) { super(UriResourceKind.function); + this.functionImport = edmFunctionImport; + this.function = function; + this.parameters = parameters; } @Override @@ -49,34 +52,16 @@ public class UriResourceFunctionImpl extends UriResourceWithKeysImpl implements Collections.unmodifiableList(parameters); } - public UriResourceFunctionImpl setParameters(final List<UriParameter> parameters) { - isParameterListFilled = true; - this.parameters = parameters; - return this; - } - @Override public EdmFunction getFunction() { return function; } - public UriResourceFunctionImpl setFunction(final EdmFunction function) { - this.function = function; - return this; - } - @Override public EdmFunctionImport getFunctionImport() { return functionImport; } - public UriResourceFunctionImpl setFunctionImport(final EdmFunctionImport edmFunctionImport, - final List<UriParameter> parameters) { - functionImport = edmFunctionImport; - setParameters(parameters); - return this; - } - @Override public EdmType getType() { return function.getReturnType().getType(); @@ -89,21 +74,6 @@ public class UriResourceFunctionImpl extends UriResourceWithKeysImpl implements @Override public String getSegmentValue() { - if (functionImport != null) { - return functionImport.getName(); - } else if (function != null) { - return function.getName(); - } - return ""; + return functionImport == null ? (function == null ? "" : function.getName()) : functionImport.getName(); } - - @Override - public String toString() { - return getSegmentValue(); - } - - public boolean isParameterListFilled() { - return isParameterListFilled; - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java index 9fbcbd0..db991a8 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java @@ -22,7 +22,7 @@ import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceKind; /** - * Covers Functionimports and BoundFunction in URI + * Abstract class for resource-path elements in URI. */ public abstract class UriResourceImpl implements UriResource { protected UriResourceKind kind; @@ -36,4 +36,8 @@ public abstract class UriResourceImpl implements UriResource { return kind; } + @Override + public String toString() { + return getSegmentValue(); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java index fc31910..e7db56c 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java @@ -27,11 +27,13 @@ import org.apache.olingo.server.api.uri.UriResourceKind; */ public class UriResourceItImpl extends UriResourceWithKeysImpl implements UriResourceIt { - private EdmType type; - private boolean isCollection; + private final EdmType type; + private final boolean isCollection; - public UriResourceItImpl() { + public UriResourceItImpl(final EdmType type, final boolean isCollection) { super(UriResourceKind.it); + this.type = type; + this.isCollection = isCollection; } @Override @@ -39,32 +41,13 @@ public class UriResourceItImpl extends UriResourceWithKeysImpl implements UriRes return type; } - public UriResourceItImpl setType(final EdmType type) { - this.type = type; - return this; - } - @Override public boolean isCollection() { - if (keyPredicates != null) { - return false; - } - return isCollection; + return keyPredicates == null && isCollection; } - public UriResourceItImpl setCollection(final boolean isCollection) { - this.isCollection = isCollection; - return this; - } - @Override - public String getSegmentValue(){ + public String getSegmentValue() { return "$it"; } - - @Override - public String toString() { - return getSegmentValue(); - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java index d980777..4f5a4fa 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java @@ -19,7 +19,6 @@ package org.apache.olingo.server.core.uri; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; -import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.server.api.uri.UriResourceKind; @@ -28,12 +27,13 @@ import org.apache.olingo.server.api.uri.queryoption.expression.Expression; public class UriResourceLambdaAllImpl extends UriResourceTypedImpl implements UriResourceLambdaAll { - protected EdmProperty property; - private String lambdaVariable; - private Expression expression; + private final String lambdaVariable; + private final Expression expression; - public UriResourceLambdaAllImpl() { + public UriResourceLambdaAllImpl(final String lambdaVariable, final Expression expression) { super(UriResourceKind.lambdaAll); + this.lambdaVariable = lambdaVariable; + this.expression = expression; } @Override @@ -51,29 +51,13 @@ public class UriResourceLambdaAllImpl extends UriResourceTypedImpl implements Ur return lambdaVariable; } - public UriResourceLambdaAllImpl setLamdaVariable(final String lambdaVariable) { - this.lambdaVariable = lambdaVariable; - return this; - } - @Override public Expression getExpression() { return expression; } - public UriResourceLambdaAllImpl setExpression(final Expression expression) { - this.expression = expression; - return this; - } - @Override public String getSegmentValue() { return "all"; } - - @Override - public String toString() { - return getSegmentValue(); - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java index fe5dfee..b586a09 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java @@ -19,7 +19,6 @@ package org.apache.olingo.server.core.uri; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; -import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.server.api.uri.UriResourceKind; @@ -28,12 +27,13 @@ import org.apache.olingo.server.api.uri.queryoption.expression.Expression; public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements UriResourceLambdaAny { - protected EdmProperty property; - private String lambdaVariable; - private Expression expression; + private final String lambdaVariable; + private final Expression expression; - public UriResourceLambdaAnyImpl() { + public UriResourceLambdaAnyImpl(final String lambdaVariable, final Expression expression) { super(UriResourceKind.lambdaAny); + this.lambdaVariable = lambdaVariable; + this.expression = expression; } @Override @@ -51,28 +51,13 @@ public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements Ur return lambdaVariable; } - public UriResourceLambdaAnyImpl setLamdaVariable(final String lambdaVariable) { - this.lambdaVariable = lambdaVariable; - return this; - } - @Override public Expression getExpression() { return expression; } - public UriResourceLambdaAnyImpl setExpression(final Expression expression) { - this.expression = expression; - return this; - } - @Override public String getSegmentValue() { return "any"; } - - @Override - public String toString() { - return getSegmentValue(); - } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java index 2eb7607..306807a 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java @@ -24,12 +24,13 @@ import org.apache.olingo.server.api.uri.UriResourceLambdaVariable; public class UriResourceLambdaVarImpl extends UriResourceTypedImpl implements UriResourceLambdaVariable { - private EdmType type; - private boolean isCollection; - private String variableText; + private final String variableText; + private final EdmType type; - public UriResourceLambdaVarImpl() { + public UriResourceLambdaVarImpl(final String variableText, final EdmType type) { super(UriResourceKind.lambdaVariable); + this.variableText = variableText; + this.type = type; } @Override @@ -37,39 +38,18 @@ public class UriResourceLambdaVarImpl extends UriResourceTypedImpl implements Ur return variableText; } - public UriResourceLambdaVarImpl setVariableText(final String variableText) { - this.variableText = variableText; - return this; - } - @Override public EdmType getType() { return type; } - public UriResourceLambdaVarImpl setType(final EdmType type) { - this.type = type; - return this; - - } - @Override public boolean isCollection() { - return isCollection; - } - - public UriResourceLambdaVarImpl setCollection(final boolean isCollection) { - this.isCollection = isCollection; - return this; + return false; } @Override public String getSegmentValue() { return variableText; } - - @Override - public String toString() { - return getSegmentValue(); - } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java index f4390b5..1d8b321 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java @@ -25,10 +25,11 @@ import org.apache.olingo.server.api.uri.UriResourceNavigation; public class UriResourceNavigationPropertyImpl extends UriResourceWithKeysImpl implements UriResourceNavigation { - protected EdmNavigationProperty navigationProperty; + private final EdmNavigationProperty navigationProperty; - public UriResourceNavigationPropertyImpl() { + public UriResourceNavigationPropertyImpl(final EdmNavigationProperty property) { super(UriResourceKind.navigationProperty); + navigationProperty = property; } @Override @@ -36,12 +37,6 @@ public class UriResourceNavigationPropertyImpl extends UriResourceWithKeysImpl i return navigationProperty; } - public UriResourceNavigationPropertyImpl setNavigationProperty(final EdmNavigationProperty property) { - navigationProperty = property; - return this; - - } - @Override public EdmType getType() { return navigationProperty.getType(); @@ -51,15 +46,9 @@ public class UriResourceNavigationPropertyImpl extends UriResourceWithKeysImpl i public boolean isCollection() { return navigationProperty.isCollection() && keyPredicates == null; } - - @Override - public String getSegmentValue(){ - return navigationProperty.getName(); - } @Override - public String toString() { - return getSegmentValue(); + public String getSegmentValue() { + return navigationProperty.getName(); } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java index d470ef4..bb04142 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java @@ -25,10 +25,11 @@ import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty; public class UriResourcePrimitivePropertyImpl extends UriResourceTypedImpl implements UriResourcePrimitiveProperty { - EdmProperty property; + private final EdmProperty property; - public UriResourcePrimitivePropertyImpl() { + public UriResourcePrimitivePropertyImpl(final EdmProperty property) { super(UriResourceKind.primitiveProperty); + this.property = property; } @Override @@ -36,11 +37,6 @@ public class UriResourcePrimitivePropertyImpl extends UriResourceTypedImpl imple return property; } - public UriResourcePrimitivePropertyImpl setProperty(final EdmProperty property) { - this.property = property; - return this; - } - @Override public EdmType getType() { return property.getType(); @@ -50,15 +46,9 @@ public class UriResourcePrimitivePropertyImpl extends UriResourceTypedImpl imple public boolean isCollection() { return property.isCollection(); } - - @Override - public String getSegmentValue(){ - return property.getName(); - } @Override - public String toString() { - return getSegmentValue(); + public String getSegmentValue() { + return property.getName(); } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java index 0c45f9a..6f01936 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java @@ -25,16 +25,10 @@ public class UriResourceRefImpl extends UriResourceImpl implements UriResourceRe public UriResourceRefImpl() { super(UriResourceKind.ref); - - } - @Override - public String getSegmentValue(){ - return "$ref"; } @Override - public String toString() { - return getSegmentValue(); + public String getSegmentValue() { + return "$ref"; } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java index 5d8737f..761899f 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java @@ -24,11 +24,13 @@ import org.apache.olingo.server.api.uri.UriResourceRoot; public class UriResourceRootImpl extends UriResourceWithKeysImpl implements UriResourceRoot { - private EdmType type; - private boolean isCollection; + private final EdmType type; + private final boolean isCollection; - public UriResourceRootImpl() { + public UriResourceRootImpl(final EdmType type, final boolean isCollection) { super(UriResourceKind.root); + this.type = type; + this.isCollection = isCollection; } @Override @@ -36,32 +38,13 @@ public class UriResourceRootImpl extends UriResourceWithKeysImpl implements UriR return type; } - public UriResourceRootImpl setType(final EdmType type) { - this.type = type; - return this; - } - @Override public boolean isCollection() { - if (keyPredicates != null) { - return false; - } - return isCollection; + return keyPredicates == null && isCollection; } - public UriResourceRootImpl setCollection(final boolean isCollection) { - this.isCollection = isCollection; - return this; - } - @Override - public String getSegmentValue(){ + public String getSegmentValue() { return "$root"; } - - @Override - public String toString() { - return getSegmentValue(); - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java index 72289f6..381a518 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java @@ -26,10 +26,11 @@ import org.apache.olingo.server.api.uri.UriResourceSingleton; public class UriResourceSingletonImpl extends UriResourceTypedImpl implements UriResourceSingleton { - private EdmSingleton singleton; + private final EdmSingleton singleton; - public UriResourceSingletonImpl() { + public UriResourceSingletonImpl(final EdmSingleton singleton) { super(UriResourceKind.singleton); + this.singleton = singleton; } @Override @@ -37,12 +38,6 @@ public class UriResourceSingletonImpl extends UriResourceTypedImpl implements Ur return singleton; } - public UriResourceSingletonImpl setSingleton(final EdmSingleton singleton) { - - this.singleton = singleton; - return this; - } - @Override public EdmEntityType getEntityTypeFilter() { return (EdmEntityType) typeFilter; @@ -62,15 +57,9 @@ public class UriResourceSingletonImpl extends UriResourceTypedImpl implements Ur public boolean isCollection() { return false; } - - @Override - public String getSegmentValue(){ - return singleton.getName(); - } @Override - public String toString() { - return getSegmentValue(); + public String getSegmentValue() { + return singleton.getName(); } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java index 24d3713..09af068 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java @@ -23,11 +23,13 @@ import org.apache.olingo.server.api.uri.UriResourceKind; public class UriResourceStartingTypeFilterImpl extends UriResourceWithKeysImpl { - private EdmType type; - private boolean isCollection; + private final EdmType type; + private final boolean isCollection; - public UriResourceStartingTypeFilterImpl() { + public UriResourceStartingTypeFilterImpl(final EdmType type, final boolean isCollection) { super(null); + this.type = type; + this.isCollection = isCollection; } @Override @@ -40,32 +42,13 @@ public class UriResourceStartingTypeFilterImpl extends UriResourceWithKeysImpl { return type; } - public UriResourceStartingTypeFilterImpl setType(final EdmType type) { - this.type = type; - return this; - } - @Override public boolean isCollection() { - if (keyPredicates != null) { - return false; - } - return isCollection; - } - - public UriResourceStartingTypeFilterImpl setCollection(final boolean isCollection) { - this.isCollection = isCollection; - return this; + return keyPredicates == null && isCollection; } @Override - public String getSegmentValue(){ - return type.getNamespace() + "." + type.getName(); + public String getSegmentValue() { + return type.getFullQualifiedName().getFullQualifiedNameAsString(); } - - @Override - public String toString() { - return getSegmentValue(); - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java index d6710ad..9930a7e 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java @@ -41,14 +41,9 @@ public abstract class UriResourceTypedImpl extends UriResourceImpl implements Ur } public String getSegmentValue(final boolean includeFilters) { - if (includeFilters) { - if (typeFilter != null) { - return getSegmentValue() + "/" + typeFilter.getFullQualifiedName().toString(); - } else { - return getSegmentValue(); - } - } - return getSegmentValue(); + return includeFilters && typeFilter != null ? + getSegmentValue() + "/" + typeFilter.getFullQualifiedName().getFullQualifiedNameAsString() : + getSegmentValue(); } @Override http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java index 73f86c4..d2b70d5 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java @@ -25,17 +25,10 @@ public class UriResourceValueImpl extends UriResourceImpl implements UriResource public UriResourceValueImpl() { super(UriResourceKind.value); - } @Override - public String getSegmentValue(){ + public String getSegmentValue() { return "$value"; } - - @Override - public String toString() { - return getSegmentValue(); - } - } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java index 61c023d..2f7fdb2 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java @@ -18,20 +18,41 @@ */ package org.apache.olingo.server.core.uri.parser; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmElement; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmEnumType; +import org.apache.olingo.commons.api.edm.EdmFunction; +import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.EdmProperty; +import org.apache.olingo.commons.api.edm.EdmReturnType; +import org.apache.olingo.commons.api.edm.EdmSingleton; +import org.apache.olingo.commons.api.edm.EdmStructuredType; import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.edm.EdmTypeDefinition; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.uri.UriParameter; +import org.apache.olingo.server.api.uri.UriResourceFunction; +import org.apache.olingo.server.api.uri.UriResourceLambdaVariable; +import org.apache.olingo.server.api.uri.UriResourceNavigation; +import org.apache.olingo.server.api.uri.UriResourcePartTyped; import org.apache.olingo.server.api.uri.queryoption.expression.Alias; import org.apache.olingo.server.api.uri.queryoption.expression.Binary; import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind; @@ -45,12 +66,32 @@ import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind; import org.apache.olingo.server.api.uri.queryoption.expression.TypeLiteral; import org.apache.olingo.server.api.uri.queryoption.expression.Unary; import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind; +import org.apache.olingo.server.core.uri.UriInfoImpl; +import org.apache.olingo.server.core.uri.UriResourceComplexPropertyImpl; +import org.apache.olingo.server.core.uri.UriResourceCountImpl; +import org.apache.olingo.server.core.uri.UriResourceEntitySetImpl; +import org.apache.olingo.server.core.uri.UriResourceFunctionImpl; +import org.apache.olingo.server.core.uri.UriResourceItImpl; +import org.apache.olingo.server.core.uri.UriResourceLambdaAllImpl; +import org.apache.olingo.server.core.uri.UriResourceLambdaAnyImpl; +import org.apache.olingo.server.core.uri.UriResourceLambdaVarImpl; +import org.apache.olingo.server.core.uri.UriResourceNavigationPropertyImpl; +import org.apache.olingo.server.core.uri.UriResourcePrimitivePropertyImpl; +import org.apache.olingo.server.core.uri.UriResourceRootImpl; +import org.apache.olingo.server.core.uri.UriResourceSingletonImpl; +import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl; +import org.apache.olingo.server.core.uri.UriResourceTypedImpl; +import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl; import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind; import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl; import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.EnumerationImpl; import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.MemberImpl; import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.TypeLiteralImpl; import org.apache.olingo.server.core.uri.queryoption.expression.UnaryImpl; +import org.apache.olingo.server.core.uri.validator.UriValidationException; public class ExpressionParser { private static final Map<TokenKind, BinaryOperatorKind> tokenToBinaryOperator; @@ -129,7 +170,7 @@ public class ExpressionParser { Map<TokenKind, EdmPrimitiveTypeKind> temp = new HashMap<TokenKind, EdmPrimitiveTypeKind>(); temp.put(TokenKind.BooleanValue, EdmPrimitiveTypeKind.Boolean); temp.put(TokenKind.StringValue, EdmPrimitiveTypeKind.String); - // TODO:Check if int64 is correct here or if it has to be single instead + // TODO: Check if int64 is correct here or if it has to be decimal or single or double instead. temp.put(TokenKind.IntegerValue, EdmPrimitiveTypeKind.Int64); temp.put(TokenKind.GuidValue, EdmPrimitiveTypeKind.Guid); temp.put(TokenKind.DateValue, EdmPrimitiveTypeKind.Date); @@ -147,20 +188,27 @@ public class ExpressionParser { private final OData odata; private UriTokenizer tokenizer; + private Deque<UriResourceLambdaVariable> lambdaVariables = new ArrayDeque<UriResourceLambdaVariable>(); + private EdmType referringType; + private Collection<String> crossjoinEntitySetNames; public ExpressionParser(final Edm edm, final OData odata) { this.edm = edm; this.odata = odata; } - public Expression parse(UriTokenizer tokenizer) throws UriParserException { + public Expression parse(UriTokenizer tokenizer, final EdmType referringType, + final Collection<String> crossjoinEntitySetNames) + throws UriParserException, UriValidationException { // Initialize tokenizer. this.tokenizer = tokenizer; + this.referringType = referringType; + this.crossjoinEntitySetNames = crossjoinEntitySetNames; return parseExpression(); } - private Expression parseExpression() throws UriParserException { + private Expression parseExpression() throws UriParserException, UriValidationException { Expression left = parseAnd(); while (tokenizer.next(TokenKind.OrOperator)) { final Expression right = parseAnd(); @@ -172,7 +220,7 @@ public class ExpressionParser { return left; } - private Expression parseAnd() throws UriParserException { + private Expression parseAnd() throws UriParserException, UriValidationException { Expression left = parseExprEquality(); while (tokenizer.next(TokenKind.AndOperator)) { final Expression right = parseExprEquality(); @@ -184,7 +232,7 @@ public class ExpressionParser { return left; } - private Expression parseExprEquality() throws UriParserException { + private Expression parseExprEquality() throws UriParserException, UriValidationException { Expression left = parseExprRel(); TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.EqualsOperator, TokenKind.NotEqualsOperator); // Null for everything other than EQ or NE @@ -199,7 +247,7 @@ public class ExpressionParser { } // TODO: The 'isof' method has relational precedence and should appear here. - private Expression parseExprRel() throws UriParserException { + private Expression parseExprRel() throws UriParserException, UriValidationException { Expression left = parseExprAdd(); TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.GreaterThanOperator, TokenKind.GreaterThanOrEqualsOperator, @@ -217,7 +265,7 @@ public class ExpressionParser { return left; } - private Expression parseExprAdd() throws UriParserException { + private Expression parseExprAdd() throws UriParserException, UriValidationException { Expression left = parseExprMul(); TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.AddOperator, TokenKind.SubOperator); // Null for everything other than ADD or SUB @@ -231,7 +279,7 @@ public class ExpressionParser { return left; } - private Expression parseExprMul() throws UriParserException { + private Expression parseExprMul() throws UriParserException, UriValidationException { Expression left = parseExprUnary(); TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.MulOperator, TokenKind.DivOperator, TokenKind.ModOperator); @@ -255,7 +303,22 @@ public class ExpressionParser { } // TODO: The 'cast' method has unary precedence and should appear here. - private Expression parseExprUnary() throws UriParserException { + private Expression parseExprUnary() throws UriParserException, UriValidationException { + // Negative numbers start with a minus indistinguishable from an unary minus operator. + // So we read numbers (and primitive values starting with numbers) right here. + // TODO: Find a better idea how to solve this problem. + final TokenKind numberTokenKind = ParserHelper.next(tokenizer, + TokenKind.DoubleValue, TokenKind.DecimalValue, TokenKind.GuidValue, + TokenKind.DateTimeOffsetValue, TokenKind.DateValue, TokenKind.TimeOfDayValue, + TokenKind.IntegerValue); + if (numberTokenKind != null) { + final EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(numberTokenKind); + final EdmPrimitiveType type = primitiveTypeKind == null ? + // Null handling + null : + odata.createPrimitiveTypeInstance(primitiveTypeKind); + return new LiteralImpl(tokenizer.getText(), type); + } Expression left = null; TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.MINUS, TokenKind.NotOperator); // Null for everything other than - or NOT @@ -279,13 +342,11 @@ public class ExpressionParser { return left; } - private Expression parseExprPrimary() throws UriParserException { + private Expression parseExprPrimary() throws UriParserException, UriValidationException { final Expression left = parseExprValue(); if (isEnumType(left) && tokenizer.next(TokenKind.HasOperator)) { ParserHelper.requireNext(tokenizer, TokenKind.EnumValue); - final String primitiveValueLiteral = tokenizer.getText(); - final Expression right = new LiteralImpl(primitiveValueLiteral, getEnumType(primitiveValueLiteral)); - checkEnumLiteral(right); + final Expression right = createEnumExpression(tokenizer.getText()); return new BinaryImpl(left, BinaryOperatorKind.HAS, right, odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean)); } else { @@ -293,7 +354,7 @@ public class ExpressionParser { } } - private Expression parseExprValue() throws UriParserException { + private Expression parseExprValue() throws UriParserException, UriValidationException { if (tokenizer.next(TokenKind.OPEN)) { final Expression expression = parseExpression(); ParserHelper.requireNext(tokenizer, TokenKind.CLOSE); @@ -310,51 +371,49 @@ public class ExpressionParser { } if (tokenizer.next(TokenKind.ROOT)) { - // TODO: Consume $root expression. + return parseFirstMemberExpr(TokenKind.ROOT); } if (tokenizer.next(TokenKind.IT)) { - // TODO: Consume $it expression. + return parseFirstMemberExpr(TokenKind.IT); } - TokenKind nextPrimitive = ParserHelper.nextPrimitive(tokenizer); + final TokenKind nextPrimitive = ParserHelper.nextPrimitiveValue(tokenizer); if (nextPrimitive != null) { final String primitiveValueLiteral = tokenizer.getText(); - final EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(nextPrimitive); - EdmPrimitiveType type; - if (primitiveTypeKind == null) { - if (nextPrimitive == TokenKind.EnumValue) { - type = getEnumType(primitiveValueLiteral); - } else { - // Null handling - type = null; - } + if (nextPrimitive == TokenKind.EnumValue) { + return createEnumExpression(primitiveValueLiteral); } else { - type = odata.createPrimitiveTypeInstance(primitiveTypeKind); + final EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(nextPrimitive); + final EdmPrimitiveType type = primitiveTypeKind == null ? + // Null handling + null : + odata.createPrimitiveTypeInstance(primitiveTypeKind); + return new LiteralImpl(primitiveValueLiteral, type); } - return new LiteralImpl(primitiveValueLiteral, type); } // The method token text includes the opening parenthesis so that method calls can be recognized unambiguously. // OData identifiers have to be considered after that. - TokenKind nextMethod = nextMethod(); + final TokenKind nextMethod = nextMethod(); if (nextMethod != null) { MethodKind methodKind = tokenToMethod.get(nextMethod); return new MethodImpl(methodKind, parseMethodParameters(methodKind)); } if (tokenizer.next(TokenKind.QualifiedName)) { - // TODO: Consume typecast or bound-function expression. + return parseFirstMemberExpr(TokenKind.QualifiedName); } if (tokenizer.next(TokenKind.ODataIdentifier)) { - // TODO: Consume property-path or lambda-variable expression. + return parseFirstMemberExpr(TokenKind.ODataIdentifier); } - throw new UriParserSyntaxException("Unexpected token", UriParserSyntaxException.MessageKeys.SYNTAX); + throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX); } - private List<Expression> parseMethodParameters(final MethodKind methodKind) throws UriParserException { + private List<Expression> parseMethodParameters(final MethodKind methodKind) + throws UriParserException, UriValidationException { List<Expression> parameters = new ArrayList<Expression>(); switch (methodKind) { // Must have no parameter. @@ -477,6 +536,411 @@ public class ExpressionParser { return parameters; } + private Expression parseFirstMemberExpr(final TokenKind lastTokenKind) + throws UriParserException, UriValidationException { + + final UriInfoImpl uriInfo = new UriInfoImpl(); + EdmType startTypeFilter = null; + + if (lastTokenKind == TokenKind.ROOT) { + parseDollarRoot(uriInfo); + } else if (lastTokenKind == TokenKind.IT) { + parseDollarIt(uriInfo); + } else if (lastTokenKind == TokenKind.ODataIdentifier) { + parseFirstMemberODataIdentifier(uriInfo); + } else if (lastTokenKind == TokenKind.QualifiedName) { + // Special handling for leading type casts and type literals + final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText()); + EdmStructuredType structuredType = edm.getEntityType(fullQualifiedName); + if (structuredType == null) { + structuredType = edm.getComplexType(fullQualifiedName); + } + + if (structuredType != null) { + if (tokenizer.next(TokenKind.SLASH)) { + // Leading type cast + checkStructuredTypeFilter(referringType, structuredType); + startTypeFilter = structuredType; + + final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier); + parseMemberExpression(tokenKind, uriInfo, new UriResourceStartingTypeFilterImpl(structuredType, false), + false); + } else { + // Type literal + checkStructuredTypeFilter(referringType, structuredType); + return new TypeLiteralImpl(structuredType); + } + } else { + // Must be bound or unbound function. // TODO: Is unbound function allowed? + parseFunction(fullQualifiedName, uriInfo, referringType, true); + } + } + + return new MemberImpl(uriInfo, startTypeFilter); + } + + private void parseDollarRoot(UriInfoImpl uriInfo) throws UriParserException, UriValidationException { + UriResourceRootImpl rootResource = new UriResourceRootImpl(referringType, true); + uriInfo.addResourcePart(rootResource); + ParserHelper.requireNext(tokenizer, TokenKind.SLASH); + ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier); + final String name = tokenizer.getText(); + UriResourcePartTyped resource = null; + final EdmEntitySet entitySet = edm.getEntityContainer().getEntitySet(name); + if (entitySet == null) { + final EdmSingleton singleton = edm.getEntityContainer().getSingleton(name); + if (singleton == null) { + throw new UriParserSemanticException("EntitySet or singleton expected.", + UriParserSemanticException.MessageKeys.UNKNOWN_PART, name); + } else { + resource = new UriResourceSingletonImpl(singleton); + } + } else { + ParserHelper.requireNext(tokenizer, TokenKind.OPEN); + final List<UriParameter> keyPredicates = + ParserHelper.parseKeyPredicate(tokenizer, entitySet.getEntityType(), null); + resource = new UriResourceEntitySetImpl(entitySet).setKeyPredicates(keyPredicates); + } + uriInfo.addResourcePart(resource); + parseSingleNavigationExpr(uriInfo, resource); + } + + private void parseDollarIt(UriInfoImpl uriInfo) throws UriParserException, UriValidationException { + UriResourceItImpl itResource = new UriResourceItImpl(referringType, + referringType instanceof EdmEntityType); // TODO: Determine isCollection. + uriInfo.addResourcePart(itResource); + if (tokenizer.next(TokenKind.SLASH)) { + final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier); + parseMemberExpression(tokenKind, uriInfo, itResource, true); + } + } + + private void parseFirstMemberODataIdentifier(UriInfoImpl uriInfo) throws UriParserException, UriValidationException { + final String name = tokenizer.getText(); + + // For a crossjoin, the identifier must be an entity-set name. + if (crossjoinEntitySetNames != null && !crossjoinEntitySetNames.isEmpty()) { + if (crossjoinEntitySetNames.contains(name)) { + final UriResourceEntitySetImpl resource = + new UriResourceEntitySetImpl(edm.getEntityContainer().getEntitySet(name)); + uriInfo.addResourcePart(resource); + if (tokenizer.next(TokenKind.SLASH)) { + final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier); + parseMemberExpression(tokenKind, uriInfo, resource, true); + } + return; + } else { + throw new UriParserSemanticException("Unknown crossjoin entity set.", + UriParserSemanticException.MessageKeys.UNKNOWN_PART, name); + } + } + + // Check if the OData identifier is a lambda variable, otherwise it must be a property. + UriResourceLambdaVariable lambdaVariable = null; + for (final UriResourceLambdaVariable variable : lambdaVariables) { + if (variable.getVariableName().equals(name)) { + lambdaVariable = variable; + break; + } + } + if (lambdaVariable != null) { + // Copy lambda variable into new resource, just in case ... + final UriResourceLambdaVariable lambdaResource = + new UriResourceLambdaVarImpl(lambdaVariable.getVariableName(), lambdaVariable.getType()); + uriInfo.addResourcePart(lambdaResource); + if (tokenizer.next(TokenKind.SLASH)) { + final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier); + parseMemberExpression(tokenKind, uriInfo, lambdaResource, true); + } + } else { + // Must be a property. + parseMemberExpression(TokenKind.ODataIdentifier, uriInfo, null, true); // TODO: Find last resource. + } + } + + private void parseMemberExpression(final TokenKind lastTokenKind, UriInfoImpl uriInfo, + final UriResourcePartTyped lastResource, final boolean allowTypeFilter) + throws UriParserException, UriValidationException { + + if (lastTokenKind == TokenKind.QualifiedName) { + // Type cast or bound function + final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText()); + final EdmEntityType edmEntityType = edm.getEntityType(fullQualifiedName); + + if (edmEntityType != null) { + if (allowTypeFilter) { + setTypeFilter(lastResource, edmEntityType); + } else { + throw new UriParserSemanticException("Type filters are not chainable.", + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + lastResource.getType().getFullQualifiedName().getFullQualifiedNameAsString(), + fullQualifiedName.getFullQualifiedNameAsString()); + } + } else { + parseBoundFunction(fullQualifiedName, uriInfo, lastResource); + } + } else if (lastTokenKind == TokenKind.ODataIdentifier) { + parsePropertyPathExpr(uriInfo, lastResource); + } else { + throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX); + } + } + + private void setTypeFilter(UriResourcePartTyped lastResource, final EdmEntityType entityTypeFilter) + throws UriParserException { + checkStructuredTypeFilter(lastResource.getType(), entityTypeFilter); + if (lastResource instanceof UriResourceTypedImpl) { + ((UriResourceTypedImpl) lastResource).setTypeFilter(entityTypeFilter); + } else if (lastResource instanceof UriResourceWithKeysImpl) { + ((UriResourceWithKeysImpl) lastResource).setEntryTypeFilter(entityTypeFilter); + } + } + + private void parsePropertyPathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + + final String oDataIdentifier = tokenizer.getText(); + + final EdmType lastType = lastResource == null ? referringType : ParserHelper.getTypeInformation(lastResource); + if (!(lastType instanceof EdmStructuredType)) { + throw new UriParserSemanticException("Property paths must follow a structured type.", + UriParserSemanticException.MessageKeys.ONLY_FOR_STRUCTURAL_TYPES, oDataIdentifier); + } + + final EdmStructuredType structuredType = (EdmStructuredType) lastType; + final EdmElement property = structuredType.getProperty(oDataIdentifier); + + if (property == null) { + throw new UriParserSemanticException("Unknown property.", + UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE, oDataIdentifier); + } + + if (property.getType() instanceof EdmComplexType) { + final UriResourceComplexPropertyImpl complexResource = + new UriResourceComplexPropertyImpl((EdmProperty) property); + uriInfo.addResourcePart(complexResource); + + if (property.isCollection()) { + parseCollectionPathExpr(uriInfo, complexResource); + } else { + parseComplexPathExpr(uriInfo, complexResource); + } + } else if (property instanceof EdmNavigationProperty) { + // Nav. property; maybe a collection + final UriResourceNavigationPropertyImpl navigationResource = + new UriResourceNavigationPropertyImpl((EdmNavigationProperty) property); + navigationResource.setKeyPredicates( + ParserHelper.parseNavigationKeyPredicate(tokenizer, (EdmNavigationProperty) property)); + uriInfo.addResourcePart(navigationResource); + + if (navigationResource.isCollection()) { + parseCollectionNavigationExpr(uriInfo, navigationResource); + } else { + parseSingleNavigationExpr(uriInfo, navigationResource); + } + } else { + // Primitive type or Enum type + final UriResourcePrimitivePropertyImpl primitiveResource = + new UriResourcePrimitivePropertyImpl((EdmProperty) property); + uriInfo.addResourcePart(primitiveResource); + + if (property.isCollection()) { + parseCollectionPathExpr(uriInfo, primitiveResource); + } else { + parseSinglePathExpr(uriInfo, primitiveResource); + } + } + } + + private void parseSingleNavigationExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + // TODO: Is that correct? + if (tokenizer.next(TokenKind.SLASH)) { + final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier); + parseMemberExpression(tokenKind, uriInfo, lastResource, true); + } + } + + private void parseCollectionNavigationExpr(UriInfoImpl uriInfo, UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + // TODO: Is type cast missing? + if (tokenizer.next(TokenKind.OPEN)) { + if (lastResource instanceof UriResourceNavigation) { + ((UriResourceNavigationPropertyImpl) lastResource).setKeyPredicates( + ParserHelper.parseNavigationKeyPredicate(tokenizer, + ((UriResourceNavigationPropertyImpl) lastResource).getProperty())); + } else if (lastResource instanceof UriResourceFunction + && ((UriResourceFunction) lastResource).getType() instanceof EdmEntityType) { + ((UriResourceFunctionImpl) lastResource).setKeyPredicates( + ParserHelper.parseKeyPredicate(tokenizer, + (EdmEntityType) ((UriResourceFunction) lastResource).getType(), + null)); + } else { + throw new UriParserSemanticException("Unknown or wrong resource type.", + UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, lastResource.toString()); + } + parseSingleNavigationExpr(uriInfo, lastResource); + } + parseCollectionPathExpr(uriInfo, lastResource); + } + + private void parseSinglePathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + if (tokenizer.next(TokenKind.SLASH)) { + ParserHelper.requireNext(tokenizer, TokenKind.QualifiedName); + parseBoundFunction(new FullQualifiedName(tokenizer.getText()), uriInfo, lastResource); + } + } + + private void parseComplexPathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + + if (tokenizer.next(TokenKind.SLASH)) { + if (tokenizer.next(TokenKind.QualifiedName)) { + final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText()); + final EdmEntityType edmEntityType = edm.getEntityType(fullQualifiedName); + + if (edmEntityType != null) { + setTypeFilter(lastResource, edmEntityType); + if (tokenizer.next(TokenKind.SLASH)) { + parseComplexPathRestExpr(uriInfo, lastResource); + } + } else { + // Must be a bound function. + parseBoundFunction(fullQualifiedName, uriInfo, lastResource); + } + } else { + parseComplexPathRestExpr(uriInfo, lastResource); + } + } + } + + private void parseComplexPathRestExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + if (tokenizer.next(TokenKind.QualifiedName)) { + final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText()); + // Must be a bound function. + parseBoundFunction(fullQualifiedName, uriInfo, lastResource); + } else if (tokenizer.next(TokenKind.ODataIdentifier)) { + parsePropertyPathExpr(uriInfo, lastResource); + } else { + throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX); + } + } + + private void parseCollectionPathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + + if (tokenizer.next(TokenKind.SLASH)) { + if (tokenizer.next(TokenKind.COUNT)) { + uriInfo.addResourcePart(new UriResourceCountImpl()); + } else if (tokenizer.next(TokenKind.ANY)) { + uriInfo.addResourcePart(parseLambdaRest(TokenKind.ANY, lastResource)); + } else if (tokenizer.next(TokenKind.ALL)) { + uriInfo.addResourcePart(parseLambdaRest(TokenKind.ALL, lastResource)); + } else if (tokenizer.next(TokenKind.QualifiedName)) { + final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText()); + parseBoundFunction(fullQualifiedName, uriInfo, lastResource); + } + } + } + + private void parseFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo, + final EdmType lastType, final boolean lastIsCollection) throws UriParserException, UriValidationException { + + final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, true); + final List<String> parameterNames = ParserHelper.getParameterNames(parameters); + final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName, + lastType.getFullQualifiedName(), lastIsCollection, parameterNames); + + if (boundFunction != null) { + parseFunctionRest(uriInfo, boundFunction, parameters); + return; + } + + final EdmFunction unboundFunction = edm.getUnboundFunction(fullQualifiedName, parameterNames); + if (unboundFunction != null) { + parseFunctionRest(uriInfo, unboundFunction, parameters); + return; + } + + throw new UriParserSemanticException("No function found.", + UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, fullQualifiedName.getFullQualifiedNameAsString()); + } + + private void parseBoundFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo, + final UriResourcePartTyped lastResource) throws UriParserException, UriValidationException { + final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, true); + final List<String> parameterNames = ParserHelper.getParameterNames(parameters); + final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName, + lastResource.getType().getFullQualifiedName(), lastResource.isCollection(), parameterNames); + if (boundFunction == null) { + throw new UriParserSemanticException("Bound function not found.", + UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, fullQualifiedName.getFullQualifiedNameAsString()); + } + parseFunctionRest(uriInfo, boundFunction, parameters); + } + + private void parseFunctionRest(UriInfoImpl uriInfo, final EdmFunction function, + final List<UriParameter> parameters) throws UriParserException, UriValidationException { + final UriResourceFunction functionResource = new UriResourceFunctionImpl(null, function, parameters); + uriInfo.addResourcePart(functionResource); + + final EdmReturnType edmReturnType = function.getReturnType(); + final EdmType edmType = edmReturnType.getType(); + final boolean isCollection = edmReturnType.isCollection(); + + if (function.isComposable()) { + if (edmType instanceof EdmEntityType ) { + if (isCollection) { + parseCollectionNavigationExpr(uriInfo, null); // TODO: Get navigation property. + } else { + parseSingleNavigationExpr(uriInfo, null); // TODO: Get navigation property. + } + } else if (edmType instanceof EdmComplexType) { + if (isCollection) { + parseCollectionPathExpr(uriInfo, functionResource); + } else { + parseComplexPathExpr(uriInfo, functionResource); + } + } else if (edmType instanceof EdmPrimitiveType) { + if (isCollection) { + parseCollectionPathExpr(uriInfo, functionResource); + } else { + parseSinglePathExpr(uriInfo, functionResource); + } + } + } else if (tokenizer.next(TokenKind.SLASH)) { + throw new UriValidationException("Function is not composable.", + UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH, ""); + } + } + + private UriResourcePartTyped parseLambdaRest(final TokenKind lastTokenKind, final UriResourcePartTyped lastResource) + throws UriParserException, UriValidationException { + + ParserHelper.requireNext(tokenizer, TokenKind.OPEN); + if (lastTokenKind == TokenKind.ANY && tokenizer.next(TokenKind.CLOSE)) { + return new UriResourceLambdaAnyImpl(null, null); + } + ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier); + final String lambbdaVariable = tokenizer.getText(); + ParserHelper.requireNext(tokenizer, TokenKind.COLON); + lambdaVariables.addFirst(new UriResourceLambdaVarImpl(lambbdaVariable, + lastResource == null ? referringType : lastResource.getType())); + final Expression lambdaPredicateExpr = parseExpression(); + lambdaVariables.removeFirst(); + // TODO: The ABNF suggests that the "lambaPredicateExpr" must contain at least one lambdaVariable. + ParserHelper.requireNext(tokenizer, TokenKind.CLOSE); + if (lastTokenKind == TokenKind.ALL) { + return new UriResourceLambdaAllImpl(lambbdaVariable, lambdaPredicateExpr); + } else if (lastTokenKind == TokenKind.ANY) { + return new UriResourceLambdaAnyImpl(lambbdaVariable, lambdaPredicateExpr); + } else { + throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX); + } + } + private TokenKind nextMethod() { return ParserHelper.next(tokenizer, TokenKind.CeilingMethod, @@ -580,9 +1044,9 @@ public class ExpressionParser { } } - private EdmPrimitiveType getEnumType(final String primitiveValueLiteral) throws UriParserException { + private EdmEnumType getEnumType(final String primitiveValueLiteral) throws UriParserException { final String enumTypeName = primitiveValueLiteral.substring(0, primitiveValueLiteral.indexOf('\'')); - final EdmPrimitiveType type = edm.getEnumType(new FullQualifiedName(enumTypeName)); + final EdmEnumType type = edm.getEnumType(new FullQualifiedName(enumTypeName)); if (type == null) { throw new UriParserSemanticException("Unknown Enum type '" + enumTypeName + "'.", UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, enumTypeName); @@ -599,13 +1063,16 @@ public class ExpressionParser { EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte); } - private void checkEnumLiteral(final Expression expression) throws UriParserException { - if (expression == null - || !(expression instanceof Literal) - || ((Literal) expression).getType() == null - || ((Literal) expression).getType().getKind() != EdmTypeKind.ENUM) { - throw new UriParserSemanticException("Enum literal expected.", - UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, ""); // TODO: better message + private Enumeration createEnumExpression(final String primitiveValueLiteral) throws UriParserException { + final EdmEnumType enumType = getEnumType(primitiveValueLiteral); + // TODO: Can the Enumeration interface be changed to handle the value as a whole? + try { + return new EnumerationImpl(enumType, + Arrays.asList(enumType.fromUriLiteral(primitiveValueLiteral).split(","))); + } catch (final EdmPrimitiveTypeException e) { + // TODO: Better error message. + throw new UriParserSemanticException("Wrong enumeration value.", e, + UriParserSemanticException.MessageKeys.UNKNOWN_PART, primitiveValueLiteral); } } @@ -664,4 +1131,13 @@ public class ExpressionParser { throw new UriParserSemanticException("Incompatible types.", UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, ""); // TODO: better message } + + private void checkStructuredTypeFilter(final EdmType type, final EdmStructuredType filterType) + throws UriParserException { + if (!filterType.compatibleTo(type)) { + throw new UriParserSemanticException("Incompatible type filter.", + UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER, + filterType.getFullQualifiedName().getFullQualifiedNameAsString()); + } + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java new file mode 100644 index 0000000..a3376e0 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.uri.parser; + +import java.util.Collection; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmStructuredType; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.uri.queryoption.FilterOption; +import org.apache.olingo.server.api.uri.queryoption.expression.Expression; +import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl; +import org.apache.olingo.server.core.uri.validator.UriValidationException; + +public class FilterParser { + + private final Edm edm; + private final OData odata; + + public FilterParser(final Edm edm, final OData odata) { + this.edm = edm; + this.odata = odata; + } + + public FilterOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType, + final Collection<String> crossjoinEntitySetNames) + throws UriParserException, UriValidationException { + final Expression filterExpression = new ExpressionParser(edm, odata) + .parse(tokenizer, referencedType, crossjoinEntitySetNames); + // TODO: Check that the expression is boolean. + return new FilterOptionImpl().setExpression(filterExpression); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java new file mode 100644 index 0000000..5ea8cb7 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.uri.parser; + +import java.util.Collection; + +import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmStructuredType; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.uri.queryoption.OrderByOption; +import org.apache.olingo.server.api.uri.queryoption.expression.Expression; +import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind; +import org.apache.olingo.server.core.uri.queryoption.OrderByItemImpl; +import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl; +import org.apache.olingo.server.core.uri.validator.UriValidationException; + +public class OrderByParser { + + private final Edm edm; + private final OData odata; + + public OrderByParser(final Edm edm, final OData odata) { + this.edm = edm; + this.odata = odata; + } + + public OrderByOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType, + final Collection<String> crossjoinEntitySetNames) + throws UriParserException, UriValidationException { + OrderByOptionImpl orderByOption = new OrderByOptionImpl(); + do { + final Expression orderByExpression = new ExpressionParser(edm, odata) + .parse(tokenizer, referencedType, crossjoinEntitySetNames); + OrderByItemImpl item = new OrderByItemImpl(); + item.setExpression(orderByExpression); + if (tokenizer.next(TokenKind.AscSuffix)) { + item.setDescending(false); + } else if (tokenizer.next(TokenKind.DescSuffix)) { + item.setDescending(true); + } + orderByOption.addOrder(item); + } while (tokenizer.next(TokenKind.COMMA)); + return orderByOption; + } +}
