This is an automated email from the ASF dual-hosted git repository. mibo pushed a commit to branch OLINGO-1583 in repository https://gitbox.apache.org/repos/asf/olingo-odata2.git
commit 307405298f22a337df638cffdfd9cba5d6130078 Author: mibo <[email protected]> AuthorDate: Sun Oct 23 08:54:29 2022 +0200 [OLINGO-1583] Added 'strictFilter' option for UriParser --- .../apache/olingo/odata2/api/uri/UriParser.java | 34 +++++- .../olingo/odata2/client/api/ODataClient.java | 35 +++++- .../olingo/odata2/client/core/ODataClientImpl.java | 48 ++++++++ .../odata2/client/core/uri/UriParserTest.java | 131 +++++++++++++++------ .../olingo/odata2/core/uri/UriParserImpl.java | 12 +- .../core/uri/expression/FilterParserImpl.java | 25 +++- 6 files changed, 239 insertions(+), 46 deletions(-) diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java index 11426d08..f7fb425b 100644 --- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java +++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java @@ -53,10 +53,25 @@ public abstract class UriParser { return RuntimeDelegate.getUriParser(edm).parse(pathSegments, queryParameters); } + /** + * Parses path segments and query parameters for the given EDM. + * Will not be available in higher versions + * @param edm Entity Data Model + * @param pathSegments list of path segments + * @param queryParameters query parameters + * @param strictFilter for URI Parsing of filter parameters + * @return {@link UriInfo} information about the parsed URI + * @throws ODataException + */ + public static UriInfo parse(final Edm edm, final List<PathSegment> pathSegments, + final Map<String, String> queryParameters, boolean strictFilter) throws ODataException { + return RuntimeDelegate.getUriParser(edm).parse(pathSegments, queryParameters, strictFilter); + } + /** * Parses path segments and query parameters. * This method ignores redundant system query parameters. - * + * * @param pathSegments list of path segments * @param queryParameters query parameters * @return {@link UriInfo} information about the parsed URI @@ -67,6 +82,23 @@ public abstract class UriParser { public abstract UriInfo parse(List<PathSegment> pathSegments, Map<String, String> queryParameters) throws UriSyntaxException, UriNotMatchingException, EdmException; + /** + * Parses path segments and query parameters. + * This method ignores redundant system query parameters. + * + * @param pathSegments list of path segments + * @param queryParameters query parameters + * @param strictFilter for URI Parsing of filter parameters + * @return {@link UriInfo} information about the parsed URI + * @throws UriSyntaxException + * @throws UriNotMatchingException + * @throws EdmException + */ + public abstract UriInfo parse(List<PathSegment> pathSegments, + Map<String, String> queryParameters, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException; + + /** * Parses path segments and query parameters. * Throws an exception if there are redundant system query parameters. diff --git a/odata2-lib/odata-client-api/src/main/java/org/apache/olingo/odata2/client/api/ODataClient.java b/odata2-lib/odata-client-api/src/main/java/org/apache/olingo/odata2/client/api/ODataClient.java index b3282a75..5a189786 100644 --- a/odata2-lib/odata-client-api/src/main/java/org/apache/olingo/odata2/client/api/ODataClient.java +++ b/odata2-lib/odata-client-api/src/main/java/org/apache/olingo/odata2/client/api/ODataClient.java @@ -106,6 +106,21 @@ public abstract class ODataClient { final Map<String, List<String>> queryParameters) throws UriSyntaxException, UriNotMatchingException, EdmException; //NOPMD - suppressed + /** + * Parses the uri and returns UriInfo + * @param edm + * @param pathSegments + * @param queryParameters + * @param strictFilter + * @return UriInfo + * @throws EntityProviderException + * @throws EdmException + */ + + public abstract UriInfo parseUri(final Edm edm, final List<PathSegment> pathSegments, + final Map<String, String> queryParameters, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException; //NOPMD - suppressed + /** * Parses the uri and returns UriInfo * @param edm @@ -115,10 +130,24 @@ public abstract class ODataClient { * @throws UriNotMatchingException * @throws EdmException */ - - public abstract UriInfo parseUri(final Edm edm, final String uri) + + public abstract UriInfo parseUri(final Edm edm, final String uri) throws UriSyntaxException, UriNotMatchingException, EdmException; //NOPMD - suppressed - + + /** + * Parses the uri and returns UriInfo + * @param edm + * @param uri + * @param strictFilter + * @return UriInfo + * @throws UriSyntaxException + * @throws UriNotMatchingException + * @throws EdmException + */ + + public abstract UriInfo parseUri(final Edm edm, final String uri, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException; //NOPMD - suppressed + /** diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ODataClientImpl.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ODataClientImpl.java index 60b2b881..13230634 100644 --- a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ODataClientImpl.java +++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ODataClientImpl.java @@ -124,6 +124,13 @@ public class ODataClientImpl extends ODataClient implements DeserializerMetadata return new UriParserImpl(edm).parseAll(pathSegments, queryParameters); } + @Override + public UriInfo parseUri(Edm edm, List<PathSegment> pathSegments, + Map<String, String> queryParameters, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException { + return new UriParserImpl(edm).parse(pathSegments, queryParameters, strictFilter); + } + @Override public UriInfo parseUri(Edm edm, String uri) throws UriSyntaxException, UriNotMatchingException, EdmException { final String[] path = uri.split(QUESTIONMARK, -1); @@ -142,6 +149,28 @@ public class ODataClientImpl extends ODataClient implements DeserializerMetadata return new UriParserImpl(edm).parseAll(pathSegments, queryParameters); } + + @Override + public UriInfo parseUri(Edm edm, String uri, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException { + + final String[] path = uri.split(QUESTIONMARK, -1); + if (path.length > 2) { + throw new UriSyntaxException(UriSyntaxException.URISYNTAX); + } + + final List<PathSegment> pathSegments = getPathSegments(path[0]); + + Map<String, String> queryParameters; + if (path.length == 2) { + queryParameters = getQueryParametersWithStrictFilter(unescape(path[1])); + } else { + queryParameters = new HashMap<String, String>(); + } + + return new UriParserImpl(edm).parse(pathSegments, queryParameters, strictFilter); + } + /** * Fetch query parameters * @param uri @@ -162,6 +191,25 @@ public class ODataClientImpl extends ODataClient implements DeserializerMetadata return allQueryParameters; } + + /** + * Fetch Query parameters + * @param uri + * @return + */ + private Map<String, String> getQueryParametersWithStrictFilter(String uri) { + Map<String, String> queryParameters = new HashMap<String, String>(); + for (final String option : uri.split(AMP)) { + final String[] keyAndValue = option.split(EQUAL); + if (keyAndValue.length == 2) { + queryParameters.put(keyAndValue[0], keyAndValue[1]); + } else { + queryParameters.put(keyAndValue[0], ""); + } + } + return queryParameters; + } + /** * Fetch path segments * @param uri diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/uri/UriParserTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/uri/UriParserTest.java index a61420bc..0183d0d5 100644 --- a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/uri/UriParserTest.java +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/uri/UriParserTest.java @@ -68,27 +68,27 @@ public class UriParserTest { public void getEdm() throws ODataException { edm = MockFacade.getMockEdm(); } - + @Test public void copyPathSegmentsTest() throws Exception { List<PathSegment> pathSegments = new ArrayList<PathSegment>(); pathSegments.add(UriParser.createPathSegment("$metadata", null)); - UriInfo result = new UriParserImpl(edm).parse(pathSegments, Collections.<String, String> emptyMap()); + UriInfo result = new UriParserImpl(edm).parse(pathSegments, Collections.<String, String>emptyMap()); assertNotNull(result); assertEquals(1, pathSegments.size()); assertEquals("$metadata", pathSegments.get(0).getPath()); } - + @Test public void copyPathSegmentsTestEncoded() throws Exception { List<PathSegment> pathSegments = new ArrayList<PathSegment>(); pathSegments.add(UriParser.createPathSegment("%24metadata", null)); UriInfoImpl result = (UriInfoImpl) new UriParserImpl(edm).parse(pathSegments, - Collections.<String, String> emptyMap()); + Collections.<String, String>emptyMap()); assertNotNull(result); assertEquals(UriType.URI8, result.getUriType()); } - + @Test public void parseNonsense() throws Exception { parseWrongUri("/bla", UriNotMatchingException.NOTFOUND); @@ -103,8 +103,8 @@ public class UriParserTest { assertEquals(UriType.URI0, result.getUriType()); result = - (UriInfoImpl) new UriParserImpl(edm).parse(Collections.<PathSegment> emptyList(), Collections - .<String, String> emptyMap()); + (UriInfoImpl) new UriParserImpl(edm).parse(Collections.<PathSegment>emptyList(), Collections + .<String, String>emptyMap()); assertEquals(UriType.URI0, result.getUriType()); } @@ -237,7 +237,7 @@ public class UriParserTest { assertEquals("1", result.getKeyPredicates().get(0).getLiteral()); assertEquals("EmployeeId", result.getKeyPredicates().get(0).getProperty().getName()); } - + @Test public void parseEmployeesEntity() throws Exception { UriInfoImpl result = parse("/Employees('1')"); @@ -310,7 +310,7 @@ public class UriParserTest { assertEquals("1", result.getKeyPredicates().get(0).getLiteral()); assertEquals("EmployeeId", result.getKeyPredicates().get(0).getProperty().getName()); } - + @Test public void parseEmployeesEntityWithKeyCountEncoded() throws Exception { UriInfoImpl result = parse("/Employees('1')/%24count"); @@ -322,7 +322,7 @@ public class UriParserTest { assertEquals("1", result.getKeyPredicates().get(0).getLiteral()); assertEquals("EmployeeId", result.getKeyPredicates().get(0).getProperty().getName()); } - + @Test public void parseEmployeesSimpleProperty() throws Exception { UriInfoImpl result = parse("/Employees('1')/EmployeeName"); @@ -341,7 +341,7 @@ public class UriParserTest { assertEquals("EmployeeName", result.getPropertyPath().get(0).getName()); assertTrue(result.isValue()); } - + @Test public void parseEmployeesSimplePropertyValueEncoded() throws Exception { UriInfoImpl result = parse("/Employees('1')/EmployeeName/%24value"); @@ -351,7 +351,7 @@ public class UriParserTest { assertEquals("EmployeeName", result.getPropertyPath().get(0).getName()); assertTrue(result.isValue()); } - + @Test public void parseEmployeesComplexProperty() throws Exception { UriInfoImpl result = parse("/Employees('1')/Location"); @@ -444,7 +444,7 @@ public class UriParserTest { assertTrue(result.isLinks()); assertEquals(UriType.URI7B, result.getUriType()); } - + @Test public void parseNavigationPropertyWithLinksManyEncoded() throws Exception { UriInfoImpl result = parse("/Managers('1')/%24links/nm_Employees"); @@ -452,7 +452,7 @@ public class UriParserTest { assertTrue(result.isLinks()); assertEquals(UriType.URI7B, result.getUriType()); } - + @Test public void parseNavigationPropertyWithManagersCount() throws Exception { UriInfoImpl result = parse("/Employees('1')/ne_Manager/$count"); @@ -640,12 +640,12 @@ public class UriParserTest { assertEquals("MaximalAge", result.getFunctionImport().getName()); assertTrue(result.isValue()); assertEquals(UriType.URI14, result.getUriType()); - + result = parse("MaximalAge/%24value"); assertEquals("MaximalAge", result.getFunctionImport().getName()); assertTrue(result.isValue()); assertEquals(UriType.URI14, result.getUriType()); - + result = parse("MostCommonLocation"); assertEquals("MostCommonLocation", result.getFunctionImport().getName()); assertEquals(UriType.URI12, result.getUriType()); @@ -657,7 +657,7 @@ public class UriParserTest { result = parse("OldestEmployee"); assertEquals("OldestEmployee", result.getFunctionImport().getName()); assertEquals(UriType.URI10, result.getUriType()); - + result = parse("EmployeeSearch?$filter=EmployeeId%20eq%20%271%27&$select=EmployeeName"); assertEquals("Employee", result.getFunctionImport().getReturnType().getType().getName()); assertEquals(EdmMultiplicity.MANY, result.getFunctionImport().getReturnType().getMultiplicity()); @@ -675,13 +675,13 @@ public class UriParserTest { .getType()); assertEquals("Hugo", result.getFunctionImportParameters().get("q").getLiteral()); } - + @Test public void parseFunctionImportParametersWithFacets() throws Exception { UriInfoImpl result = parse("FINullableParameter"); assertEquals("FINullableParameter", result.getFunctionImport().getName()); assertTrue(result.getFunctionImportParameters().isEmpty()); - + result = parse("FINullableParameter?Id='A'"); assertEquals("FINullableParameter", result.getFunctionImport().getName()); assertFalse(result.getFunctionImportParameters().isEmpty()); @@ -720,7 +720,7 @@ public class UriParserTest { assertEquals("abc", result.getSkipToken()); assertEquals(2, result.getSkip().intValue()); assertEquals(1, result.getTop().intValue()); - + result = parse("Employees?$format=json&%24inlinecount=allpages&%24skiptoken=abc&%24skip=2&$top=1"); assertEquals("Employees", result.getTargetEntitySet().getName()); assertEquals(UriType.URI1, result.getUriType()); @@ -729,7 +729,7 @@ public class UriParserTest { assertEquals("abc", result.getSkipToken()); assertEquals(2, result.getSkip().intValue()); assertEquals(1, result.getTop().intValue()); - + result = parse("Employees?$format=atom&$inlinecount=none&$skip=0&$top=0"); assertEquals("Employees", result.getTargetEntitySet().getName()); assertEquals(UriType.URI1, result.getUriType()); @@ -777,16 +777,40 @@ public class UriParserTest { assertNotNull(result.getFilter()); assertNotNull(result.getOrderBy()); assertEquals("EmployeeName desc", result.getOrderBy().getUriLiteral()); - + result = parse("EmployeeSearch?$filter=EmployeeId%20eq%20%271%27"); assertEquals("Employee", result.getFunctionImport().getReturnType().getType().getName()); assertEquals(EdmMultiplicity.MANY, result.getFunctionImport().getReturnType().getMultiplicity()); assertEquals(UriType.URI10a, result.getUriType()); assertNotNull(result.getFilter()); } - - @Test(expected=UriSyntaxException.class) - public void parseFilterOptionsWithError1() throws Exception { + + @Test + public void parseFilterOptions() throws Exception { + UriInfoImpl result = parse("Employees?$filter=Age%20gt%2020", false); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertNotNull(result.getFilter()); + + result = parse("Employees?$filter=EmployeeName%20gt%20%27Archana%27", false); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertNotNull(result.getFilter()); + + result = parse("Managers?$filter=nm_Employees%20eq%20null", false); + assertEquals("Managers", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertNotNull(result.getFilter()); + + + result = parse("Managers?$filter=nm_Employees/EmployeeName%20eq%20%27Archana%27", false); + assertEquals("Managers", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertNotNull(result.getFilter()); + } + + @Test(expected = UriSyntaxException.class) + public void parseFilterOptionsWithError1() throws Exception { ODataClient.newInstance().parseUri(edm, "Managers?count?$filter=nm_Employees/EmployeeName%20eq%20%27Archana%27"); } @@ -918,13 +942,13 @@ public class UriParserTest { assertEquals(UriType.URI1, result.getUriType()); assertEquals(1, result.getSelect().size()); assertEquals("EmployeeName", result.getSelect().get(0).getProperty().getName()); - + result = parse("Employees?%24select=EmployeeName"); assertEquals("Employees", result.getTargetEntitySet().getName()); assertEquals(UriType.URI1, result.getUriType()); assertEquals(1, result.getSelect().size()); assertEquals("EmployeeName", result.getSelect().get(0).getProperty().getName()); - + result = parse("Employees?$select=*"); assertEquals("Employees", result.getTargetEntitySet().getName()); assertEquals(UriType.URI1, result.getUriType()); @@ -1010,7 +1034,7 @@ public class UriParserTest { assertEquals("Employees", result.getExpand().get(0).get(0).getTargetEntitySet().getName()); assertEquals(result.getTargetEntitySet().getEntityType().getProperty("nm_Employees"), result.getExpand().get(0).get(0).getNavigationProperty()); - + result = parse("Managers('1')?%24expand=nm_Employees"); assertEquals("Managers", result.getTargetEntitySet().getName()); assertEquals(UriType.URI2, result.getUriType()); @@ -1043,7 +1067,7 @@ public class UriParserTest { } private void wrongGetKey(final EdmEntitySet entitySet, final String link, final String serviceRoot, - final MessageReference exceptionContext) throws ODataException { + final MessageReference exceptionContext) throws ODataException { try { new UriParserImpl(null).getKeyFromEntityLink(entitySet, link, serviceRoot == null ? null : URI.create(serviceRoot)); @@ -1101,14 +1125,28 @@ public class UriParserTest { assertTrue(segmentWithMatrix.getMatrixParameters().get("parameter1").contains("one")); assertTrue(segmentWithMatrix.getMatrixParameters().get("parameter1").contains("two")); } - + /** * Parse the URI part after an OData service root, given as string. * Query parameters can be included. + * * @param uri the URI part * @return a {@link UriInfoImpl} instance containing the parsed information */ - private UriInfoImpl parse(final String uri) throws UriSyntaxException, UriNotMatchingException, EdmException { + private UriInfoImpl parse(final String uri) + throws UriSyntaxException, UriNotMatchingException, EdmException { + return parse(uri, true); + } + + /** + * Parse the URI part after an OData service root, given as string. + * Query parameters can be included. + * @param uri the URI part + * @return a {@link UriInfoImpl} instance containing the parsed information + */ + private UriInfoImpl parse(final String uri, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException { + final String[] path = uri.split("\\?", -1); if (path.length > 2) { throw new UriSyntaxException(UriSyntaxException.URISYNTAX); @@ -1116,9 +1154,14 @@ public class UriParserTest { final List<PathSegment> pathSegments = MockFacade.getPathSegmentsAsODataPathSegmentMock(Arrays.asList(path[0].split("/", -1))); - final Map<String, List<String>> queryParameters = getQueryParameters(path.length == 2 ? unescape(path[1]) : ""); - - return (UriInfoImpl) ODataClient.newInstance().parseUri(edm, pathSegments, queryParameters); + if (strictFilter) { + final Map<String, List<String>> queryParameters = getQueryParameters(path.length == 2 ? unescape(path[1]) : ""); + return (UriInfoImpl) ODataClient.newInstance().parseUri(edm, pathSegments, queryParameters); + } else { + final Map<String, String> queryParameters = + getQueryParametersWithStrictFilter(path.length == 2 ? unescape(path[1]) : ""); + return (UriInfoImpl) ODataClient.newInstance().parseUri(edm, pathSegments, queryParameters, false); + } } private Map<String, List<String>> getQueryParameters(final String uri) { @@ -1136,7 +1179,25 @@ public class UriParserTest { return allQueryParameters; } - + + /** + * Fetch Query parameters + * @param uri + * @return + */ + private Map<String, String> getQueryParametersWithStrictFilter(String uri) { + Map<String, String> queryParameters = new HashMap<String, String>(); + for (final String option : uri.split("&")) { + final String[] keyAndValue = option.split("="); + if (keyAndValue.length == 2) { + queryParameters.put(keyAndValue[0], keyAndValue[1]); + } else { + queryParameters.put(keyAndValue[0], ""); + } + } + return queryParameters; + } + private String unescape(final String s) throws UriSyntaxException { try { return new URI(s).getPath(); diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java index 6ebab2f1..528151a2 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java @@ -93,6 +93,7 @@ public class UriParserImpl extends UriParser { private Map<SystemQueryOption, String> systemQueryOptions; private Map<String, String> otherQueryParameters; private String originalFilterString = ""; + private boolean strictFilter = true; public UriParserImpl(final Edm edm) { this.edm = edm; @@ -114,6 +115,13 @@ public class UriParserImpl extends UriParser { return parseAll(pathSegments, convertFromSingleMapToMultiMap(queryParameters)); } + @Override + public UriInfo parse(List<PathSegment> pathSegments, Map<String, String> queryParameters, boolean strictFilter) + throws UriSyntaxException, UriNotMatchingException, EdmException { + this.strictFilter = strictFilter; + return parseAll(pathSegments, convertFromSingleMapToMultiMap(queryParameters)); + } + @Override public UriInfo parseAll(final List<PathSegment> pathSegments, final Map<String, List<String>> allQueryParameters) throws UriSyntaxException, UriNotMatchingException, EdmException { @@ -735,7 +743,7 @@ public class UriParserImpl extends UriParser { final EdmType targetType = uriResult.getTargetType(); if (targetType instanceof EdmEntityType) { try { - uriResult.setFilter(new FilterParserImpl((EdmEntityType) targetType,originalFilterString). + uriResult.setFilter(new FilterParserImpl((EdmEntityType) targetType, strictFilter, originalFilterString). parseFilterString(filter, true)); } catch (ExpressionParserException e) { throw new UriSyntaxException(UriSyntaxException.INVALIDFILTEREXPRESSION.addContent(filter), e); @@ -1004,7 +1012,7 @@ public class UriParserImpl extends UriParser { @Override public FilterExpression parseFilterString(final EdmEntityType entityType, final String expression) throws ODataMessageException { - return new FilterParserImpl(entityType).parseFilterString(expression); + return new FilterParserImpl(entityType, strictFilter).parseFilterString(expression); } @Override diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java index b8f5c88b..b37a804a 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java @@ -67,6 +67,8 @@ public class FilterParserImpl implements FilterParser { protected String curExpression; protected String originalFilterString = ""; protected String decodedFilterString = ""; + private boolean strictFilter = true; + /** * Creates a new FilterParser implementation @@ -75,16 +77,29 @@ public class FilterParserImpl implements FilterParser { public FilterParserImpl(final EdmEntityType resourceEntityType) { this.resourceEntityType = resourceEntityType; } - + /** * Creates a new FilterParser implementation * @param resourceEntityType EntityType of the resource on which the filter is applied - * @param originalFilterString String original filter string prior to decoding + * @param strictFilter boolean check to decide weather to validate filter */ - public FilterParserImpl(final EdmEntityType resourceEntityType, String originalFilterString) { + public FilterParserImpl(final EdmEntityType resourceEntityType, boolean strictFilter) { this.resourceEntityType = resourceEntityType; + this.strictFilter = strictFilter; + } + + /** + * Creates a new FilterParser implementation + * @param resourceEntityType EntityType of the resource on which the filter is applied + * @param strictFilter boolean check to decide weather to validate filter + * @param originalFilterString String original filter string prior to decoding + */ + public FilterParserImpl(final EdmEntityType resourceEntityType, boolean strictFilter, + String originalFilterString) { + this.resourceEntityType = resourceEntityType; + this.strictFilter = strictFilter; this.originalFilterString = originalFilterString; - } + } @Override public FilterExpression parseFilterString(final String filterExpression) throws ExpressionParserException, @@ -524,7 +539,7 @@ public class FilterParserImpl implements FilterParser { property.setEdmProperty(edmProperty); property.setEdmType(edmProperty.getType()); if(isLastFilterElement(propertyName)) { - if (edmProperty.getMultiplicity() == EdmMultiplicity.MANY) { + if (edmProperty.getMultiplicity() == EdmMultiplicity.MANY && strictFilter) { throw new ExpressionParserException( ExpressionParserException.INVALID_MULTIPLICITY.create() .addContent(propertyName)
