[OLINGO-730] UriParser fix

This commit is contained in:
Christian Holzer 2015-08-14 10:48:08 +02:00
parent 9235cb2b05
commit 4a81409246
3 changed files with 55 additions and 4 deletions

View File

@ -63,7 +63,18 @@ public class UriContext {
*/ */
public ExpandItemImpl contextExpandItemPath; public ExpandItemImpl contextExpandItemPath;
// CHECKSTYLE:ON (Maven checkstyle) // 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) // CHECKSTYLE:OFF (Maven checkstyle)
/** /**
* Set within method * Set within method

View File

@ -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.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet; 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.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind; import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind; import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
@ -457,7 +458,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
} }
} else if (property instanceof EdmNavigationProperty) { } else if (property instanceof EdmNavigationProperty) {
// create navigation property // 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" throw wrap(new UriParserSemanticException("Navigation properties in expand system query options must not"
+ " be followed a an key", UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED)); + " be followed a an key", UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
} }
@ -701,6 +703,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
if (!(obj instanceof UriResourcePartTyped)) { if (!(obj instanceof UriResourcePartTyped)) {
throw wrap(new UriParserSemanticException("all only allowed on typed path segments", throw wrap(new UriParserSemanticException("all only allowed on typed path segments",
UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "all")); 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(); UriContext.LambdaVariables var = new UriContext.LambdaVariables();
@ -926,6 +933,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
if (!(lastResourcePart instanceof UriResourcePartTyped)) { if (!(lastResourcePart instanceof UriResourcePartTyped)) {
throw wrap(new UriParserSemanticException("any only allowed on typed path segments", throw wrap(new UriParserSemanticException("any only allowed on typed path segments",
UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "any")); 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(); UriContext.LambdaVariables var = new UriContext.LambdaVariables();
@ -1221,8 +1233,10 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
context.contextExpandItemPath = expandItem; context.contextExpandItemPath = expandItem;
context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource); context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
context.contextVisitExpandResourcePath = true;
super.visitExpandPath(ctx); super.visitExpandPath(ctx);
context.contextVisitExpandResourcePath = false;
EdmType startType = removeUriResourceStartingTypeFilterImpl(context.contextUriInfo); EdmType startType = removeUriResourceStartingTypeFilterImpl(context.contextUriInfo);
expandItem.setResourcePath(context.contextUriInfo); expandItem.setResourcePath(context.contextUriInfo);
if (startType != null) { if (startType != null) {

View File

@ -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.Encoder;
import org.apache.olingo.commons.core.edm.EdmProviderImpl; import org.apache.olingo.commons.core.edm.EdmProviderImpl;
import org.apache.olingo.server.api.ODataApplicationException; 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.UriInfoKind;
import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind; import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
@ -5252,6 +5253,27 @@ public class TestFullResourcePath {
+ "($filter=PropertyString eq 'Test String1')"); + "($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("<<NavPropertyETTwoKeyNavMany/PropertyInt16> 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("<<NavPropertyETTwoKeyNavMany/PropertyInt16> eq <1>>");
}
@Test(expected=UriParserException.class) @Test(expected=UriParserException.class)
public void testFilterSystemQueryOptionAnyWithKeyAny() throws Exception { public void testFilterSystemQueryOptionAnyWithKeyAny() throws Exception {
testUri.run("ESAllPrim", "$filter=NavPropertyETTwoPrimMany(1)" testUri.run("ESAllPrim", "$filter=NavPropertyETTwoPrimMany(1)"
@ -5272,7 +5294,11 @@ public class TestFullResourcePath {
.at(2).isCount(); .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 { public static String encode(final String decoded) throws UnsupportedEncodingException {
return Encoder.encode(decoded); return Encoder.encode(decoded);