Merge branch 'OLINGO-801_ComplexParameter'
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/483ee9de Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/483ee9de Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/483ee9de Branch: refs/heads/master Commit: 483ee9de15cf8bbcc18e2560496724b06be76cf2 Parents: 0ce0a88 3584e1d Author: Christian Holzer <[email protected]> Authored: Thu Oct 29 15:42:05 2015 +0100 Committer: Christian Holzer <[email protected]> Committed: Thu Oct 29 15:42:05 2015 +0100 ---------------------------------------------------------------------- .../olingo/server/core/uri/antlr/UriLexer.g4 | 8 +- .../olingo/server/core/uri/antlr/UriParser.g4 | 11 +- .../olingo/server/core/uri/UriInfoImpl.java | 22 ++- .../olingo/server/core/uri/parser/Parser.java | 27 +++- .../server/core/uri/parser/UriContext.java | 7 +- .../core/uri/parser/UriParseTreeVisitor.java | 161 ++++++++++++------- .../uri/parser/UriParserSemanticException.java | 6 +- .../uri/parser/UriParserSyntaxException.java | 4 +- .../uri/validator/UriValidationException.java | 7 +- .../server/core/uri/validator/UriValidator.java | 53 ++++++ .../server-core-exceptions-i18n.properties | 5 + .../core/uri/antlr/TestFullResourcePath.java | 94 ++++++++++- .../core/uri/antlr/TestUriParserImpl.java | 2 +- .../core/uri/testutil/EdmTechTestProvider.java | 128 +++++++++++++++ .../core/uri/testutil/FilterValidator.java | 29 +++- 15 files changed, 475 insertions(+), 89 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/483ee9de/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java ---------------------------------------------------------------------- diff --cc lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java index bc6a111,40c67c7..42ca097 --- 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 @@@ -1907,9 -1925,9 +1926,9 @@@ public class UriParseTreeVisitor extend UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES, "1", Integer.toString(ctx.vlNVO.size()))); } - + @SuppressWarnings("unchecked") - List<UriParameterImpl> list = (List<UriParameterImpl>) ctx.vlNVO.get(0).accept(this); + List<UriParameter> list = (List<UriParameter>) ctx.vlNVO.get(0).accept(this); ((UriResourceWithKeysImpl) pathInfoSegment) .setKeyPredicates(list); } else { @@@ -1983,25 -2001,27 +2002,26 @@@ @Override public Object visitIntLiteral(final IntLiteralContext ctx) { + EdmPrimitiveTypeKind typeKind = null; try { final long value = Long.parseLong(ctx.getText()); - EdmType type = null; - if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { - type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.SByte); + typeKind = EdmPrimitiveTypeKind.SByte; } else if (value >= 0 && value <= 255) { - type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte); + typeKind = EdmPrimitiveTypeKind.Byte; } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { - type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int16); + typeKind = EdmPrimitiveTypeKind.Int16; } else if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) { - type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int32); + typeKind = EdmPrimitiveTypeKind.Int32; } else { - type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int64); + typeKind = EdmPrimitiveTypeKind.Int64; } - } catch (final NumberFormatException e) { - typeKind = EdmPrimitiveTypeKind.Decimal; - - return new LiteralImpl().setText(ctx.getText()).setType(type); + } catch (NumberFormatException e) { + return new LiteralImpl().setText(ctx.getText()) + .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)); } + return new LiteralImpl().setText(ctx.getText()) + .setType(EdmPrimitiveTypeFactory.getInstance(typeKind)); } @Override @@@ -2122,12 -2143,17 +2142,16 @@@ @Override public Object visitSelectEOF(final SelectEOFContext ctx) { - List<SelectItem> selectItems = new ArrayList<SelectItem>(); + context.contextReadingQueryPart = true; + List<SelectItemImpl> selectItems = new ArrayList<SelectItemImpl>(); - for (SelectItemContext si : ctx.vlSI) { - selectItems.add((SelectItemImpl) si.accept(this)); + selectItems.add((SelectItem) si.accept(this)); } - return new SelectOptionImpl().setSelectItems(selectItems).setText(ctx.getText()); + final QueryOptionImpl result = new SelectOptionImpl().setSelectItems(selectItems).setText(ctx.getText()); + context.contextReadingQueryPart = false; + + return result; } @Override http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/483ee9de/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java ---------------------------------------------------------------------- diff --cc lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java index b24f379,90f9995..566318c --- 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 @@@ -5652,30 -5643,111 +5653,117 @@@ public class TestFullResourcePath testUri.run("ESAllPrim", "$filter=" + Short.MIN_VALUE + " eq " + Short.MAX_VALUE) .goFilter().isBinary(BinaryOperatorKind.EQ) - .left().isLiteral("" + Short.MIN_VALUE).isLiteralType(EdmInt16.getInstance()) + .left().isLiteral(Short.toString(Short.MIN_VALUE)) + .isLiteralType(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16)) .root() - .right().isLiteral("" + Short.MAX_VALUE).isLiteralType(EdmInt16.getInstance()); - + .right().isLiteral(Short.toString(Short.MAX_VALUE)) + .isLiteralType(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16)); + testUri.run("ESAllPrim", "$filter=" + Integer.MIN_VALUE + " eq " + Integer.MAX_VALUE) .goFilter().isBinary(BinaryOperatorKind.EQ) - .left().isLiteral("" + Integer.MIN_VALUE).isLiteralType(EdmInt32.getInstance()) + .left().isLiteral(Integer.toString(Integer.MIN_VALUE)) + .isLiteralType(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int32)) .root() - .right().isLiteral("" + Integer.MAX_VALUE).isLiteralType(EdmInt32.getInstance()); - + .right().isLiteral(Integer.toString(Integer.MAX_VALUE)) + .isLiteralType(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int32)); + testUri.run("ESAllPrim", "$filter=" + Long.MIN_VALUE + " eq " + Long.MAX_VALUE) .goFilter().isBinary(BinaryOperatorKind.EQ) - .left().isLiteral("" + Long.MIN_VALUE).isLiteralType(EdmInt64.getInstance()) + .left().isLiteral(Long.toString(Long.MIN_VALUE)) + .isLiteralType(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int64)) .root() - .right().isLiteral("" + Long.MAX_VALUE).isLiteralType(EdmInt64.getInstance()); + .right().isLiteral(Long.toString(Long.MAX_VALUE)) + .isLiteralType(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int64)); } + + @Test + public void parameterAliasLiteralValidation() throws Exception { + testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=1"); + testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=-2"); + testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe'") + .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY); + testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe") + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + } + + @Test + public void functionsWithComplexParameters() throws Exception { + testUri.run("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp=@p1)", "@p1={\"PropertyInt16\":1,\"ProperyString\":\"1\"}") + .goPath() + .at(0).isEntitySet("ESTwoKeyNav") + .at(1).isFunction("BFCESTwoKeyNavRTStringParam").isParameterAlias(0, "ParameterComp", "@p1") + .isInAliasToValueMap("@p1", "{\"PropertyInt16\":1,\"ProperyString\":\"1\"}"); + + // Test JSON String lexer rule =\"3,Int16=abc},\\\nabc&test%test\b\f\r\t\u0022} + final String stringValueEncoded = "=\\\"3,Int16=abc},\\\\\\nabc%26test%25test\\b\\f\\r\\t\\u0022}"; + final String stringValueDecoded = "=\\\"3,Int16=abc},\\\\\\nabc&test%test\\b\\f\\r\\t\\u0022}"; - public static String encode(final String decoded) { - return decoded.replaceAll(":", "%3A"); + testUri.run("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp=@p1)", "@p1={\"PropertyInt16\":1,\"ProperyString\":\"" + stringValueEncoded + "\"}") + .goPath() + .at(0).isEntitySet("ESTwoKeyNav") + .at(1).isFunction("BFCESTwoKeyNavRTStringParam").isParameterAlias(0, "ParameterComp", "@p1") + .isInAliasToValueMap("@p1", "{\"PropertyInt16\":1,\"ProperyString\":\"" + stringValueDecoded + "\"}"); + + testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp={\"PropertyString\":\"Test\",\"PropertyInt16\":1}) eq 'Test'") + .goFilter().left().is("<<BFCESTwoKeyNavRTStringParam> eq <'Test'>>") + .isParameterText(0, "{\"PropertyString\":\"Test\",\"PropertyInt16\":1}"); + + testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp={\"PropertyString\":\"" + stringValueEncoded + "\",\"PropertyInt16\":1}) eq 'Test'") + .goFilter().left().is("<<BFCESTwoKeyNavRTStringParam> eq <'Test'>>") + .isParameterText(0, "{\"PropertyString\":\"=\\\"3,Int16=abc},\\\\\\nabc&test%test\\b\\f\\r\\t\\u0022}\"," + + "\"PropertyInt16\":1}"); + + testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp=@p1) eq 0&@p1={\"PropertyInt16\":1,\"ProperyString\":\"1\"}"); + + testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp=@p1)", "@p1={\"PropertyInt16\":1,\"ProperyString\":'1'}") + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + + testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam" + + "(ParameterComp={\"PropertyInt16\":1,\"PropertyString\":\"Test\"})") + .isExSemantic(UriParserSemanticException.MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH); + + testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=null)") + .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER); + + testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)") + .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER); + + testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null") + .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER); + + testUri.run("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test='null'"); + + testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test, UnknownParam=1)", "@test='null'") + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND); + + testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test='null'"); + testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null"); + testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)"); + testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=null)"); + + testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null&@test='1'") + .isExSyntax(UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS); + + testUri.runEx("ESAllPrim", "$filter=FINRTInt16() eq 0") + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_IMPORT_NOT_ALLOWED); + } + + @Test + @Ignore("Key predicates in filter/orderby expression are not validated currently") + public void testKeyPredicatesInExpressions() throws Exception { + testUri.run("ESTwoKeyNav", "$filter=NavPropertyETTwoKeyNavMany(PropertyString='1',PropertyInt16=1)" + + "/PropertyInt16 eq 1"); + testUri.runEx("ESTwoKeyNav", "$filter=NavPropertyETTwoKeyNavMany(Prop='22',P=2)/PropertyInt16 eq 0") + .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY); + } + + public static String encode(final String decoded) throws UnsupportedEncodingException { + return Encoder.encode(decoded); } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/483ee9de/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/483ee9de/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java ---------------------------------------------------------------------- diff --cc lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java index ad9d4eb,fa0e537..309a25f --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java @@@ -31,22 -31,26 +31,26 @@@ import org.apache.olingo.commons.api.ed import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriInfoKind; + import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.queryoption.FilterOption; +import org.apache.olingo.server.api.uri.queryoption.OrderByOption; +import org.apache.olingo.server.api.uri.queryoption.expression.Binary; import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind; +import org.apache.olingo.server.api.uri.queryoption.expression.Enumeration; import org.apache.olingo.server.api.uri.queryoption.expression.Expression; import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException; +import org.apache.olingo.server.api.uri.queryoption.expression.Literal; import org.apache.olingo.server.api.uri.queryoption.expression.Member; +import org.apache.olingo.server.api.uri.queryoption.expression.Method; import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind; -import org.apache.olingo.server.core.uri.UriInfoImpl; +import org.apache.olingo.server.api.uri.queryoption.expression.TypeLiteral; + import org.apache.olingo.server.core.uri.UriResourceFunctionImpl; import org.apache.olingo.server.core.uri.parser.Parser; import org.apache.olingo.server.core.uri.parser.UriParserException; import org.apache.olingo.server.core.uri.parser.UriParserSemanticException; import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException; -import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl; -import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.EnumerationImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl; + import org.apache.olingo.server.core.uri.queryoption.expression.MemberImpl; + import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.TypeLiteralImpl; public class FilterValidator implements TestValidator { private Edm edm;
