From 4a8140924656e83114402ffc249ecf8dc8639caa Mon Sep 17 00:00:00 2001 From: Christian Holzer Date: Fri, 14 Aug 2015 10:48:08 +0200 Subject: [PATCH] [OLINGO-730] UriParser fix --- .../server/core/uri/parser/UriContext.java | 13 ++++++++- .../core/uri/parser/UriParseTreeVisitor.java | 18 ++++++++++-- .../core/uri/antlr/TestFullResourcePath.java | 28 ++++++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) 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 07eb1d34a..348364f40 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 @@ -63,7 +63,18 @@ public class UriContext { */ public ExpandItemImpl contextExpandItemPath; // CHECKSTYLE:ON (Maven checkstyle) - + + //CHECKSTYLE:OFF (Maven checkstyle) + /** + * Set to true in method xxx right before calling {@link org.apache.olingo.server.core.uri.parser.UriParseTreeVisitor#readResourcePathSegment} + * After reading the path the variable is set back to false + * + * readResourcePathSegment handles all navigation properties, it depends on the context if key predicates are allowed or not. + * In case of expand + */ + public boolean contextVisitExpandResourcePath; + //CHECKSTYLE:ON (Maven checkstyle) + // CHECKSTYLE:OFF (Maven checkstyle) /** * Set within method 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 c405f704e..c853c1ac5 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 @@ -45,6 +45,7 @@ import org.apache.olingo.server.api.uri.UriInfoKind; import org.apache.olingo.server.api.uri.UriInfoResource; import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceEntitySet; +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.BinaryOperatorKind; import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind; @@ -457,7 +458,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { } } else if (property instanceof EdmNavigationProperty) { // create navigation property - if(ctx.getParent() instanceof ExpandPathContext && ctx.vlNVO.size() > 0) { + if(context.contextVisitExpandResourcePath && ctx.vlNVO.size() > 0) { + //if(ctx.getParent() instanceof ExpandPathContext && ctx.vlNVO.size() > 0) { throw wrap(new UriParserSemanticException("Navigation properties in expand system query options must not" + " be followed a an key", UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED)); } @@ -701,6 +703,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (!(obj instanceof UriResourcePartTyped)) { throw wrap(new UriParserSemanticException("all only allowed on typed path segments", UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "all")); + } else if(obj instanceof UriResourceNavigation) { + if(!((UriResourceNavigation) obj).getKeyPredicates().isEmpty()) { + throw wrap(new UriParserSemanticException("Any lamdba expression must not be following navigation properties" + + "with key predicates", UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED)); + } } UriContext.LambdaVariables var = new UriContext.LambdaVariables(); @@ -926,6 +933,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (!(lastResourcePart instanceof UriResourcePartTyped)) { throw wrap(new UriParserSemanticException("any only allowed on typed path segments", UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "any")); + } else if(lastResourcePart instanceof UriResourceNavigation) { + if(!((UriResourceNavigation) lastResourcePart).getKeyPredicates().isEmpty()) { + throw wrap(new UriParserSemanticException("Any lamdba expression must not be following navigation properties" + + "with key predicates", UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED)); + } } UriContext.LambdaVariables var = new UriContext.LambdaVariables(); @@ -1221,8 +1233,10 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { context.contextExpandItemPath = expandItem; context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource); + context.contextVisitExpandResourcePath = true; super.visitExpandPath(ctx); - + context.contextVisitExpandResourcePath = false; + EdmType startType = removeUriResourceStartingTypeFilterImpl(context.contextUriInfo); expandItem.setResourcePath(context.contextUriInfo); if (startType != null) { diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java index dc31ac969..fb231f0ce 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java @@ -26,6 +26,7 @@ import org.apache.olingo.commons.api.http.HttpContentType; import org.apache.olingo.commons.core.Encoder; import org.apache.olingo.commons.core.edm.EdmProviderImpl; import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.processor.EntityProcessor; import org.apache.olingo.server.api.uri.UriInfoKind; import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind; @@ -5252,6 +5253,27 @@ public class TestFullResourcePath { + "($filter=PropertyString eq 'Test String1')"); } + @Test + public void testKeyPredicatesInExpandFilter() throws Exception { + testUri.run("ESKeyNav(0)", "$expand=NavPropertyETTwoKeyNavMany($filter=NavPropertyETTwoKeyNavMany" + + "(PropertyInt16=1,PropertyString='2')/PropertyInt16 eq 1)").goPath().goExpand() + .first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true) + .goUpExpandValidator() + .isFilterSerialized("< eq <1>>"); + } + + @Test + public void testKeyPredicatesInDoubleExpandedFilter() throws Exception { + testUri.run("ESKeyNav(0)", "$expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany" + + "($filter=NavPropertyETTwoKeyNavMany(PropertyInt16=1,PropertyString='2')/PropertyInt16 eq 1))") + .goPath().goExpand() + .first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true) + .goUpExpandValidator().goExpand() + .first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true) + .goUpExpandValidator() + .isFilterSerialized("< eq <1>>"); + } + @Test(expected=UriParserException.class) public void testFilterSystemQueryOptionAnyWithKeyAny() throws Exception { testUri.run("ESAllPrim", "$filter=NavPropertyETTwoPrimMany(1)" @@ -5272,7 +5294,11 @@ public class TestFullResourcePath { .at(2).isCount(); } - // ESKeyNav(1)/NavPropertyETTwoKeyNavMany/$count + @Test(expected=UriParserException.class) + public void testNavigationWithMoreThanOneKey() throws Exception { + testUri.run("ESKeyNav(1)/NavPropertyETTwoKeyNavMany(PropertyInt=1,PropertyString='2')" + + "(PropertyInt=1,PropertyString='2')"); + } public static String encode(final String decoded) throws UnsupportedEncodingException { return Encoder.encode(decoded);