[OLINGO-834] ExpressionParser parses path expressions
Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
parent
104ecf43d2
commit
a809165896
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,15 +26,9 @@ public class UriResourceCountImpl extends UriResourceImpl implements UriResource
|
|||
public UriResourceCountImpl() {
|
||||
super(UriResourceKind.count);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSegmentValue(){
|
||||
public String getSegmentValue() {
|
||||
return "$count";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSegmentValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(){
|
||||
public String getSegmentValue() {
|
||||
return navigationProperty.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSegmentValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,16 +25,10 @@ public class UriResourceRefImpl extends UriResourceImpl implements UriResourceRe
|
|||
|
||||
public UriResourceRefImpl() {
|
||||
super(UriResourceKind.ref);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSegmentValue(){
|
||||
public String getSegmentValue() {
|
||||
return "$ref";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSegmentValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(){
|
||||
public String getSegmentValue() {
|
||||
return singleton.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSegmentValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -46,29 +46,22 @@ import org.apache.olingo.server.api.uri.UriResourceRef;
|
|||
import org.apache.olingo.server.api.uri.UriResourceValue;
|
||||
import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.CustomQueryOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.QueryOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
import org.apache.olingo.server.core.uri.UriInfoImpl;
|
||||
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.antlr.UriLexer;
|
||||
import org.apache.olingo.server.core.uri.antlr.UriParserParser;
|
||||
import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandItemsEOFContext;
|
||||
import org.apache.olingo.server.core.uri.antlr.UriParserParser.FilterExpressionEOFContext;
|
||||
import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderByEOFContext;
|
||||
import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
|
||||
import org.apache.olingo.server.core.uri.parser.search.SearchParser;
|
||||
import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.FormatOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.IdOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.SkipTokenOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
|
||||
|
@ -84,9 +77,7 @@ public class Parser {
|
|||
private final Edm edm;
|
||||
private final OData odata;
|
||||
|
||||
private enum ParserEntryRules {
|
||||
ExpandItems, FilterExpression, Orderby
|
||||
}
|
||||
private enum ParserEntryRules { ExpandItems }
|
||||
|
||||
public Parser(final Edm edm, final OData odata) {
|
||||
this.edm = edm;
|
||||
|
@ -131,7 +122,7 @@ public class Parser {
|
|||
if (numberOfSegments > 1) {
|
||||
final String typeCastSegment = pathSegmentsDecoded.get(1);
|
||||
ensureLastSegment(typeCastSegment, 2, numberOfSegments);
|
||||
context.contextUriInfo = new ResourcePathParser(edm, odata).parseDollarEntityTypeCast(typeCastSegment);
|
||||
context.contextUriInfo = new ResourcePathParser(edm).parseDollarEntityTypeCast(typeCastSegment);
|
||||
context.contextTypes.push(context.contextUriInfo.getEntityTypeCast());
|
||||
} else {
|
||||
context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.entityId);
|
||||
|
@ -141,7 +132,7 @@ public class Parser {
|
|||
|
||||
} else if (firstSegment.startsWith("$crossjoin")) {
|
||||
ensureLastSegment(firstSegment, 1, numberOfSegments);
|
||||
context.contextUriInfo = new ResourcePathParser(edm, odata).parseCrossjoinSegment(firstSegment);
|
||||
context.contextUriInfo = new ResourcePathParser(edm).parseCrossjoinSegment(firstSegment);
|
||||
final EdmEntityContainer container = edm.getEntityContainer();
|
||||
for (final String name : context.contextUriInfo.getEntitySetNames()) {
|
||||
context.contextTypes.push(container.getEntitySet(name).getEntityType());
|
||||
|
@ -150,7 +141,7 @@ public class Parser {
|
|||
|
||||
} else {
|
||||
context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
|
||||
final ResourcePathParser resourcePathParser = new ResourcePathParser(edm, odata);
|
||||
final ResourcePathParser resourcePathParser = new ResourcePathParser(edm);
|
||||
int count = 0;
|
||||
UriResource lastSegment = null;
|
||||
for (final String pathSegment : pathSegmentsDecoded) {
|
||||
|
@ -183,7 +174,7 @@ public class Parser {
|
|||
|
||||
if (lastSegment instanceof UriResourcePartTyped) {
|
||||
final UriResourcePartTyped typed = (UriResourcePartTyped) lastSegment;
|
||||
final EdmType type = getTypeInformation(typed);
|
||||
final EdmType type = ParserHelper.getTypeInformation(typed);
|
||||
if (type != null) { // could be null for, e.g., actions without return type
|
||||
context.contextTypes.push(type);
|
||||
}
|
||||
|
@ -199,23 +190,13 @@ public class Parser {
|
|||
if (optionName.startsWith("$")) {
|
||||
SystemQueryOption systemOption = null;
|
||||
if (optionName.equals(SystemQueryOptionKind.FILTER.toString())) {
|
||||
try {
|
||||
FilterExpressionEOFContext ctxFilterExpression =
|
||||
(FilterExpressionEOFContext) parseRule(optionValue, ParserEntryRules.FilterExpression);
|
||||
systemOption = (FilterOptionImpl) uriParseTreeVisitor.visitFilterExpressionEOF(ctxFilterExpression);
|
||||
} catch (final ParseCancellationException e) {
|
||||
throw e.getCause() instanceof UriParserException ?
|
||||
(UriParserException) e.getCause() :
|
||||
new UriParserSyntaxException("Syntax error", e, UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
// UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
|
||||
// systemOption = new FilterOptionImpl().setExpression(
|
||||
// new ExpressionParser().parse(filterTokenizer));
|
||||
// if (!filterTokenizer.next(TokenKind.EOF)) {
|
||||
// throw new UriParserSyntaxException("Illegal value of $filter option!",
|
||||
// UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
|
||||
// optionName, optionValue);
|
||||
// }
|
||||
UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
|
||||
systemOption = new FilterParser(edm, odata).parse(filterTokenizer,
|
||||
context.contextTypes.peek() instanceof EdmStructuredType ?
|
||||
(EdmStructuredType) context.contextTypes.peek() :
|
||||
null,
|
||||
context.contextUriInfo.getEntitySetNames());
|
||||
checkOptionEOF(filterTokenizer, optionName, optionValue);
|
||||
|
||||
} else if (optionName.equals(SystemQueryOptionKind.FORMAT.toString())) {
|
||||
FormatOptionImpl formatOption = new FormatOptionImpl();
|
||||
|
@ -253,15 +234,13 @@ public class Parser {
|
|||
UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
|
||||
|
||||
} else if (optionName.equals(SystemQueryOptionKind.ORDERBY.toString())) {
|
||||
try {
|
||||
OrderByEOFContext ctxOrderByExpression =
|
||||
(OrderByEOFContext) parseRule(optionValue, ParserEntryRules.Orderby);
|
||||
systemOption = (OrderByOptionImpl) uriParseTreeVisitor.visitOrderByEOF(ctxOrderByExpression);
|
||||
} catch (final ParseCancellationException e) {
|
||||
throw e.getCause() instanceof UriParserException ?
|
||||
(UriParserException) e.getCause() :
|
||||
new UriParserSyntaxException("Syntax error", e, UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
UriTokenizer orderByTokenizer = new UriTokenizer(optionValue);
|
||||
systemOption = new OrderByParser(edm, odata).parse(orderByTokenizer,
|
||||
context.contextTypes.peek() instanceof EdmStructuredType ?
|
||||
(EdmStructuredType) context.contextTypes.peek() :
|
||||
null,
|
||||
context.contextUriInfo.getEntitySetNames());
|
||||
checkOptionEOF(orderByTokenizer, optionName, optionValue);
|
||||
|
||||
} else if (optionName.equals(SystemQueryOptionKind.SEARCH.toString())) {
|
||||
systemOption = new SearchParser().parse(optionValue);
|
||||
|
@ -273,11 +252,7 @@ public class Parser {
|
|||
(EdmStructuredType) context.contextTypes.peek() :
|
||||
null,
|
||||
context.isCollection);
|
||||
if (!selectTokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Illegal value of $select option!",
|
||||
UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
|
||||
optionName, optionValue);
|
||||
}
|
||||
checkOptionEOF(selectTokenizer, optionName, optionValue);
|
||||
|
||||
} else if (optionName.equals(SystemQueryOptionKind.SKIP.toString())) {
|
||||
SkipOptionImpl skipOption = new SkipOptionImpl();
|
||||
|
@ -343,15 +318,12 @@ public class Parser {
|
|||
UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
final FilterExpressionEOFContext filterExpCtx =
|
||||
(FilterExpressionEOFContext) parseRule(optionValue, ParserEntryRules.FilterExpression);
|
||||
expression = ((FilterOption) uriParseTreeVisitor.visitFilterExpressionEOF(filterExpCtx))
|
||||
.getExpression();
|
||||
} catch (final ParseCancellationException e) {
|
||||
throw e.getCause() instanceof UriParserException ?
|
||||
(UriParserException) e.getCause() :
|
||||
new UriParserSyntaxException("Syntax error", e, UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
UriTokenizer aliasValueTokenizer = new UriTokenizer(optionValue);
|
||||
expression = new ExpressionParser(edm, odata).parse(aliasValueTokenizer, null,
|
||||
context.contextUriInfo.getEntitySetNames());
|
||||
if (!aliasValueTokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Illegal value for alias '" + optionName + "'.",
|
||||
UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
}
|
||||
context.contextUriInfo.addAlias((AliasQueryOption) new AliasQueryOptionImpl()
|
||||
|
@ -384,28 +356,13 @@ public class Parser {
|
|||
return index > 0 && index < value.length() - 1 && index == value.lastIndexOf('/');
|
||||
}
|
||||
|
||||
protected static EdmType getTypeInformation(final UriResourcePartTyped resourcePart) {
|
||||
EdmType type = null;
|
||||
if (resourcePart instanceof UriResourceWithKeysImpl) {
|
||||
final UriResourceWithKeysImpl lastPartWithKeys = (UriResourceWithKeysImpl) resourcePart;
|
||||
if (lastPartWithKeys.getTypeFilterOnEntry() != null) {
|
||||
type = lastPartWithKeys.getTypeFilterOnEntry();
|
||||
} else if (lastPartWithKeys.getTypeFilterOnCollection() != null) {
|
||||
type = lastPartWithKeys.getTypeFilterOnCollection();
|
||||
} else {
|
||||
type = lastPartWithKeys.getType();
|
||||
}
|
||||
|
||||
} else if (resourcePart instanceof UriResourceTypedImpl) {
|
||||
final UriResourceTypedImpl lastPartTyped = (UriResourceTypedImpl) resourcePart;
|
||||
type = lastPartTyped.getTypeFilter() == null ?
|
||||
lastPartTyped.getType() :
|
||||
lastPartTyped.getTypeFilter();
|
||||
} else {
|
||||
type = resourcePart.getType();
|
||||
private void checkOptionEOF(UriTokenizer tokenizer, final String optionName, final String optionValue)
|
||||
throws UriParserException {
|
||||
if (!tokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Illegal value of '" + optionName + "' option!",
|
||||
UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
|
||||
optionName, optionValue);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private ParserRuleContext parseRule(final String input, final ParserEntryRules entryPoint)
|
||||
|
@ -435,14 +392,6 @@ public class Parser {
|
|||
|
||||
// parse
|
||||
switch (entryPoint) {
|
||||
case FilterExpression:
|
||||
lexer.mode(Lexer.DEFAULT_MODE);
|
||||
ret = parser.filterExpressionEOF();
|
||||
break;
|
||||
case Orderby:
|
||||
lexer.mode(Lexer.DEFAULT_MODE);
|
||||
ret = parser.orderByEOF();
|
||||
break;
|
||||
case ExpandItems:
|
||||
lexer.mode(Lexer.DEFAULT_MODE);
|
||||
ret = parser.expandItemsEOF();
|
||||
|
@ -471,14 +420,6 @@ public class Parser {
|
|||
|
||||
// parse
|
||||
switch (entryPoint) {
|
||||
case FilterExpression:
|
||||
lexer.mode(Lexer.DEFAULT_MODE);
|
||||
ret = parser.filterExpressionEOF();
|
||||
break;
|
||||
case Orderby:
|
||||
lexer.mode(Lexer.DEFAULT_MODE);
|
||||
ret = parser.orderByEOF();
|
||||
break;
|
||||
case ExpandItems:
|
||||
lexer.mode(Lexer.DEFAULT_MODE);
|
||||
ret = parser.expandItemsEOF();
|
||||
|
|
|
@ -18,10 +18,35 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core.uri.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
|
||||
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.EdmType;
|
||||
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
|
||||
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.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.core.ODataImpl;
|
||||
import org.apache.olingo.server.core.uri.UriParameterImpl;
|
||||
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.validator.UriValidationException;
|
||||
|
||||
public class ParserHelper {
|
||||
|
||||
private static final OData odata = new ODataImpl();
|
||||
|
||||
public static void requireNext(UriTokenizer tokenizer, final TokenKind required) throws UriParserException {
|
||||
if (!tokenizer.next(required)) {
|
||||
throw new UriParserSyntaxException("Expected token '" + required.toString() + "' not found.",
|
||||
|
@ -33,16 +58,16 @@ public class ParserHelper {
|
|||
requireNext(tokenizer, TokenKind.EOF);
|
||||
}
|
||||
|
||||
public static TokenKind next(UriTokenizer tokenizer, final TokenKind... kind) {
|
||||
for (int i = 0; i < kind.length; i++) {
|
||||
if (tokenizer.next(kind[i])) {
|
||||
return kind[i];
|
||||
public static TokenKind next(UriTokenizer tokenizer, final TokenKind... kinds) {
|
||||
for (final TokenKind kind : kinds) {
|
||||
if (tokenizer.next(kind)) {
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static TokenKind nextPrimitive(UriTokenizer tokenizer) {
|
||||
public static TokenKind nextPrimitiveValue(UriTokenizer tokenizer) {
|
||||
return next(tokenizer,
|
||||
TokenKind.NULL,
|
||||
TokenKind.BooleanValue,
|
||||
|
@ -62,4 +87,304 @@ public class ParserHelper {
|
|||
TokenKind.BinaryValue,
|
||||
TokenKind.EnumValue);
|
||||
}
|
||||
|
||||
protected static List<UriParameter> parseFunctionParameters(UriTokenizer tokenizer, final boolean withComplex)
|
||||
throws UriParserException {
|
||||
List<UriParameter> parameters = new ArrayList<UriParameter>();
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
|
||||
if (tokenizer.next(TokenKind.CLOSE)) {
|
||||
return parameters;
|
||||
}
|
||||
do {
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
|
||||
final String name = tokenizer.getText();
|
||||
if (parameters.contains(name)) {
|
||||
throw new UriParserSemanticException("Duplicated function parameter " + name,
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, name);
|
||||
}
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
|
||||
if (tokenizer.next(TokenKind.COMMA) || tokenizer.next(TokenKind.CLOSE) || tokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Parameter value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
if (tokenizer.next(TokenKind.ParameterAliasName)) {
|
||||
parameters.add(new UriParameterImpl().setName(name).setAlias(tokenizer.getText()));
|
||||
} else if (tokenizer.next(TokenKind.jsonArrayOrObject)) {
|
||||
if (withComplex) {
|
||||
parameters.add(new UriParameterImpl().setName(name).setText(tokenizer.getText()));
|
||||
} else {
|
||||
throw new UriParserSemanticException("A JSON array or object is not allowed as parameter value.",
|
||||
UriParserSemanticException.MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH, tokenizer.getText());
|
||||
}
|
||||
} else if (nextPrimitiveValue(tokenizer) == null) {
|
||||
throw new UriParserSemanticException("Wrong parameter value.",
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, "");
|
||||
} else {
|
||||
final String literalValue = tokenizer.getText();
|
||||
parameters.add(new UriParameterImpl().setName(name)
|
||||
.setText("null".equals(literalValue) ? null : literalValue));
|
||||
}
|
||||
} while (tokenizer.next(TokenKind.COMMA));
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
protected static List<UriParameter> parseNavigationKeyPredicate(UriTokenizer tokenizer,
|
||||
final EdmNavigationProperty navigationProperty) throws UriParserException, UriValidationException {
|
||||
if (tokenizer.next(TokenKind.OPEN)) {
|
||||
if (navigationProperty.isCollection()) {
|
||||
return parseKeyPredicate(tokenizer, navigationProperty.getType(), navigationProperty.getPartner());
|
||||
} else {
|
||||
throw new UriParserSemanticException("A key is not allowed on non-collection navigation properties.",
|
||||
UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static List<UriParameter> parseKeyPredicate(UriTokenizer tokenizer, final EdmEntityType edmEntityType,
|
||||
final EdmNavigationProperty partner) throws UriParserException, UriValidationException {
|
||||
final List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
||||
if (tokenizer.next(TokenKind.CLOSE)) {
|
||||
throw new UriParserSemanticException(
|
||||
"Expected " + keyPropertyRefs.size() + " key predicates but none.",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(keyPropertyRefs.size()), "0");
|
||||
}
|
||||
List<UriParameter> keys = new ArrayList<UriParameter>();
|
||||
Map<String, String> referencedNames = new HashMap<String, String>();
|
||||
|
||||
if (partner != null) {
|
||||
// Prepare list of potentially missing keys to be filled from referential constraints.
|
||||
for (final String name : edmEntityType.getKeyPredicateNames()) {
|
||||
final String referencedName = partner.getReferencingPropertyName(name);
|
||||
if (referencedName != null) {
|
||||
referencedNames.put(name, referencedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenizer.next(TokenKind.ODataIdentifier)) {
|
||||
keys.addAll(compoundKey(tokenizer, edmEntityType));
|
||||
} else if (keyPropertyRefs.size() - referencedNames.size() == 1) {
|
||||
for (final EdmKeyPropertyRef candidate : keyPropertyRefs) {
|
||||
if (referencedNames.get(candidate.getName()) == null) {
|
||||
keys.add(simpleKey(tokenizer, candidate));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new UriParserSemanticException(
|
||||
"Expected " + (keyPropertyRefs.size() -referencedNames.size()) + " key predicates but found one.",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(keyPropertyRefs.size() - referencedNames.size()), "1");
|
||||
}
|
||||
|
||||
if (keys.size() < keyPropertyRefs.size() && partner != null) {
|
||||
// Fill missing keys from referential constraints.
|
||||
for (final String name : edmEntityType.getKeyPredicateNames()) {
|
||||
boolean found = false;
|
||||
for (final UriParameter key : keys) {
|
||||
if (name.equals(key.getName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && referencedNames.get(name) != null) {
|
||||
keys.add(0, new UriParameterImpl().setName(name).setReferencedProperty(referencedNames.get(name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that all key predicates are filled from the URI.
|
||||
if (keys.size() < keyPropertyRefs.size()) {
|
||||
throw new UriParserSemanticException(
|
||||
"Expected " + keyPropertyRefs.size() + " key predicates but found " + keys.size() + ".",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(keyPropertyRefs.size()), Integer.toString(keys.size()));
|
||||
} else {
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
private static UriParameter simpleKey(UriTokenizer tokenizer, final EdmKeyPropertyRef edmKeyPropertyRef)
|
||||
throws UriParserException, UriValidationException {
|
||||
final EdmProperty edmProperty = edmKeyPropertyRef == null ? null : edmKeyPropertyRef.getProperty();
|
||||
if (nextPrimitiveTypeValue(tokenizer,
|
||||
edmProperty == null ? null : (EdmPrimitiveType) edmProperty.getType(),
|
||||
edmProperty == null ? false : edmProperty.isNullable())) {
|
||||
final String literalValue = tokenizer.getText();
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
|
||||
return createUriParameter(edmProperty, edmKeyPropertyRef.getName(), literalValue);
|
||||
} else {
|
||||
throw new UriParserSemanticException("The key value is not valid.",
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, edmKeyPropertyRef.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static List<UriParameter> compoundKey(UriTokenizer tokenizer, final EdmEntityType edmEntityType)
|
||||
throws UriParserException, UriValidationException {
|
||||
|
||||
List<UriParameter> parameters = new ArrayList<UriParameter>();
|
||||
List<String> parameterNames = new ArrayList<String>();
|
||||
|
||||
// To validate that each key predicate is exactly specified once, we use a list to pick from.
|
||||
List<String> remainingKeyNames = new ArrayList<String>(edmEntityType.getKeyPredicateNames());
|
||||
|
||||
// At least one key predicate is mandatory. Try to fetch all.
|
||||
boolean hasComma = false;
|
||||
do {
|
||||
final String keyPredicateName = tokenizer.getText();
|
||||
if (parameterNames.contains(keyPredicateName)) {
|
||||
throw new UriValidationException("Duplicated key property " + keyPredicateName,
|
||||
UriValidationException.MessageKeys.DOUBLE_KEY_PROPERTY, keyPredicateName);
|
||||
}
|
||||
if (remainingKeyNames.isEmpty()) {
|
||||
throw new UriParserSemanticException("Too many key properties.",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(parameters.size()), Integer.toString(parameters.size() + 1));
|
||||
}
|
||||
if (!remainingKeyNames.remove(keyPredicateName)) {
|
||||
throw new UriValidationException("Unknown key property " + keyPredicateName,
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, keyPredicateName);
|
||||
}
|
||||
parameters.add(keyValuePair(tokenizer, keyPredicateName, edmEntityType));
|
||||
parameterNames.add(keyPredicateName);
|
||||
hasComma = tokenizer.next(TokenKind.COMMA);
|
||||
if (hasComma) {
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
|
||||
}
|
||||
} while (hasComma);
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
protected static UriParameter keyValuePair(UriTokenizer tokenizer,
|
||||
final String keyPredicateName, final EdmEntityType edmEntityType)
|
||||
throws UriParserException, UriValidationException {
|
||||
final EdmKeyPropertyRef keyPropertyRef = edmEntityType.getKeyPropertyRef(keyPredicateName);
|
||||
final EdmProperty edmProperty = keyPropertyRef == null ? null : keyPropertyRef.getProperty();
|
||||
if (edmProperty == null) {
|
||||
throw new UriValidationException(keyPredicateName + " is not a valid key property name.",
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, keyPredicateName);
|
||||
}
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
|
||||
if (tokenizer.next(TokenKind.COMMA) || tokenizer.next(TokenKind.CLOSE) || tokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Key value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
if (nextPrimitiveTypeValue(tokenizer, (EdmPrimitiveType) edmProperty.getType(), edmProperty.isNullable())) {
|
||||
return createUriParameter(edmProperty, keyPredicateName, tokenizer.getText());
|
||||
} else {
|
||||
throw new UriParserSemanticException(keyPredicateName + " has not a valid key value.",
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, keyPredicateName);
|
||||
}
|
||||
}
|
||||
|
||||
private static UriParameter createUriParameter(final EdmProperty edmProperty, final String parameterName,
|
||||
final String literalValue) throws UriParserException, UriValidationException {
|
||||
if (literalValue.startsWith("@")) {
|
||||
return new UriParameterImpl()
|
||||
.setName(parameterName)
|
||||
.setAlias(literalValue);
|
||||
}
|
||||
|
||||
final EdmPrimitiveType primitiveType = (EdmPrimitiveType) edmProperty.getType();
|
||||
try {
|
||||
if (!(primitiveType.validate(primitiveType.fromUriLiteral(literalValue), edmProperty.isNullable(),
|
||||
edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode()))) {
|
||||
throw new UriValidationException("Invalid key property",
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
|
||||
}
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new UriValidationException("Invalid key property",
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
|
||||
}
|
||||
|
||||
return new UriParameterImpl()
|
||||
.setName(parameterName)
|
||||
.setText("null".equals(literalValue) ? null : literalValue);
|
||||
}
|
||||
|
||||
private static boolean nextPrimitiveTypeValue(UriTokenizer tokenizer,
|
||||
final EdmPrimitiveType primitiveType, final boolean nullable) {
|
||||
final EdmPrimitiveType type = primitiveType instanceof EdmTypeDefinition ?
|
||||
((EdmTypeDefinition) primitiveType).getUnderlyingType() :
|
||||
primitiveType;
|
||||
if (tokenizer.next(TokenKind.ParameterAliasName)) {
|
||||
return true;
|
||||
} else if (nullable && tokenizer.next(TokenKind.NULL)) {
|
||||
return true;
|
||||
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean).equals(type)) {
|
||||
return tokenizer.next(TokenKind.BooleanValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String).equals(type)) {
|
||||
return tokenizer.next(TokenKind.StringValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.SByte).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Byte).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int32).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int64).equals(type)) {
|
||||
return tokenizer.next(TokenKind.IntegerValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Guid).equals(type)) {
|
||||
return tokenizer.next(TokenKind.GuidValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Date).equals(type)) {
|
||||
return tokenizer.next(TokenKind.DateValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.DateTimeOffset).equals(type)) {
|
||||
return tokenizer.next(TokenKind.DateTimeOffsetValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.TimeOfDay).equals(type)) {
|
||||
return tokenizer.next(TokenKind.TimeOfDayValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Decimal).equals(type)) {
|
||||
// The order is important.
|
||||
// A decimal value should not be parsed as integer and let the tokenizer stop at the decimal point.
|
||||
return tokenizer.next(TokenKind.DecimalValue)
|
||||
|| tokenizer.next(TokenKind.IntegerValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Double).equals(type)) {
|
||||
// The order is important.
|
||||
// A floating-point value should not be parsed as decimal and let the tokenizer stop at 'E'.
|
||||
// A decimal value should not be parsed as integer and let the tokenizer stop at the decimal point.
|
||||
return tokenizer.next(TokenKind.DoubleValue)
|
||||
|| tokenizer.next(TokenKind.DecimalValue)
|
||||
|| tokenizer.next(TokenKind.IntegerValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Duration).equals(type)) {
|
||||
return tokenizer.next(TokenKind.DurationValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary).equals(type)) {
|
||||
return tokenizer.next(TokenKind.BinaryValue);
|
||||
} else if (type.getKind() == EdmTypeKind.ENUM) {
|
||||
return tokenizer.next(TokenKind.EnumValue);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected static List<String> getParameterNames(final List<UriParameter> parameters) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (final UriParameter parameter : parameters) {
|
||||
names.add(parameter.getName());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
protected static EdmType getTypeInformation(final UriResourcePartTyped resourcePart) {
|
||||
EdmType type = null;
|
||||
if (resourcePart instanceof UriResourceWithKeysImpl) {
|
||||
final UriResourceWithKeysImpl lastPartWithKeys = (UriResourceWithKeysImpl) resourcePart;
|
||||
if (lastPartWithKeys.getTypeFilterOnEntry() != null) {
|
||||
type = lastPartWithKeys.getTypeFilterOnEntry();
|
||||
} else if (lastPartWithKeys.getTypeFilterOnCollection() != null) {
|
||||
type = lastPartWithKeys.getTypeFilterOnCollection();
|
||||
} else {
|
||||
type = lastPartWithKeys.getType();
|
||||
}
|
||||
|
||||
} else if (resourcePart instanceof UriResourceTypedImpl) {
|
||||
final UriResourceTypedImpl lastPartTyped = (UriResourceTypedImpl) resourcePart;
|
||||
type = lastPartTyped.getTypeFilter() == null ?
|
||||
lastPartTyped.getType() :
|
||||
lastPartTyped.getTypeFilter();
|
||||
} else {
|
||||
type = resourcePart.getType();
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core.uri.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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.EdmAction;
|
||||
|
@ -31,25 +28,18 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
|||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunction;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
|
||||
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
|
||||
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.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.UriInfoKind;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.core.uri.UriInfoImpl;
|
||||
import org.apache.olingo.server.core.uri.UriParameterImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceActionImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceComplexPropertyImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceCountImpl;
|
||||
|
@ -69,13 +59,11 @@ public class ResourcePathParser {
|
|||
|
||||
private final Edm edm;
|
||||
private final EdmEntityContainer edmEntityContainer;
|
||||
private final OData odata;
|
||||
private UriTokenizer tokenizer;
|
||||
|
||||
public ResourcePathParser(final Edm edm, final OData odata) {
|
||||
public ResourcePathParser(final Edm edm) {
|
||||
this.edm = edm;
|
||||
edmEntityContainer = edm.getEntityContainer();
|
||||
this.odata = odata;
|
||||
}
|
||||
|
||||
public UriResource parsePathSegment(final String pathSegment, UriResource previous)
|
||||
|
@ -188,10 +176,11 @@ public class ResourcePathParser {
|
|||
|
||||
final EdmEntitySet edmEntitySet = edmEntityContainer.getEntitySet(oDataIdentifier);
|
||||
if (edmEntitySet != null) {
|
||||
final UriResourceEntitySetImpl entitySetResource = new UriResourceEntitySetImpl().setEntitSet(edmEntitySet);
|
||||
final UriResourceEntitySetImpl entitySetResource = new UriResourceEntitySetImpl(edmEntitySet);
|
||||
|
||||
if (tokenizer.next(TokenKind.OPEN)) {
|
||||
final List<UriParameter> keyPredicates = keyPredicate(entitySetResource.getEntityType(), null);
|
||||
final List<UriParameter> keyPredicates =
|
||||
ParserHelper.parseKeyPredicate(tokenizer, entitySetResource.getEntityType(), null);
|
||||
entitySetResource.setKeyPredicates(keyPredicates);
|
||||
}
|
||||
|
||||
|
@ -202,13 +191,13 @@ public class ResourcePathParser {
|
|||
final EdmSingleton edmSingleton = edmEntityContainer.getSingleton(oDataIdentifier);
|
||||
if (edmSingleton != null) {
|
||||
ParserHelper.requireTokenEnd(tokenizer);
|
||||
return new UriResourceSingletonImpl().setSingleton(edmSingleton);
|
||||
return new UriResourceSingletonImpl(edmSingleton);
|
||||
}
|
||||
|
||||
final EdmActionImport edmActionImport = edmEntityContainer.getActionImport(oDataIdentifier);
|
||||
if (edmActionImport != null) {
|
||||
ParserHelper.requireTokenEnd(tokenizer);
|
||||
return new UriResourceActionImpl().setActionImport(edmActionImport);
|
||||
return new UriResourceActionImpl(edmActionImport);
|
||||
}
|
||||
|
||||
final EdmFunctionImport edmFunctionImport = edmEntityContainer.getFunctionImport(oDataIdentifier);
|
||||
|
@ -252,8 +241,8 @@ public class ResourcePathParser {
|
|||
return property.isPrimitive()
|
||||
|| property.getType().getKind() == EdmTypeKind.ENUM
|
||||
|| property.getType().getKind() == EdmTypeKind.DEFINITION ?
|
||||
new UriResourcePrimitivePropertyImpl().setProperty(property) :
|
||||
new UriResourceComplexPropertyImpl().setProperty(property);
|
||||
new UriResourcePrimitivePropertyImpl(property) :
|
||||
new UriResourceComplexPropertyImpl(property);
|
||||
}
|
||||
final EdmNavigationProperty navigationProperty = structType.getNavigationProperty(name);
|
||||
if (navigationProperty == null) {
|
||||
|
@ -262,18 +251,9 @@ public class ResourcePathParser {
|
|||
UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE,
|
||||
structType.getFullQualifiedName().getFullQualifiedNameAsString(), name);
|
||||
}
|
||||
List<UriParameter> keyPredicate = null;
|
||||
if (tokenizer.next(TokenKind.OPEN)) {
|
||||
if (navigationProperty.isCollection()) {
|
||||
keyPredicate = keyPredicate(navigationProperty.getType(), navigationProperty.getPartner());
|
||||
} else {
|
||||
throw new UriParserSemanticException("A key is not allowed on non-collection navigation properties.",
|
||||
UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
List<UriParameter> keyPredicate = ParserHelper.parseNavigationKeyPredicate(tokenizer, navigationProperty);
|
||||
ParserHelper.requireTokenEnd(tokenizer);
|
||||
return new UriResourceNavigationPropertyImpl()
|
||||
.setNavigationProperty(navigationProperty)
|
||||
return new UriResourceNavigationPropertyImpl(navigationProperty)
|
||||
.setKeyPredicates(keyPredicate);
|
||||
}
|
||||
|
||||
|
@ -289,7 +269,7 @@ public class ResourcePathParser {
|
|||
previousTyped.isCollection());
|
||||
if (boundAction != null) {
|
||||
ParserHelper.requireTokenEnd(tokenizer);
|
||||
return new UriResourceActionImpl().setAction(boundAction);
|
||||
return new UriResourceActionImpl(boundAction);
|
||||
}
|
||||
EdmStructuredType type = edm.getEntityType(name);
|
||||
if (type == null) {
|
||||
|
@ -314,169 +294,6 @@ public class ResourcePathParser {
|
|||
}
|
||||
}
|
||||
|
||||
private List<UriParameter> keyPredicate(final EdmEntityType edmEntityType, final EdmNavigationProperty partner)
|
||||
throws UriParserException, UriValidationException {
|
||||
final List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
||||
if (tokenizer.next(TokenKind.CLOSE)) {
|
||||
throw new UriParserSemanticException(
|
||||
"Expected " + keyPropertyRefs.size() + " key predicates but none.",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(keyPropertyRefs.size()), "0");
|
||||
}
|
||||
List<UriParameter> keys = new ArrayList<UriParameter>();
|
||||
Map<String, String> referencedNames = new HashMap<String, String>();
|
||||
|
||||
if (partner != null) {
|
||||
// Prepare list of potentially missing keys to be filled from referential constraints.
|
||||
for (final String name : edmEntityType.getKeyPredicateNames()) {
|
||||
final String referencedName = partner.getReferencingPropertyName(name);
|
||||
if (referencedName != null) {
|
||||
referencedNames.put(name, referencedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenizer.next(TokenKind.ODataIdentifier)) {
|
||||
keys.addAll(compoundKey(edmEntityType));
|
||||
} else if (keyPropertyRefs.size() - referencedNames.size() == 1) {
|
||||
for (final EdmKeyPropertyRef candidate : keyPropertyRefs) {
|
||||
if (referencedNames.get(candidate.getName()) == null) {
|
||||
keys.add(simpleKey(candidate));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new UriParserSemanticException(
|
||||
"Expected " + (keyPropertyRefs.size() -referencedNames.size()) + " key predicates but found one.",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(keyPropertyRefs.size() - referencedNames.size()), "1");
|
||||
}
|
||||
|
||||
if (keys.size() < keyPropertyRefs.size() && partner != null) {
|
||||
// Fill missing keys from referential constraints.
|
||||
for (final String name : edmEntityType.getKeyPredicateNames()) {
|
||||
boolean found = false;
|
||||
for (final UriParameter key : keys) {
|
||||
if (name.equals(key.getName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && referencedNames.get(name) != null) {
|
||||
keys.add(0, new UriParameterImpl().setName(name).setReferencedProperty(referencedNames.get(name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that all key predicates are filled from the URI.
|
||||
if (keys.size() < keyPropertyRefs.size()) {
|
||||
throw new UriParserSemanticException(
|
||||
"Expected " + keyPropertyRefs.size() + " key predicates but found " + keys.size() + ".",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(keyPropertyRefs.size()), Integer.toString(keys.size()));
|
||||
} else {
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
private UriParameter simpleKey(final EdmKeyPropertyRef edmKeyPropertyRef)
|
||||
throws UriParserException, UriValidationException {
|
||||
final EdmProperty edmProperty = edmKeyPropertyRef == null ? null : edmKeyPropertyRef.getProperty();
|
||||
if (nextPrimitiveTypeValue(
|
||||
edmProperty == null ? null : (EdmPrimitiveType) edmProperty.getType(),
|
||||
edmProperty == null ? false : edmProperty.isNullable())) {
|
||||
final String literalValue = tokenizer.getText();
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
|
||||
return createUriParameter(edmProperty, edmKeyPropertyRef.getName(), literalValue);
|
||||
} else {
|
||||
throw new UriParserSemanticException("The key value is not valid.",
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, edmKeyPropertyRef.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private List<UriParameter> compoundKey(final EdmEntityType edmEntityType)
|
||||
throws UriParserException, UriValidationException {
|
||||
|
||||
List<UriParameter> parameters = new ArrayList<UriParameter>();
|
||||
List<String> parameterNames = new ArrayList<String>();
|
||||
|
||||
// To validate that each key predicate is exactly specified once, we use a list to pick from.
|
||||
List<String> remainingKeyNames = new ArrayList<String>(edmEntityType.getKeyPredicateNames());
|
||||
|
||||
// At least one key predicate is mandatory. Try to fetch all.
|
||||
boolean hasComma = false;
|
||||
do {
|
||||
final String keyPredicateName = tokenizer.getText();
|
||||
if (parameterNames.contains(keyPredicateName)) {
|
||||
throw new UriValidationException("Duplicated key property " + keyPredicateName,
|
||||
UriValidationException.MessageKeys.DOUBLE_KEY_PROPERTY, keyPredicateName);
|
||||
}
|
||||
if (remainingKeyNames.isEmpty()) {
|
||||
throw new UriParserSemanticException("Too many key properties.",
|
||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||
Integer.toString(parameters.size()), Integer.toString(parameters.size() + 1));
|
||||
}
|
||||
if (!remainingKeyNames.remove(keyPredicateName)) {
|
||||
throw new UriValidationException("Unknown key property " + keyPredicateName,
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, keyPredicateName);
|
||||
}
|
||||
parameters.add(keyValuePair(keyPredicateName, edmEntityType));
|
||||
parameterNames.add(keyPredicateName);
|
||||
hasComma = tokenizer.next(TokenKind.COMMA);
|
||||
if (hasComma) {
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
|
||||
}
|
||||
} while (hasComma);
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private UriParameter keyValuePair(final String keyPredicateName, final EdmEntityType edmEntityType)
|
||||
throws UriParserException, UriValidationException {
|
||||
final EdmKeyPropertyRef keyPropertyRef = edmEntityType.getKeyPropertyRef(keyPredicateName);
|
||||
final EdmProperty edmProperty = keyPropertyRef == null ? null : keyPropertyRef.getProperty();
|
||||
if (edmProperty == null) {
|
||||
throw new UriValidationException(keyPredicateName + " is not a valid key property name.",
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, keyPredicateName);
|
||||
}
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
|
||||
if (tokenizer.next(TokenKind.COMMA) || tokenizer.next(TokenKind.CLOSE) || tokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Key value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
if (nextPrimitiveTypeValue((EdmPrimitiveType) edmProperty.getType(), edmProperty.isNullable())) {
|
||||
return createUriParameter(edmProperty, keyPredicateName, tokenizer.getText());
|
||||
} else {
|
||||
throw new UriParserSemanticException(keyPredicateName + " has not a valid key value.",
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, keyPredicateName);
|
||||
}
|
||||
}
|
||||
|
||||
private UriParameter createUriParameter(final EdmProperty edmProperty, final String parameterName,
|
||||
final String literalValue) throws UriParserException, UriValidationException {
|
||||
if (literalValue.startsWith("@")) {
|
||||
return new UriParameterImpl()
|
||||
.setName(parameterName)
|
||||
.setAlias(literalValue);
|
||||
}
|
||||
|
||||
final EdmPrimitiveType primitiveType = (EdmPrimitiveType) edmProperty.getType();
|
||||
try {
|
||||
if (!(primitiveType.validate(primitiveType.fromUriLiteral(literalValue), edmProperty.isNullable(),
|
||||
edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode()))) {
|
||||
throw new UriValidationException("Invalid key property",
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
|
||||
}
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new UriValidationException("Invalid key property",
|
||||
UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
|
||||
}
|
||||
|
||||
return new UriParameterImpl()
|
||||
.setName(parameterName)
|
||||
.setText("null".equals(literalValue) ? null : literalValue);
|
||||
}
|
||||
|
||||
private UriResource typeCast(final FullQualifiedName name, final EdmStructuredType type,
|
||||
final UriResourcePartTyped previousTyped) throws UriParserException, UriValidationException {
|
||||
if (type.compatibleTo(previousTyped.getType())) {
|
||||
|
@ -501,7 +318,7 @@ public class ResourcePathParser {
|
|||
}
|
||||
if (tokenizer.next(TokenKind.OPEN)) {
|
||||
((UriResourceWithKeysImpl) previousTyped).setKeyPredicates(
|
||||
keyPredicate((EdmEntityType) type, null));
|
||||
ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) type, null));
|
||||
}
|
||||
} else {
|
||||
previousTypeFilter = ((UriResourceTypedImpl) previousTyped).getTypeFilter();
|
||||
|
@ -534,11 +351,8 @@ public class ResourcePathParser {
|
|||
private UriResource functionCall(final EdmFunctionImport edmFunctionImport,
|
||||
final FullQualifiedName boundFunctionName, final FullQualifiedName bindingParameterTypeName,
|
||||
final boolean isBindingParameterCollection) throws UriParserException, UriValidationException {
|
||||
final List<UriParameter> parameters = functionParameters();
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (final UriParameter parameter : parameters) {
|
||||
names.add(parameter.getName());
|
||||
}
|
||||
final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, false);
|
||||
final List<String> names = ParserHelper.getParameterNames(parameters);
|
||||
EdmFunction function = null;
|
||||
if (edmFunctionImport != null) {
|
||||
function = edmFunctionImport.getUnboundFunction(names);
|
||||
|
@ -557,16 +371,13 @@ public class ResourcePathParser {
|
|||
UriParserSemanticException.MessageKeys.UNKNOWN_PART, boundFunctionName.getFullQualifiedNameAsString());
|
||||
}
|
||||
}
|
||||
UriResourceFunctionImpl resource = new UriResourceFunctionImpl()
|
||||
.setFunctionImport(edmFunctionImport, null)
|
||||
.setFunction(function)
|
||||
.setParameters(parameters);
|
||||
UriResourceFunctionImpl resource = new UriResourceFunctionImpl(edmFunctionImport, function, parameters);
|
||||
if (tokenizer.next(TokenKind.OPEN)) {
|
||||
if (function.getReturnType() != null
|
||||
&& function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY
|
||||
&& function.getReturnType().isCollection()) {
|
||||
resource.setKeyPredicates(
|
||||
keyPredicate((EdmEntityType) function.getReturnType().getType(), null));
|
||||
ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) function.getReturnType().getType(), null));
|
||||
} else {
|
||||
throw new UriParserSemanticException("A key is not allowed.",
|
||||
UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);
|
||||
|
@ -575,106 +386,4 @@ public class ResourcePathParser {
|
|||
ParserHelper.requireTokenEnd(tokenizer);
|
||||
return resource;
|
||||
}
|
||||
|
||||
private List<UriParameter> functionParameters() throws UriParserException {
|
||||
List<UriParameter> parameters = new ArrayList<UriParameter>();
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
|
||||
if (tokenizer.next(TokenKind.CLOSE)) {
|
||||
return parameters;
|
||||
}
|
||||
do {
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
|
||||
final String name = tokenizer.getText();
|
||||
if (parameters.contains(name)) {
|
||||
throw new UriParserSemanticException("Duplicated function parameter " + name,
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, name);
|
||||
}
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
|
||||
if (tokenizer.next(TokenKind.COMMA) || tokenizer.next(TokenKind.CLOSE) || tokenizer.next(TokenKind.EOF)) {
|
||||
throw new UriParserSyntaxException("Parameter value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
|
||||
}
|
||||
if (tokenizer.next(TokenKind.ParameterAliasName)) {
|
||||
parameters.add(new UriParameterImpl().setName(name).setAlias(tokenizer.getText()));
|
||||
} else if (nextPrimitiveValue()) {
|
||||
final String literalValue = tokenizer.getText();
|
||||
parameters.add(new UriParameterImpl().setName(name)
|
||||
.setText("null".equals(literalValue) ? null : literalValue));
|
||||
} else {
|
||||
throw new UriParserSemanticException("Wrong parameter value.",
|
||||
UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, "");
|
||||
}
|
||||
} while (tokenizer.next(TokenKind.COMMA));
|
||||
ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private boolean nextPrimitiveTypeValue(final EdmPrimitiveType primitiveType, final boolean nullable) {
|
||||
final EdmPrimitiveType type = primitiveType instanceof EdmTypeDefinition ?
|
||||
((EdmTypeDefinition) primitiveType).getUnderlyingType() :
|
||||
primitiveType;
|
||||
if (tokenizer.next(TokenKind.ParameterAliasName)) {
|
||||
return true;
|
||||
} else if (nullable && tokenizer.next(TokenKind.NULL)) {
|
||||
return true;
|
||||
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean).equals(type)) {
|
||||
return tokenizer.next(TokenKind.BooleanValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String).equals(type)) {
|
||||
return tokenizer.next(TokenKind.StringValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.SByte).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Byte).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int32).equals(type)
|
||||
|| odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int64).equals(type)) {
|
||||
return tokenizer.next(TokenKind.IntegerValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Guid).equals(type)) {
|
||||
return tokenizer.next(TokenKind.GuidValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Date).equals(type)) {
|
||||
return tokenizer.next(TokenKind.DateValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.DateTimeOffset).equals(type)) {
|
||||
return tokenizer.next(TokenKind.DateTimeOffsetValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.TimeOfDay).equals(type)) {
|
||||
return tokenizer.next(TokenKind.TimeOfDayValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Decimal).equals(type)) {
|
||||
// The order is important.
|
||||
// A decimal value should not be parsed as integer and let the tokenizer stop at the decimal point.
|
||||
return tokenizer.next(TokenKind.DecimalValue)
|
||||
|| tokenizer.next(TokenKind.IntegerValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Double).equals(type)) {
|
||||
// The order is important.
|
||||
// A floating-point value should not be parsed as decimal and let the tokenizer stop at 'E'.
|
||||
// A decimal value should not be parsed as integer and let the tokenizer stop at the decimal point.
|
||||
return tokenizer.next(TokenKind.DoubleValue)
|
||||
|| tokenizer.next(TokenKind.DecimalValue)
|
||||
|| tokenizer.next(TokenKind.IntegerValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Duration).equals(type)) {
|
||||
return tokenizer.next(TokenKind.DurationValue);
|
||||
} else if (odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary).equals(type)) {
|
||||
return tokenizer.next(TokenKind.BinaryValue);
|
||||
} else if (type.getKind() == EdmTypeKind.ENUM) {
|
||||
return tokenizer.next(TokenKind.EnumValue);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean nextPrimitiveValue() {
|
||||
return tokenizer.next(TokenKind.NULL)
|
||||
|| tokenizer.next(TokenKind.BooleanValue)
|
||||
|| tokenizer.next(TokenKind.StringValue)
|
||||
|
||||
// The order of the next seven expressions is important in order to avoid
|
||||
// finding partly parsed tokens (counter-intuitive as it may be, even a GUID may start with digits ...).
|
||||
|| tokenizer.next(TokenKind.DoubleValue)
|
||||
|| tokenizer.next(TokenKind.DecimalValue)
|
||||
|| tokenizer.next(TokenKind.GuidValue)
|
||||
|| tokenizer.next(TokenKind.DateTimeOffsetValue)
|
||||
|| tokenizer.next(TokenKind.DateValue)
|
||||
|| tokenizer.next(TokenKind.TimeOfDayValue)
|
||||
|| tokenizer.next(TokenKind.IntegerValue)
|
||||
|
||||
|| tokenizer.next(TokenKind.DurationValue)
|
||||
|| tokenizer.next(TokenKind.BinaryValue)
|
||||
|| tokenizer.next(TokenKind.EnumValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,10 +156,10 @@ public class SelectParser {
|
|||
throw new UriParserSemanticException("Function not found.",
|
||||
UriParserSemanticException.MessageKeys.UNKNOWN_PART, qualifiedName.getFullQualifiedNameAsString());
|
||||
} else {
|
||||
return new UriResourceFunctionImpl().setFunction(boundFunction);
|
||||
return new UriResourceFunctionImpl(null, boundFunction, null);
|
||||
}
|
||||
} else {
|
||||
return new UriResourceActionImpl().setAction(boundAction);
|
||||
return new UriResourceActionImpl(boundAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,16 +187,16 @@ public class SelectParser {
|
|||
UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE,
|
||||
referencedType.getName(), name);
|
||||
} else {
|
||||
resource.addResourcePart(new UriResourceNavigationPropertyImpl().setNavigationProperty(navigationProperty));
|
||||
resource.addResourcePart(new UriResourceNavigationPropertyImpl(navigationProperty));
|
||||
}
|
||||
|
||||
} else if (property.isPrimitive()
|
||||
|| property.getType().getKind() == EdmTypeKind.ENUM
|
||||
|| property.getType().getKind() == EdmTypeKind.DEFINITION) {
|
||||
resource.addResourcePart(new UriResourcePrimitivePropertyImpl().setProperty(property));
|
||||
resource.addResourcePart(new UriResourcePrimitivePropertyImpl(property));
|
||||
|
||||
} else {
|
||||
UriResourceComplexPropertyImpl complexPart = new UriResourceComplexPropertyImpl().setProperty(property);
|
||||
UriResourceComplexPropertyImpl complexPart = new UriResourceComplexPropertyImpl(property);
|
||||
resource.addResourcePart(complexPart);
|
||||
if (tokenizer.next(TokenKind.SLASH)) {
|
||||
if (tokenizer.next(TokenKind.QualifiedName)) {
|
||||
|
|
|
@ -32,10 +32,9 @@ import org.apache.olingo.server.core.uri.queryoption.SelectItemImpl;
|
|||
*/
|
||||
public class UriContext {
|
||||
|
||||
public static class LambdaVariables {
|
||||
public static class LambdaVariable {
|
||||
public String name;
|
||||
public EdmType type;
|
||||
public boolean isCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +42,7 @@ public class UriContext {
|
|||
* As lambda functions can be nested there may be more than one allowed lambda variables at a time while parsing a
|
||||
* $filter or $orderby expressions.
|
||||
*/
|
||||
public Deque<LambdaVariables> allowedLambdaVariables;
|
||||
public Deque<LambdaVariable> allowedLambdaVariables;
|
||||
/**
|
||||
* Used to stack type information for nested $expand, $filter query options and other cases.
|
||||
*/
|
||||
|
@ -110,7 +109,7 @@ public class UriContext {
|
|||
contextReadingFunctionParameters = false;
|
||||
contextSelectItem = null;
|
||||
contextTypes = new ArrayDeque<EdmType>();
|
||||
allowedLambdaVariables = new ArrayDeque<UriContext.LambdaVariables>();
|
||||
allowedLambdaVariables = new ArrayDeque<UriContext.LambdaVariable>();
|
||||
|
||||
}
|
||||
}
|
|
@ -252,8 +252,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
return new FullQualifiedName(namespace, odi);
|
||||
}
|
||||
|
||||
private UriContext.LambdaVariables getLambdaVar(final String odi) {
|
||||
for (UriContext.LambdaVariables item : context.allowedLambdaVariables) {
|
||||
private UriContext.LambdaVariable getLambdaVar(final String odi) {
|
||||
for (UriContext.LambdaVariable item : context.allowedLambdaVariables) {
|
||||
if (item.name.equals(odi)) {
|
||||
return item;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|| parts.get(0) instanceof UriResourceRoot)) {
|
||||
ensureNamespaceIsNull(ctx.vNS);
|
||||
context.contextUriInfo.addResourcePart(
|
||||
new UriResourceEntitySetImpl().setEntitSet(edmEntitySet));
|
||||
new UriResourceEntitySetImpl(edmEntitySet));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|| parts.get(0) instanceof UriResourceRoot)) {
|
||||
ensureNamespaceIsNull(ctx.vNS);
|
||||
context.contextUriInfo.addResourcePart(
|
||||
new UriResourceSingletonImpl().setSingleton(edmSingleton));
|
||||
new UriResourceSingletonImpl(edmSingleton));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|| parts.get(0) instanceof UriResourceRoot)) {
|
||||
ensureNamespaceIsNull(ctx.vNS);
|
||||
context.contextUriInfo.addResourcePart(
|
||||
new UriResourceActionImpl().setActionImport(edmActionImport));
|
||||
new UriResourceActionImpl(edmActionImport));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -344,9 +344,6 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
// mark parameters as consumed
|
||||
ctx.vlNVO.remove(0);
|
||||
|
||||
UriResourceFunctionImpl uriResource = new UriResourceFunctionImpl()
|
||||
.setFunctionImport(edmFunctionImport, parameters);
|
||||
|
||||
// collect parameter names
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (UriParameter item : parameters) {
|
||||
|
@ -366,7 +363,9 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
}
|
||||
|
||||
ensureNamespaceIsNull(ctx.vNS);
|
||||
uriResource.setFunction(edmFunctionImport.getUnboundFunction(names));
|
||||
UriResourceFunctionImpl uriResource = new UriResourceFunctionImpl(edmFunctionImport,
|
||||
edmFunctionImport.getUnboundFunction(names),
|
||||
parameters);
|
||||
context.contextUriInfo.addResourcePart(uriResource);
|
||||
return null;
|
||||
}
|
||||
|
@ -390,7 +389,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
sourceType = context.contextTypes.peek();
|
||||
sourceIsCollection = context.isCollection;
|
||||
} else if (lastResourcePart instanceof UriResourcePartTyped) {
|
||||
sourceType = Parser.getTypeInformation((UriResourcePartTyped) lastResourcePart);
|
||||
sourceType = ParserHelper.getTypeInformation((UriResourcePartTyped) lastResourcePart);
|
||||
sourceIsCollection = ((UriResourcePartTyped) lastResourcePart).isCollection();
|
||||
} else {
|
||||
throw wrap(new UriParserSemanticException(
|
||||
|
@ -401,12 +400,9 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
if (ctx.vNS == null) { // without namespace
|
||||
|
||||
// first check for lambda variable because a newly add property should not shadow a long used lambda variable
|
||||
UriContext.LambdaVariables lVar = getLambdaVar(odi);
|
||||
UriContext.LambdaVariable lVar = getLambdaVar(odi);
|
||||
if (lVar != null) {
|
||||
UriResourceLambdaVarImpl lambdaResource = new UriResourceLambdaVarImpl();
|
||||
lambdaResource.setVariableText(lVar.name);
|
||||
lambdaResource.setType(lVar.type);
|
||||
lambdaResource.setCollection(lVar.isCollection);
|
||||
UriResourceLambdaVarImpl lambdaResource = new UriResourceLambdaVarImpl(lVar.name, lVar.type);
|
||||
context.contextUriInfo.addResourcePart(lambdaResource);
|
||||
return null;
|
||||
}
|
||||
|
@ -442,14 +438,13 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|| property.getType().getKind() == EdmTypeKind.ENUM
|
||||
|| property.getType().getKind() == EdmTypeKind.DEFINITION) {
|
||||
// create simple property
|
||||
UriResourcePrimitivePropertyImpl simpleResource = new UriResourcePrimitivePropertyImpl()
|
||||
.setProperty((EdmProperty) property);
|
||||
UriResourcePrimitivePropertyImpl simpleResource =
|
||||
new UriResourcePrimitivePropertyImpl((EdmProperty) property);
|
||||
context.contextUriInfo.addResourcePart(simpleResource);
|
||||
return null;
|
||||
} else {
|
||||
// create complex property
|
||||
UriResourceComplexPropertyImpl complexResource = new UriResourceComplexPropertyImpl()
|
||||
.setProperty((EdmProperty) property);
|
||||
UriResourceComplexPropertyImpl complexResource = new UriResourceComplexPropertyImpl((EdmProperty) property);
|
||||
context.contextUriInfo.addResourcePart(complexResource);
|
||||
return null;
|
||||
}
|
||||
|
@ -461,8 +456,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
|
||||
}
|
||||
|
||||
UriResourceNavigationPropertyImpl navigationResource = new UriResourceNavigationPropertyImpl()
|
||||
.setNavigationProperty((EdmNavigationProperty) property);
|
||||
UriResourceNavigationPropertyImpl navigationResource =
|
||||
new UriResourceNavigationPropertyImpl((EdmNavigationProperty) property);
|
||||
context.contextUriInfo.addResourcePart(navigationResource);
|
||||
return null;
|
||||
} else {
|
||||
|
@ -488,9 +483,9 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|
||||
if (lastResourcePart == null) {
|
||||
// this may be the case if a member expression within a filter starts with a typeCast
|
||||
UriResourceStartingTypeFilterImpl uriResource = new UriResourceStartingTypeFilterImpl()
|
||||
.setType(filterEntityType)
|
||||
.setCollection(sourceIsCollection);
|
||||
UriResourceStartingTypeFilterImpl uriResource = new UriResourceStartingTypeFilterImpl(
|
||||
filterEntityType,
|
||||
sourceIsCollection);
|
||||
if (sourceIsCollection) {
|
||||
uriResource.setCollectionTypeFilter(filterEntityType);
|
||||
} else {
|
||||
|
@ -562,9 +557,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
// is simple complex type cast
|
||||
if (lastResourcePart == null) {
|
||||
// this may be the case if a member expression within a filter starts with a typeCast
|
||||
UriResourceStartingTypeFilterImpl uriResource = new UriResourceStartingTypeFilterImpl()
|
||||
.setType(filterComplexType)
|
||||
.setCollection(sourceIsCollection);
|
||||
UriResourceStartingTypeFilterImpl uriResource =
|
||||
new UriResourceStartingTypeFilterImpl(filterComplexType, sourceIsCollection);
|
||||
|
||||
if (sourceIsCollection) {
|
||||
uriResource.setCollectionTypeFilter(filterComplexType);
|
||||
|
@ -626,8 +620,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
// check for action
|
||||
EdmAction action = edm.getBoundAction(fullFilterName, fullBindingTypeName, sourceIsCollection);
|
||||
if (action != null) {
|
||||
UriResourceActionImpl pathInfoAction = new UriResourceActionImpl();
|
||||
pathInfoAction.setAction(action);
|
||||
UriResourceActionImpl pathInfoAction = new UriResourceActionImpl(action);
|
||||
context.contextUriInfo.addResourcePart(pathInfoAction);
|
||||
return null;
|
||||
}
|
||||
|
@ -652,9 +645,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
EdmFunction function = edm.getBoundFunction(fullFilterName, fullBindingTypeName, sourceIsCollection, names);
|
||||
|
||||
if (function != null) {
|
||||
UriResourceFunctionImpl pathInfoFunction = new UriResourceFunctionImpl()
|
||||
.setFunction(function)
|
||||
.setParameters(parameters);
|
||||
UriResourceFunctionImpl pathInfoFunction = new UriResourceFunctionImpl(null, function, parameters);
|
||||
context.contextUriInfo.addResourcePart(pathInfoFunction);
|
||||
|
||||
// mark parameters as consumed
|
||||
|
@ -666,9 +657,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
function = edm.getUnboundFunction(fullFilterName, names);
|
||||
|
||||
if (function != null) {
|
||||
UriResourceFunctionImpl pathInfoFunction = new UriResourceFunctionImpl()
|
||||
.setFunction(function)
|
||||
.setParameters(parameters);
|
||||
UriResourceFunctionImpl pathInfoFunction = new UriResourceFunctionImpl(null, function, parameters);
|
||||
context.contextUriInfo.addResourcePart(pathInfoFunction);
|
||||
|
||||
// mark parameters as consumed
|
||||
|
@ -706,8 +695,6 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|
||||
@Override
|
||||
public Object visitAllExpr(final AllExprContext ctx) {
|
||||
UriResourceLambdaAllImpl all = new UriResourceLambdaAllImpl();
|
||||
|
||||
UriResource obj = context.contextUriInfo.getLastResourcePart();
|
||||
if (!(obj instanceof UriResourcePartTyped)) {
|
||||
throw wrap(new UriParserSemanticException("all only allowed on typed path segments",
|
||||
|
@ -720,16 +707,14 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
}
|
||||
}
|
||||
|
||||
UriContext.LambdaVariables var = new UriContext.LambdaVariables();
|
||||
UriContext.LambdaVariable var = new UriContext.LambdaVariable();
|
||||
var.name = ctx.vLV.getText();
|
||||
var.type = Parser.getTypeInformation((UriResourcePartTyped) obj);
|
||||
var.isCollection = false;
|
||||
var.type = ParserHelper.getTypeInformation((UriResourcePartTyped) obj);
|
||||
|
||||
all.setLamdaVariable(ctx.vLV.getText());
|
||||
context.allowedLambdaVariables.push(var);
|
||||
all.setExpression((Expression) ctx.vLE.accept(this));
|
||||
Expression expression = (Expression) ctx.vLE.accept(this);
|
||||
context.allowedLambdaVariables.pop();
|
||||
return all;
|
||||
return new UriResourceLambdaAllImpl(var.name, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -895,7 +880,6 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|
||||
@Override
|
||||
public Object visitAnyExpr(final AnyExprContext ctx) {
|
||||
UriResourceLambdaAnyImpl any = new UriResourceLambdaAnyImpl();
|
||||
if (ctx.vLV != null) {
|
||||
UriResourceImpl lastResourcePart = (UriResourceImpl) context.contextUriInfo.getLastResourcePart();
|
||||
if (!(lastResourcePart instanceof UriResourcePartTyped)) {
|
||||
|
@ -909,17 +893,16 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
}
|
||||
}
|
||||
|
||||
UriContext.LambdaVariables var = new UriContext.LambdaVariables();
|
||||
UriContext.LambdaVariable var = new UriContext.LambdaVariable();
|
||||
var.name = ctx.vLV.getText();
|
||||
var.type = Parser.getTypeInformation((UriResourcePartTyped) lastResourcePart);
|
||||
var.isCollection = false;
|
||||
var.type = ParserHelper.getTypeInformation((UriResourcePartTyped) lastResourcePart);
|
||||
|
||||
any.setLamdaVariable(ctx.vLV.getText());
|
||||
context.allowedLambdaVariables.push(var);
|
||||
any.setExpression((Expression) ctx.vLE.accept(this));
|
||||
Expression expression = (Expression) ctx.vLE.accept(this);
|
||||
context.allowedLambdaVariables.pop();
|
||||
return new UriResourceLambdaAnyImpl(var.name, expression);
|
||||
}
|
||||
return any;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1238,18 +1221,18 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
if (context.contextExpandItemPath == null) {
|
||||
// use the type of the last resource path segement
|
||||
UriResourceTypedImpl lastSegment = (UriResourceTypedImpl) context.contextUriInfo.getLastResourcePart();
|
||||
targetType = Parser.getTypeInformation(lastSegment);
|
||||
targetType = ParserHelper.getTypeInformation(lastSegment);
|
||||
isColl = lastSegment.isCollection();
|
||||
} else {
|
||||
if (context.contextExpandItemPath.getResourcePath() == null) {
|
||||
// use the type of the last resource path segement
|
||||
UriResourceTypedImpl lastSegment = (UriResourceTypedImpl) context.contextUriInfo.getLastResourcePart();
|
||||
targetType = Parser.getTypeInformation(lastSegment);
|
||||
targetType = ParserHelper.getTypeInformation(lastSegment);
|
||||
isColl = lastSegment.isCollection();
|
||||
} else {
|
||||
// use the type of the last ''expand'' path segement
|
||||
UriInfoImpl info = (UriInfoImpl) context.contextExpandItemPath.getResourcePath();
|
||||
targetType = Parser.getTypeInformation((UriResourcePartTyped) info.getLastResourcePart());
|
||||
targetType = ParserHelper.getTypeInformation((UriResourcePartTyped) info.getLastResourcePart());
|
||||
isColl = ((UriResourcePartTyped) info.getLastResourcePart()).isCollection();
|
||||
}
|
||||
}
|
||||
|
@ -1400,10 +1383,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
}
|
||||
|
||||
if (ctx.vIt != null || ctx.vIts != null) {
|
||||
UriResourceItImpl pathInfoIT = new UriResourceItImpl();
|
||||
pathInfoIT.setType(context.contextTypes.peek());
|
||||
pathInfoIT.setCollection(context.isCollection);
|
||||
uriInfoImplpath.addResourcePart(pathInfoIT);
|
||||
uriInfoImplpath.addResourcePart(new UriResourceItImpl(context.contextTypes.peek(), context.isCollection));
|
||||
}
|
||||
|
||||
if (ctx.vPs != null) {
|
||||
|
@ -1915,9 +1895,9 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|
||||
UriResourcePartTyped lastType = (UriResourcePartTyped) lastResource;
|
||||
|
||||
UriResourceRootImpl pathInfoRoot = new UriResourceRootImpl();
|
||||
pathInfoRoot.setCollection(lastType.isCollection());
|
||||
pathInfoRoot.setType(Parser.getTypeInformation(lastType));
|
||||
UriResourceRootImpl pathInfoRoot = new UriResourceRootImpl(
|
||||
ParserHelper.getTypeInformation(lastType),
|
||||
lastType.isCollection());
|
||||
|
||||
UriInfoImpl uriInfoImplpath = new UriInfoImpl().setKind(UriInfoKind.resource);
|
||||
uriInfoImplpath.addResourcePart(pathInfoRoot);
|
||||
|
@ -2010,7 +1990,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
UriInfoImpl uriInfo = (UriInfoImpl) context.contextSelectItem.getResourcePath();
|
||||
UriResource last = uriInfo.getLastResourcePart();
|
||||
|
||||
prevType = Parser.getTypeInformation((UriResourcePartTyped) last);
|
||||
prevType = ParserHelper.getTypeInformation((UriResourcePartTyped) last);
|
||||
if (prevType == null) {
|
||||
throw wrap(new UriParserSemanticException("prev segment not typed",
|
||||
UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "select"));
|
||||
|
@ -2038,8 +2018,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
|| property.getType().getKind() == EdmTypeKind.ENUM
|
||||
|| property.getType().getKind() == EdmTypeKind.DEFINITION) {
|
||||
|
||||
UriResourcePrimitivePropertyImpl simple = new UriResourcePrimitivePropertyImpl();
|
||||
simple.setProperty(property);
|
||||
UriResourcePrimitivePropertyImpl simple = new UriResourcePrimitivePropertyImpl(property);
|
||||
|
||||
UriInfoImpl uriInfo = (UriInfoImpl) context.contextSelectItem.getResourcePath();
|
||||
if (uriInfo == null) {
|
||||
|
@ -2059,8 +2038,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
} else {
|
||||
UriInfoImpl uriInfo = (UriInfoImpl) context.contextSelectItem.getResourcePath();
|
||||
|
||||
UriResourceComplexPropertyImpl complex = new UriResourceComplexPropertyImpl();
|
||||
complex.setProperty(property);
|
||||
UriResourceComplexPropertyImpl complex = new UriResourceComplexPropertyImpl(property);
|
||||
|
||||
if (uriInfo == null) {
|
||||
uriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
|
||||
|
@ -2096,7 +2074,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
EdmComplexType ct = edm.getComplexType(fullName);
|
||||
if (ct != null) {
|
||||
if ((ct.compatibleTo(prevType))) {
|
||||
UriResourceStartingTypeFilterImpl resourcePart = new UriResourceStartingTypeFilterImpl();
|
||||
UriResourceStartingTypeFilterImpl resourcePart = new UriResourceStartingTypeFilterImpl(null, false);
|
||||
resourcePart.setCollectionTypeFilter(ct);
|
||||
|
||||
UriInfoImpl uriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
|
||||
|
@ -2115,7 +2093,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
EdmEntityType et = edm.getEntityType(fullName);
|
||||
if (et != null) {
|
||||
if ((et.compatibleTo(prevType))) {
|
||||
UriResourceStartingTypeFilterImpl resourcePart = new UriResourceStartingTypeFilterImpl();
|
||||
UriResourceStartingTypeFilterImpl resourcePart = new UriResourceStartingTypeFilterImpl(null, false);
|
||||
resourcePart.setCollectionTypeFilter(et);
|
||||
|
||||
UriInfoImpl uriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
|
||||
|
@ -2142,13 +2120,13 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
throw wrap(new UriParserSemanticException("prev segment typed",
|
||||
UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "select"));
|
||||
}
|
||||
EdmType prevType = Parser.getTypeInformation((UriResourcePartTyped) last);
|
||||
EdmType prevType = ParserHelper.getTypeInformation((UriResourcePartTyped) last);
|
||||
|
||||
if (prevType instanceof EdmComplexType) {
|
||||
EdmComplexType ct = edm.getComplexType(fullName);
|
||||
if (ct != null) {
|
||||
if ((ct.compatibleTo(prevType))) {
|
||||
UriResourceStartingTypeFilterImpl resourcePart = new UriResourceStartingTypeFilterImpl();
|
||||
UriResourceStartingTypeFilterImpl resourcePart = new UriResourceStartingTypeFilterImpl(null, false);
|
||||
resourcePart.setCollectionTypeFilter(ct);
|
||||
|
||||
uriInfo.addResourcePart(resourcePart);
|
||||
|
@ -2186,7 +2164,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
throw wrap(new UriParserSemanticException("prev segment typed",
|
||||
UriParserSemanticException.MessageKeys.PREVIOUS_PART_TYPED));
|
||||
}
|
||||
prevType = Parser.getTypeInformation((UriResourcePartTyped) last);
|
||||
prevType = ParserHelper.getTypeInformation((UriResourcePartTyped) last);
|
||||
}
|
||||
|
||||
final FullQualifiedName finalTypeName = prevType.getFullQualifiedName();
|
||||
|
@ -2195,8 +2173,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
EdmAction action = edm.getBoundAction(fullName, finalTypeName, null);
|
||||
|
||||
if (action != null) {
|
||||
UriResourceActionImpl uriAction = new UriResourceActionImpl();
|
||||
uriAction.setAction(action);
|
||||
UriResourceActionImpl uriAction = new UriResourceActionImpl(action);
|
||||
|
||||
UriInfoImpl resourcePath = (UriInfoImpl) context.contextSelectItem.getResourcePath();
|
||||
resourcePath.addResourcePart(uriAction);
|
||||
|
@ -2206,8 +2183,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
|
|||
EdmFunction function = edm.getBoundFunction(fullName, finalTypeName, null, null);
|
||||
|
||||
if (function != null) {
|
||||
UriResourceFunctionImpl uriFunction = new UriResourceFunctionImpl();
|
||||
uriFunction.setFunction(function);
|
||||
UriResourceFunctionImpl uriFunction = new UriResourceFunctionImpl(null, function, null);
|
||||
|
||||
UriInfoImpl resourcePath = (UriInfoImpl) context.contextSelectItem.getResourcePath();
|
||||
resourcePath.addResourcePart(uriFunction);
|
||||
|
|
|
@ -40,10 +40,14 @@ public class UriTokenizer {
|
|||
ROOT,
|
||||
IT,
|
||||
|
||||
ANY,
|
||||
ALL,
|
||||
|
||||
OPEN,
|
||||
CLOSE,
|
||||
COMMA,
|
||||
SEMI,
|
||||
COLON,
|
||||
DOT,
|
||||
SLASH,
|
||||
EQ,
|
||||
|
@ -119,7 +123,10 @@ public class UriTokenizer {
|
|||
TotalsecondsMethod,
|
||||
ToupperMethod,
|
||||
TrimMethod,
|
||||
YearMethod
|
||||
YearMethod,
|
||||
|
||||
AscSuffix,
|
||||
DescSuffix
|
||||
}
|
||||
|
||||
private final String parseString;
|
||||
|
@ -174,6 +181,13 @@ public class UriTokenizer {
|
|||
found = nextConstant("$it");
|
||||
break;
|
||||
|
||||
case ANY:
|
||||
found = nextConstant("any");
|
||||
break;
|
||||
case ALL:
|
||||
found = nextConstant("all");
|
||||
break;
|
||||
|
||||
case OPEN:
|
||||
found = nextCharacter('(');
|
||||
break;
|
||||
|
@ -186,6 +200,9 @@ public class UriTokenizer {
|
|||
case SEMI:
|
||||
found = nextCharacter(';');
|
||||
break;
|
||||
case COLON:
|
||||
found = nextCharacter(':');
|
||||
break;
|
||||
case DOT:
|
||||
found = nextCharacter('.');
|
||||
break;
|
||||
|
@ -409,6 +426,14 @@ public class UriTokenizer {
|
|||
case YearMethod:
|
||||
found = nextMethod("year");
|
||||
break;
|
||||
|
||||
// Suffixes
|
||||
case AscSuffix:
|
||||
found = nextSuffix("asc");
|
||||
break;
|
||||
case DescSuffix:
|
||||
found = nextSuffix("desc");
|
||||
break;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
|
@ -542,6 +567,15 @@ public class UriTokenizer {
|
|||
return nextConstant(methodName) && nextCharacter('(');
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves past (required) whitespace and the given suffix name if found;
|
||||
* otherwise leaves the index unchanged.
|
||||
* @return whether the suffix has been found at the current index
|
||||
*/
|
||||
private boolean nextSuffix(final String suffixName) {
|
||||
return nextWhitespace() && nextConstant(suffixName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves past an OData identifier if found; otherwise leaves the index unchanged.
|
||||
* @return whether an OData identifier has been found at the current index
|
||||
|
|
|
@ -94,4 +94,9 @@ public class MemberImpl implements Member {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return path.getUriResourceParts().toString() + (startTypeFilter == null ? "" : startTypeFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
@ -33,9 +34,6 @@ import org.apache.olingo.server.api.uri.UriResourceAction;
|
|||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.QueryOption;
|
||||
import org.apache.olingo.server.core.uri.UriInfoImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceActionImpl;
|
||||
import org.apache.olingo.server.core.uri.UriResourceEntitySetImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
|
||||
import org.apache.olingo.server.core.uri.queryoption.CustomQueryOptionImpl;
|
||||
|
@ -86,9 +84,9 @@ public class UriInfoImplTest {
|
|||
public void resourceParts() {
|
||||
UriInfoImpl uriInfo = new UriInfoImpl();
|
||||
|
||||
final UriResourceAction action = new UriResourceActionImpl();
|
||||
final UriResourceEntitySet entitySet0 = new UriResourceEntitySetImpl();
|
||||
final UriResourceEntitySet entitySet1 = new UriResourceEntitySetImpl();
|
||||
final UriResourceAction action = new UriResourceActionImpl((EdmAction) null);
|
||||
final UriResourceEntitySet entitySet0 = new UriResourceEntitySetImpl(null);
|
||||
final UriResourceEntitySet entitySet1 = new UriResourceEntitySetImpl(null);
|
||||
|
||||
uriInfo.addResourcePart(action);
|
||||
uriInfo.addResourcePart(entitySet0);
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Locale;
|
|||
import org.apache.olingo.server.api.OData;
|
||||
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.validator.UriValidationException;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExpressionParserTest {
|
||||
|
@ -127,7 +128,7 @@ public class ExpressionParserTest {
|
|||
@Test
|
||||
public void unary() throws Exception {
|
||||
Expression expression = parseExpression("-5");
|
||||
assertEquals("{MINUS 5}", expression.toString());
|
||||
assertEquals("-5", expression.toString());
|
||||
|
||||
assertEquals("{MINUS -1}", parseExpression("--1").toString());
|
||||
assertEquals("{MINUS duration'PT1M'}", parseExpression("-duration'PT1M'").toString());
|
||||
|
@ -135,13 +136,13 @@ public class ExpressionParserTest {
|
|||
expression = parseExpression("not false");
|
||||
assertEquals("{NOT false}", expression.toString());
|
||||
|
||||
wrongExpression("-11:12:13");
|
||||
wrongExpression("not 11:12:13");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void grouping() throws Exception {
|
||||
Expression expression = parseExpression("-5 add 5");
|
||||
assertEquals("{{MINUS 5} ADD 5}", expression.toString());
|
||||
assertEquals("{-5 ADD 5}", expression.toString());
|
||||
|
||||
expression = parseExpression("-(5 add 5)");
|
||||
assertEquals("{MINUS {5 ADD 5}}", expression.toString());
|
||||
|
@ -149,7 +150,7 @@ public class ExpressionParserTest {
|
|||
|
||||
@Test
|
||||
public void precedence() throws Exception {
|
||||
assertEquals("{{MINUS 1} ADD {2 DIV 3}}", parseExpression("-1 add 2 div 3").toString());
|
||||
assertEquals("{-1 ADD {2 DIV 3}}", parseExpression("-1 add 2 div 3").toString());
|
||||
assertEquals("{true OR {{NOT false} AND true}}", parseExpression("true or not false and true").toString());
|
||||
}
|
||||
|
||||
|
@ -264,7 +265,8 @@ public class ExpressionParserTest {
|
|||
wrongExpression("substring(1,2)");
|
||||
}
|
||||
|
||||
private Expression parseMethod(TokenKind kind, String... parameters) throws UriParserException {
|
||||
private Expression parseMethod(TokenKind kind, String... parameters)
|
||||
throws UriParserException, UriValidationException {
|
||||
String expressionString = kind.name().substring(0, kind.name().indexOf("Method"))
|
||||
.toLowerCase(Locale.ROOT).replace("geo", "geo.") + '(';
|
||||
boolean first = true;
|
||||
|
@ -283,9 +285,10 @@ public class ExpressionParserTest {
|
|||
return expression;
|
||||
}
|
||||
|
||||
private Expression parseExpression(final String expressionString) throws UriParserException {
|
||||
private Expression parseExpression(final String expressionString)
|
||||
throws UriParserException, UriValidationException {
|
||||
UriTokenizer tokenizer = new UriTokenizer(expressionString);
|
||||
Expression expression = new ExpressionParser(null, odata).parse(tokenizer);
|
||||
Expression expression = new ExpressionParser(null, odata).parse(tokenizer, null, null);
|
||||
assertNotNull(expression);
|
||||
assertTrue(tokenizer.next(TokenKind.EOF));
|
||||
return expression;
|
||||
|
@ -293,10 +296,12 @@ public class ExpressionParserTest {
|
|||
|
||||
private void wrongExpression(final String expressionString) {
|
||||
try {
|
||||
new ExpressionParser(null, odata).parse(new UriTokenizer(expressionString));
|
||||
new ExpressionParser(null, odata).parse(new UriTokenizer(expressionString), null, null);
|
||||
fail("Expected exception not thrown.");
|
||||
} catch (final UriParserException e) {
|
||||
assertNotNull(e);
|
||||
} catch (final UriValidationException e) {
|
||||
assertNotNull(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public class UriTokenizerTest {
|
|||
|
||||
@Test
|
||||
public void sequence() {
|
||||
final UriTokenizer tokenizer = new UriTokenizer("(A=1,B=2);.*/+-");
|
||||
UriTokenizer tokenizer = new UriTokenizer("(A=1,B=2);.*/+-");
|
||||
assertTrue(tokenizer.next(TokenKind.OPEN));
|
||||
assertFalse(tokenizer.next(TokenKind.OPEN));
|
||||
assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
|
||||
|
@ -78,6 +78,22 @@ public class UriTokenizerTest {
|
|||
assertTrue(tokenizer.next(TokenKind.PLUS));
|
||||
assertTrue(tokenizer.next(TokenKind.MINUS));
|
||||
assertTrue(tokenizer.next(TokenKind.EOF));
|
||||
|
||||
tokenizer = new UriTokenizer("any(a:true) or all(b:false)");
|
||||
assertTrue(tokenizer.next(TokenKind.ANY));
|
||||
assertTrue(tokenizer.next(TokenKind.OPEN));
|
||||
assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
|
||||
assertTrue(tokenizer.next(TokenKind.COLON));
|
||||
assertTrue(tokenizer.next(TokenKind.BooleanValue));
|
||||
assertTrue(tokenizer.next(TokenKind.CLOSE));
|
||||
assertTrue(tokenizer.next(TokenKind.OrOperator));
|
||||
assertTrue(tokenizer.next(TokenKind.ALL));
|
||||
assertTrue(tokenizer.next(TokenKind.OPEN));
|
||||
assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
|
||||
assertTrue(tokenizer.next(TokenKind.COLON));
|
||||
assertTrue(tokenizer.next(TokenKind.BooleanValue));
|
||||
assertTrue(tokenizer.next(TokenKind.CLOSE));
|
||||
assertTrue(tokenizer.next(TokenKind.EOF));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -455,6 +471,19 @@ public class UriTokenizerTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suffixes() {
|
||||
UriTokenizer tokenizer = new UriTokenizer("p1 asc,p2 desc");
|
||||
assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
|
||||
assertTrue(tokenizer.next(TokenKind.AscSuffix));
|
||||
assertTrue(tokenizer.next(TokenKind.COMMA));
|
||||
assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
|
||||
assertTrue(tokenizer.next(TokenKind.DescSuffix));
|
||||
assertTrue(tokenizer.next(TokenKind.EOF));
|
||||
|
||||
wrongToken(TokenKind.DescSuffix, " desc", 'D');
|
||||
}
|
||||
|
||||
private void wrongToken(final TokenKind kind, final String value, final char disturbCharacter) {
|
||||
assertFalse(new UriTokenizer(disturbCharacter + value).next(kind));
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public class UriResourceImplTest {
|
|||
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
|
||||
|
||||
@Test
|
||||
public void testUriParameterImpl() {
|
||||
public void uriParameterImpl() {
|
||||
UriParameterImpl impl = new UriParameterImpl();
|
||||
Expression expression = new LiteralImpl("Expression", null);
|
||||
|
||||
|
@ -73,21 +73,20 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceActionImpl() {
|
||||
UriResourceActionImpl impl = new UriResourceActionImpl();
|
||||
public void uriResourceActionImpl() {
|
||||
UriResourceActionImpl impl = new UriResourceActionImpl((EdmAction) null);
|
||||
assertEquals(UriResourceKind.action, impl.getKind());
|
||||
assertEquals("", impl.toString());
|
||||
|
||||
// action
|
||||
EdmAction action = edm.getUnboundAction(ActionProvider.nameUARTETTwoKeyTwoPrimParam);
|
||||
impl.setAction(action);
|
||||
impl = new UriResourceActionImpl(action);
|
||||
assertEquals(action, impl.getAction());
|
||||
assertEquals(ActionProvider.nameUARTETTwoKeyTwoPrimParam.getName(), impl.toString());
|
||||
|
||||
// action import
|
||||
impl = new UriResourceActionImpl();
|
||||
EdmActionImport actionImport = edm.getEntityContainer().getActionImport("AIRTCTTwoPrimParam");
|
||||
impl.setActionImport(actionImport);
|
||||
impl = new UriResourceActionImpl(actionImport);
|
||||
assertEquals(actionImport, impl.getActionImport());
|
||||
assertEquals(actionImport.getUnboundAction(), impl.getAction());
|
||||
assertFalse(impl.isCollection());
|
||||
|
@ -95,20 +94,16 @@ public class UriResourceImplTest {
|
|||
assertEquals(actionImport.getUnboundAction().getReturnType().getType(), impl.getType());
|
||||
|
||||
actionImport = edm.getEntityContainer().getActionImport("AIRT");
|
||||
impl.setActionImport(actionImport);
|
||||
impl = new UriResourceActionImpl(actionImport);
|
||||
assertFalse(impl.isCollection());
|
||||
assertNull(impl.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceLambdaAllImpl() {
|
||||
UriResourceLambdaAllImpl impl = new UriResourceLambdaAllImpl();
|
||||
assertEquals(UriResourceKind.lambdaAll, impl.getKind());
|
||||
|
||||
public void uriResourceLambdaAllImpl() {
|
||||
Expression expression = new LiteralImpl("Expression", null);
|
||||
impl.setExpression(expression);
|
||||
impl.setLamdaVariable("A");
|
||||
|
||||
UriResourceLambdaAllImpl impl = new UriResourceLambdaAllImpl("A", expression);
|
||||
assertEquals(UriResourceKind.lambdaAll, impl.getKind());
|
||||
assertFalse(impl.isCollection());
|
||||
assertEquals(expression, impl.getExpression());
|
||||
assertEquals("A", impl.getLambdaVariable());
|
||||
|
@ -117,14 +112,10 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceLambdaAnyImpl() {
|
||||
UriResourceLambdaAnyImpl impl = new UriResourceLambdaAnyImpl();
|
||||
assertEquals(UriResourceKind.lambdaAny, impl.getKind());
|
||||
|
||||
public void uriResourceLambdaAnyImpl() {
|
||||
Expression expression = new LiteralImpl("Expression", null);
|
||||
impl.setExpression(expression);
|
||||
impl.setLamdaVariable("A");
|
||||
|
||||
UriResourceLambdaAnyImpl impl = new UriResourceLambdaAnyImpl("A", expression);
|
||||
assertEquals(UriResourceKind.lambdaAny, impl.getKind());
|
||||
assertFalse(impl.isCollection());
|
||||
assertEquals(expression, impl.getExpression());
|
||||
assertEquals("A", impl.getLambdaVariable());
|
||||
|
@ -133,14 +124,11 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceComplexPropertyImpl() {
|
||||
UriResourceComplexPropertyImpl impl = new UriResourceComplexPropertyImpl();
|
||||
assertEquals(UriResourceKind.complexProperty, impl.getKind());
|
||||
|
||||
public void uriResourceComplexPropertyImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETKeyNav);
|
||||
EdmProperty property = (EdmProperty) entityType.getProperty("PropertyCompNav");
|
||||
impl.setProperty(property);
|
||||
|
||||
UriResourceComplexPropertyImpl impl = new UriResourceComplexPropertyImpl(property);
|
||||
assertEquals(UriResourceKind.complexProperty, impl.getKind());
|
||||
assertEquals(property, impl.getProperty());
|
||||
assertEquals(property.getName(), impl.toString());
|
||||
assertFalse(impl.isCollection());
|
||||
|
@ -158,14 +146,11 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourcePrimitivePropertyImpl() {
|
||||
UriResourcePrimitivePropertyImpl impl = new UriResourcePrimitivePropertyImpl();
|
||||
assertEquals(UriResourceKind.primitiveProperty, impl.getKind());
|
||||
|
||||
public void uriResourcePrimitivePropertyImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETKeyNav);
|
||||
EdmProperty property = (EdmProperty) entityType.getProperty("PropertyInt16");
|
||||
impl.setProperty(property);
|
||||
|
||||
UriResourcePrimitivePropertyImpl impl = new UriResourcePrimitivePropertyImpl(property);
|
||||
assertEquals(UriResourceKind.primitiveProperty, impl.getKind());
|
||||
assertEquals(property, impl.getProperty());
|
||||
assertEquals(property.getName(), impl.toString());
|
||||
assertFalse(impl.isCollection());
|
||||
|
@ -173,20 +158,17 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceCountImpl() {
|
||||
public void uriResourceCountImpl() {
|
||||
UriResourceCountImpl impl = new UriResourceCountImpl();
|
||||
assertEquals(UriResourceKind.count, impl.getKind());
|
||||
assertEquals("$count", impl.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceEntitySetImpl() {
|
||||
UriResourceEntitySetImpl impl = new UriResourceEntitySetImpl();
|
||||
assertEquals(UriResourceKind.entitySet, impl.getKind());
|
||||
|
||||
public void uriResourceEntitySetImpl() {
|
||||
EdmEntitySet entitySet = edm.getEntityContainer().getEntitySet("ESAllPrim");
|
||||
impl.setEntitSet(entitySet);
|
||||
|
||||
UriResourceEntitySetImpl impl = new UriResourceEntitySetImpl(entitySet);
|
||||
assertEquals(UriResourceKind.entitySet, impl.getKind());
|
||||
assertEquals("ESAllPrim", impl.toString());
|
||||
assertEquals(entitySet, impl.getEntitySet());
|
||||
|
||||
|
@ -201,8 +183,8 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceFunctionImpl() {
|
||||
UriResourceFunctionImpl impl = new UriResourceFunctionImpl();
|
||||
public void uriResourceFunctionImpl() {
|
||||
UriResourceFunctionImpl impl = new UriResourceFunctionImpl(null, null, null);
|
||||
assertEquals(UriResourceKind.function, impl.getKind());
|
||||
assertEquals("", impl.toString());
|
||||
|
||||
|
@ -210,39 +192,38 @@ public class UriResourceImplTest {
|
|||
EdmFunction function = edm.getEntityContainer().getFunctionImport("FINRTInt16")
|
||||
.getUnboundFunction(Collections.<String> emptyList());
|
||||
assertNotNull(function);
|
||||
impl.setFunction(function);
|
||||
impl = new UriResourceFunctionImpl(null, function, null);
|
||||
|
||||
assertEquals(function, impl.getFunction());
|
||||
assertEquals("UFNRTInt16", impl.toString());
|
||||
assertEquals(function.getReturnType().getType(), impl.getType());
|
||||
assertFalse(impl.isParameterListFilled());
|
||||
assertTrue(impl.getParameters().isEmpty());
|
||||
|
||||
// function import
|
||||
impl = new UriResourceFunctionImpl();
|
||||
EdmFunctionImport functionImport = edm.getEntityContainer().getFunctionImport("FINRTInt16");
|
||||
impl.setFunctionImport(functionImport, Collections.<UriParameter> emptyList());
|
||||
impl = new UriResourceFunctionImpl(functionImport, functionImport.getUnboundFunctions().get(0),
|
||||
Collections.<UriParameter> emptyList());
|
||||
assertEquals(functionImport, impl.getFunctionImport());
|
||||
assertEquals("FINRTInt16", impl.toString());
|
||||
|
||||
// function collection
|
||||
impl = new UriResourceFunctionImpl();
|
||||
functionImport = edm.getEntityContainer().getFunctionImport("FICRTCollESTwoKeyNavParam");
|
||||
assertNotNull(function);
|
||||
UriParameter parameter = new UriParameterImpl().setName("ParameterInt16");
|
||||
impl.setFunctionImport(functionImport, Collections.singletonList(parameter));
|
||||
impl = new UriResourceFunctionImpl(functionImport,
|
||||
functionImport.getUnboundFunction(Collections.singletonList("ParameterInt16")),
|
||||
Collections.singletonList(parameter));
|
||||
assertEquals("FICRTCollESTwoKeyNavParam", impl.toString());
|
||||
|
||||
impl.setFunction(functionImport.getUnboundFunction(Collections.singletonList("ParameterInt16")));
|
||||
assertTrue(impl.isCollection());
|
||||
impl.setKeyPredicates(Collections.<UriParameter> emptyList());
|
||||
assertFalse(impl.isCollection());
|
||||
|
||||
assertFalse(impl.getParameters().isEmpty());
|
||||
assertEquals(parameter, impl.getParameters().get(0));
|
||||
assertTrue(impl.isParameterListFilled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceImplKeyPred() {
|
||||
public void uriResourceImplKeyPred() {
|
||||
final EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
class Mock extends UriResourceWithKeysImpl {
|
||||
|
||||
|
@ -306,7 +287,7 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceImplTyped() {
|
||||
public void uriResourceImplTyped() {
|
||||
final EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
class Mock extends UriResourceTypedImpl {
|
||||
|
||||
|
@ -344,18 +325,15 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceItImpl() {
|
||||
UriResourceItImpl impl = new UriResourceItImpl();
|
||||
assertEquals(UriResourceKind.it, impl.getKind());
|
||||
|
||||
public void uriResourceItImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
UriResourceItImpl impl = new UriResourceItImpl(entityType, false);
|
||||
assertEquals(UriResourceKind.it, impl.getKind());
|
||||
assertEquals("$it", impl.toString());
|
||||
|
||||
impl.setType(entityType);
|
||||
assertEquals(entityType, impl.getType());
|
||||
|
||||
assertFalse(impl.isCollection());
|
||||
impl.setCollection(true);
|
||||
|
||||
impl = new UriResourceItImpl(entityType, true);
|
||||
assertTrue(impl.isCollection());
|
||||
impl.setKeyPredicates(Collections.singletonList(
|
||||
(UriParameter) new UriParameterImpl().setName("ParameterInt16")));
|
||||
|
@ -363,15 +341,13 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceNavigationPropertyImpl() {
|
||||
UriResourceNavigationPropertyImpl impl = new UriResourceNavigationPropertyImpl();
|
||||
assertEquals(UriResourceKind.navigationProperty, impl.getKind());
|
||||
|
||||
public void uriResourceNavigationPropertyImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
EdmNavigationProperty property = (EdmNavigationProperty) entityType.getProperty("NavPropertyETKeyNavMany");
|
||||
assertNotNull(property);
|
||||
|
||||
impl.setNavigationProperty(property);
|
||||
UriResourceNavigationPropertyImpl impl = new UriResourceNavigationPropertyImpl(property);
|
||||
assertEquals(UriResourceKind.navigationProperty, impl.getKind());
|
||||
assertEquals(property, impl.getProperty());
|
||||
|
||||
assertEquals("NavPropertyETKeyNavMany", impl.toString());
|
||||
|
@ -384,25 +360,22 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceRefImpl() {
|
||||
public void uriResourceRefImpl() {
|
||||
UriResourceRefImpl impl = new UriResourceRefImpl();
|
||||
assertEquals(UriResourceKind.ref, impl.getKind());
|
||||
assertEquals("$ref", impl.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceRootImpl() {
|
||||
UriResourceRootImpl impl = new UriResourceRootImpl();
|
||||
assertEquals(UriResourceKind.root, impl.getKind());
|
||||
|
||||
public void uriResourceRootImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
UriResourceRootImpl impl = new UriResourceRootImpl(entityType, false);
|
||||
assertEquals(UriResourceKind.root, impl.getKind());
|
||||
assertEquals("$root", impl.toString());
|
||||
|
||||
impl.setType(entityType);
|
||||
assertEquals(entityType, impl.getType());
|
||||
|
||||
assertFalse(impl.isCollection());
|
||||
impl.setCollection(true);
|
||||
|
||||
impl = new UriResourceRootImpl(entityType, true);
|
||||
assertTrue(impl.isCollection());
|
||||
impl.setKeyPredicates(Collections.singletonList(
|
||||
(UriParameter) new UriParameterImpl().setName("ParameterInt16")));
|
||||
|
@ -410,14 +383,11 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceSingletonImpl() {
|
||||
UriResourceSingletonImpl impl = new UriResourceSingletonImpl();
|
||||
assertEquals(UriResourceKind.singleton, impl.getKind());
|
||||
|
||||
public void uriResourceSingletonImpl() {
|
||||
EdmSingleton singleton = edm.getEntityContainer().getSingleton("SINav");
|
||||
EdmEntityType entityTypeBaseColl = edm.getEntityType(EntityTypeProvider.nameETBaseTwoKeyNav);
|
||||
impl.setSingleton(singleton);
|
||||
|
||||
UriResourceSingletonImpl impl = new UriResourceSingletonImpl(singleton);
|
||||
assertEquals(UriResourceKind.singleton, impl.getKind());
|
||||
assertEquals("SINav", impl.toString());
|
||||
assertEquals(singleton, impl.getSingleton());
|
||||
|
||||
|
@ -433,41 +403,33 @@ public class UriResourceImplTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceValueImpl() {
|
||||
public void uriResourceValueImpl() {
|
||||
UriResourceValueImpl impl = new UriResourceValueImpl();
|
||||
assertEquals(UriResourceKind.value, impl.getKind());
|
||||
assertEquals("$value", impl.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceLambdaVarImpl() {
|
||||
UriResourceLambdaVarImpl impl = new UriResourceLambdaVarImpl();
|
||||
assertEquals(UriResourceKind.lambdaVariable, impl.getKind());
|
||||
|
||||
public void uriResourceLambdaVarImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
impl.setType(entityType);
|
||||
impl.setVariableText("A");
|
||||
|
||||
UriResourceLambdaVarImpl impl = new UriResourceLambdaVarImpl("A", entityType);
|
||||
assertEquals(UriResourceKind.lambdaVariable, impl.getKind());
|
||||
assertEquals("A", impl.toString());
|
||||
assertEquals(entityType, impl.getType());
|
||||
assertEquals("A", impl.getVariableName());
|
||||
assertFalse(impl.isCollection());
|
||||
impl.setCollection(true);
|
||||
assertTrue(impl.isCollection());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriResourceStartingTypeFilterImpl() {
|
||||
UriResourceStartingTypeFilterImpl impl = new UriResourceStartingTypeFilterImpl();
|
||||
|
||||
public void uriResourceStartingTypeFilterImpl() {
|
||||
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
|
||||
impl.setType(entityType);
|
||||
UriResourceStartingTypeFilterImpl impl = new UriResourceStartingTypeFilterImpl(entityType, false);
|
||||
assertEquals("olingo.odata.test1.ETTwoKeyNav", impl.toString());
|
||||
assertEquals(entityType, impl.getType());
|
||||
|
||||
assertFalse(impl.isCollection());
|
||||
impl.setCollection(true);
|
||||
|
||||
impl = new UriResourceStartingTypeFilterImpl(entityType, true);
|
||||
assertTrue(impl.isCollection());
|
||||
impl.setKeyPredicates(Collections.singletonList(
|
||||
(UriParameter) new UriParameterImpl().setName("ParameterInt16")));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,6 +38,7 @@ import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
|
|||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
|
||||
import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestUriParserImpl {
|
||||
|
@ -561,11 +562,12 @@ public class TestUriParserImpl {
|
|||
@Test
|
||||
public void unary() throws Exception {
|
||||
testFilter.runOnETAllPrim("not PropertyBoolean").isCompr("<not <PropertyBoolean>>");
|
||||
testFilter.runOnETAllPrim("- PropertyInt16 eq PropertyInt16").isCompr("<<- <PropertyInt16>> eq <PropertyInt16>>");
|
||||
testFilter.runOnETAllPrim("-PropertyInt16 eq PropertyInt16").isCompr("<<- <PropertyInt16>> eq <PropertyInt16>>");
|
||||
}
|
||||
|
||||
// TODO: Use correct types.
|
||||
@Test
|
||||
@Ignore
|
||||
public void filterComplexMixedPriority() throws Exception {
|
||||
testFilter.runOnETAllPrim("PropertyInt16 or PropertyInt32 and PropertyInt64")
|
||||
.isCompr("<<PropertyInt16> or <<PropertyInt32> and <PropertyInt64>>>");
|
||||
|
@ -1069,28 +1071,21 @@ public class TestUriParserImpl {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testLambda() throws Exception {
|
||||
testUri.run("ESTwoKeyNav", "$filter=CollPropertyComp/all( l : true )")
|
||||
.goFilter().is("<CollPropertyComp/<ALL;<true>>>");
|
||||
public void lambda() throws Exception {
|
||||
testFilter.runOnETTwoKeyNav("CollPropertyComp/all(l:true)")
|
||||
.is("<CollPropertyComp/<ALL;<true>>>");
|
||||
|
||||
testUri.run("ESTwoKeyNav", "$filter=CollPropertyComp/all( x : x/PropertyInt16 eq 2)")
|
||||
.goFilter().is("<CollPropertyComp/<ALL;<<x/PropertyInt16> eq <2>>>>");
|
||||
testFilter.runOnETTwoKeyNav("CollPropertyComp/all(x:x/PropertyInt16 eq 2)")
|
||||
.is("<CollPropertyComp/<ALL;<<x/PropertyInt16> eq <2>>>>");
|
||||
|
||||
testUri.run("ESTwoKeyNav", "$filter=CollPropertyComp/any( l : true )")
|
||||
.goFilter().is("<CollPropertyComp/<ANY;<true>>>");
|
||||
testUri.run("ESTwoKeyNav", "$filter=CollPropertyComp/any( )")
|
||||
.goFilter().is("<CollPropertyComp/<ANY;>>");
|
||||
|
||||
testUri.run("ESTwoKeyNav", "$filter=all( l : true )")
|
||||
.goFilter().is("<<ALL;<true>>>");
|
||||
testUri.run("ESTwoKeyNav", "$filter=any( l : true )")
|
||||
.goFilter().is("<<ANY;<true>>>");
|
||||
testUri.run("ESTwoKeyNav", "$filter=any( )")
|
||||
.goFilter().is("<<ANY;>>");
|
||||
testFilter.runOnETTwoKeyNav("CollPropertyComp/any(l:true)")
|
||||
.is("<CollPropertyComp/<ANY;<true>>>");
|
||||
testFilter.runOnETTwoKeyNav("CollPropertyComp/any()")
|
||||
.is("<CollPropertyComp/<ANY;>>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomQueryOption() throws Exception {
|
||||
public void customQueryOption() throws Exception {
|
||||
testUri.run("ESTwoKeyNav", "custom")
|
||||
.isCustomParameter(0, "custom", "");
|
||||
testUri.run("ESTwoKeyNav", "custom=ABC")
|
||||
|
@ -1098,6 +1093,7 @@ public class TestUriParserImpl {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Geo types are not supported yet.")
|
||||
public void geo() throws Exception {
|
||||
testFilter.runOnETAllPrim("geo.distance(PropertySByte,PropertySByte)")
|
||||
.is("<geo.distance(<PropertySByte>,<PropertySByte>)>")
|
||||
|
|
|
@ -128,7 +128,7 @@ public class ExpressionTest {
|
|||
// UriResourceImpl
|
||||
EdmAction action = edm.getUnboundAction(ActionProvider.nameUARTString);
|
||||
UriInfoResource uriInfo = new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourceActionImpl().setAction(action)).asUriInfoResource();
|
||||
new UriResourceActionImpl(action)).asUriInfoResource();
|
||||
MemberImpl expression = new MemberImpl(uriInfo, null);
|
||||
assertEquals(action.getReturnType().getType(), expression.getType());
|
||||
|
||||
|
@ -142,7 +142,7 @@ public class ExpressionTest {
|
|||
// UriResourceImplTyped check collection = true case
|
||||
action = edm.getUnboundAction(ActionProvider.nameUARTCollStringTwoParam);
|
||||
expression = new MemberImpl(new UriInfoImpl().setKind(UriInfoKind.resource)
|
||||
.addResourcePart(new UriResourceActionImpl().setAction(action))
|
||||
.addResourcePart(new UriResourceActionImpl(action))
|
||||
.asUriInfoResource(),
|
||||
null);
|
||||
assertTrue(expression.isCollection());
|
||||
|
@ -150,7 +150,7 @@ public class ExpressionTest {
|
|||
// UriResourceImplTyped with filter
|
||||
EdmFunction function = edm.getUnboundFunction(FunctionProvider.nameUFCRTETKeyNav, null);
|
||||
expression = new MemberImpl(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourceFunctionImpl().setFunction(function).setEntryTypeFilter(entityType))
|
||||
new UriResourceFunctionImpl(null, function, null).setEntryTypeFilter(entityType))
|
||||
.asUriInfoResource(),
|
||||
null);
|
||||
assertEquals(entityType, expression.getType());
|
||||
|
@ -158,7 +158,7 @@ public class ExpressionTest {
|
|||
// UriResourceImplKeyPred
|
||||
function = edm.getUnboundFunction(FunctionProvider.nameUFCRTETKeyNav, null);
|
||||
expression = new MemberImpl(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourceFunctionImpl().setFunction(function))
|
||||
new UriResourceFunctionImpl(null, function, null))
|
||||
.asUriInfoResource(),
|
||||
null);
|
||||
assertEquals(function.getReturnType().getType(), expression.getType());
|
||||
|
@ -167,7 +167,7 @@ public class ExpressionTest {
|
|||
EdmEntityType entityBaseType = edm.getEntityType(EntityTypeProvider.nameETBaseTwoKeyNav);
|
||||
function = edm.getUnboundFunction(FunctionProvider.nameUFCRTCollETTwoKeyNavParam, Arrays.asList("ParameterInt16"));
|
||||
expression = new MemberImpl(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourceFunctionImpl().setFunction(function).setEntryTypeFilter(entityBaseType))
|
||||
new UriResourceFunctionImpl(null, function, null).setEntryTypeFilter(entityBaseType))
|
||||
.asUriInfoResource(),
|
||||
null);
|
||||
assertEquals(entityBaseType, expression.getType());
|
||||
|
@ -176,7 +176,7 @@ public class ExpressionTest {
|
|||
entityBaseType = edm.getEntityType(EntityTypeProvider.nameETBaseTwoKeyNav);
|
||||
function = edm.getUnboundFunction(FunctionProvider.nameUFCRTCollETTwoKeyNavParam, Arrays.asList("ParameterInt16"));
|
||||
expression = new MemberImpl(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
|
||||
new UriResourceFunctionImpl().setFunction(function).setCollectionTypeFilter(entityBaseType))
|
||||
new UriResourceFunctionImpl(null, function, null).setCollectionTypeFilter(entityBaseType))
|
||||
.asUriInfoResource(),
|
||||
null);
|
||||
assertEquals(entityBaseType, expression.getType());
|
||||
|
|
Loading…
Reference in New Issue