You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/12/21 10:41:35 UTC
[3/4] olingo-odata4 git commit: [OLINGO-834] ExpressionParser parses
path expressions
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
index 2a994d3..118c649 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
@@ -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();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
index e811575..65ee461 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
@@ -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;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
index 5d2fbde..1cd4d7a 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
@@ -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);
- }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
index b257e68..00f3673 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
@@ -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)) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriContext.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriContext.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriContext.java
index c0db85b..36a0887 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriContext.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriContext.java
@@ -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>();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
index 9d29ab2..1bab218 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
@@ -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);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
index 4b43cd9..37f1b76 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
@@ -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) {
@@ -543,6 +568,15 @@ public class UriTokenizer {
}
/**
+ * 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
*/
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/MemberImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/MemberImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/MemberImpl.java
index a71e382..6ef37e4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/MemberImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/MemberImpl.java
@@ -94,4 +94,9 @@ public class MemberImpl implements Member {
}
return false;
}
+
+ @Override
+ public String toString() {
+ return path.getUriResourceParts().toString() + (startTypeFilter == null ? "" : startTypeFilter);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
index 4c76e96..68e6637 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
@@ -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);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
index 183ff22..4ab7fce 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
@@ -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);
}
}
}