This is an automated email from the ASF dual-hosted git repository. ramyav pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/olingo-odata2.git
The following commit(s) were added to refs/heads/master by this push: new 006bf43 [OLINGO-1530]+ in url filter parameter is passed as space 006bf43 is described below commit 006bf435948d6d56fb61402fd1a783dffb90f0e7 Author: ramya vasanth <ramya.vasa...@sap.com> AuthorDate: Thu Sep 16 17:25:13 2021 +0530 [OLINGO-1530]+ in url filter parameter is passed as space --- .../olingo/odata2/core/uri/UriParserImpl.java | 7 +- .../core/uri/expression/FilterParserImpl.java | 40 +++++++- .../olingo/odata2/core/uri/UriParserTest.java | 109 +++++++++++++++++++++ 3 files changed, 152 insertions(+), 4 deletions(-) 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 881e97b..6ebab2f 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 @@ -92,6 +92,7 @@ public class UriParserImpl extends UriParser { private UriInfoImpl uriResult; private Map<SystemQueryOption, String> systemQueryOptions; private Map<String, String> otherQueryParameters; + private String originalFilterString = ""; public UriParserImpl(final Edm edm) { this.edm = edm; @@ -635,6 +636,9 @@ public class UriParserImpl extends UriParser { if (valueList.size() >= 1) { String value = valueList.get(0); if(formEncoding){ + if(decodedString.equalsIgnoreCase(SystemQueryOption.$filter.toString())){ + originalFilterString = value; + } value = getFormEncodedValue(value); } if (decodedString.startsWith("$")) { @@ -731,7 +735,8 @@ public class UriParserImpl extends UriParser { final EdmType targetType = uriResult.getTargetType(); if (targetType instanceof EdmEntityType) { try { - uriResult.setFilter(new FilterParserImpl((EdmEntityType) targetType).parseFilterString(filter, true)); + uriResult.setFilter(new FilterParserImpl((EdmEntityType) targetType,originalFilterString). + parseFilterString(filter, true)); } catch (ExpressionParserException e) { throw new UriSyntaxException(UriSyntaxException.INVALIDFILTEREXPRESSION.addContent(filter), e); } catch (ODataMessageException e) { 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 6623a75..b8f5c88 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 @@ -65,6 +65,8 @@ public class FilterParserImpl implements FilterParser { protected EdmEntityType resourceEntityType = null; protected TokenList tokenList = null; protected String curExpression; + protected String originalFilterString = ""; + protected String decodedFilterString = ""; /** * Creates a new FilterParser implementation @@ -73,6 +75,16 @@ 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 + */ + public FilterParserImpl(final EdmEntityType resourceEntityType, String originalFilterString) { + this.resourceEntityType = resourceEntityType; + this.originalFilterString = originalFilterString; + } @Override public FilterExpression parseFilterString(final String filterExpression) throws ExpressionParserException, @@ -84,6 +96,7 @@ public class FilterParserImpl implements FilterParser { throws ExpressionParserException, ExpressionParserInternalError { CommonExpression node = null; curExpression = filterExpression; + decodedFilterString = filterExpression; try { // Throws TokenizerException and FilterParserException. FilterParserException is caught somewhere above tokenList = new Tokenizer(filterExpression).tokenize(); @@ -120,8 +133,11 @@ public class FilterParserImpl implements FilterParser { throw FilterParserExceptionImpl.createTYPE_EXPECTED_AT(EdmBoolean.getInstance(), node.getEdmType(), 1, curExpression); } - - return new FilterExpressionImpl(filterExpression, node); + if (filterExpression.equals(decodedFilterString)) { + return new FilterExpressionImpl(filterExpression, node); + } else { + return new FilterExpressionImpl(decodedFilterString, node); + } } protected CommonExpression readElements(final CommonExpression leftExpression, final int priority) @@ -363,7 +379,8 @@ public class FilterParserImpl implements FilterParser { // -->Check if token is a terminal // is a terminal e.g. a Value like an EDM.String 'hugo' or 125L or 1.25D" if (token.getKind() == TokenKind.SIMPLE_TYPE) { - LiteralExpression literal = new LiteralExpressionImpl(token.getUriLiteral(), token.getJavaLiteral()); + LiteralExpression literal = new LiteralExpressionImpl( + getEncodedUriLiteral(token.getUriLiteral(),token.getPosition()), token.getJavaLiteral()); return literal; } @@ -622,6 +639,23 @@ public class FilterParserImpl implements FilterParser { } methodExpression.setEdmType(parameterSet.getReturnType()); } + + /* + * In case we have + in the string literal and is replaced with ' '(space) in UriParserImpl + * it needs to be changed back to + + */ + private String getEncodedUriLiteral(String uriLiteral,int pos) { + if (originalFilterString.length()!=0 && uriLiteral.contains(" ")) { + String encodedUriLiteral = uriLiteral.replaceAll(" ", "+"); + String originalFilterToken = originalFilterString.substring(pos,pos+uriLiteral.length()); + if (originalFilterToken!=null && originalFilterToken.equals(encodedUriLiteral)) { + decodedFilterString=decodedFilterString.substring(0, pos)+encodedUriLiteral+ + decodedFilterString.substring(pos+uriLiteral.length()); + uriLiteral = encodedUriLiteral; + } + } + return uriLiteral; + } static void initAvailTables() { Map<String, InfoBinaryOperator> lAvailableBinaryOperators = new HashMap<String, InfoBinaryOperator>(); diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java index 2429f35..707ff09 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java @@ -1097,8 +1097,117 @@ public class UriParserTest extends BaseTest { parseWrongUri("Employees?$filter=EmployeeId+eq+%271%27&odata-accept-forms-encoding=asdf", UriSyntaxException.INVALIDFILTEREXPRESSION); } + + + @Test + public void parseSystemQueryOptionHavingPlusAsValueFilterFormEncoding1() throws Exception { + UriInfoImpl result = parse("Employees?$filter=EmployeeId+eq+%27A+B%27&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("EmployeeId eq 'A+B'", result.getFilter().getUriLiteral()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValueFilterFormEncoding2() throws Exception { + UriInfoImpl result = parse("Employees?$filter=EmployeeId+eq+%27A+B+C%27&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("EmployeeId eq 'A+B+C'", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValueANDFilterFormEncoding() throws Exception { + UriInfoImpl result = parse("Employees?$filter=EmployeeId+eq+%27A+B%27+and+" + + "EmployeeName+eq+%27Sam%27&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("EmployeeId eq 'A+B' and EmployeeName eq 'Sam'", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValuestartswithFilterFormEncoding() throws Exception { + UriInfoImpl result = parse("Employees?$filter=substring(EmployeeId,1)+eq+%27A+B%27" + + "&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("substring(EmployeeId,1) eq 'A+B'", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValuesubstringofilterFormEncoding() throws Exception { + UriInfoImpl result = parse("Employees?$filter=startswith(EmployeeId,%27A+B%27)&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("startswith(EmployeeId,'A+B')", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } @Test + public void parseSystemQueryOptionHavingPlusAsValueendswithFilterFormEncoding() throws Exception { + UriInfoImpl result = parse("Employees?$filter=endswith(EmployeeId,%27A+B%27)&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("endswith(EmployeeId,'A+B')", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValueORFilterFormEncoding1() throws Exception { + UriInfoImpl result = parse("Employees?$filter=EmployeeId+eq+%27A+B%27+or+" + + "EmployeeName+eq+%27A%20B%27&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("EmployeeId eq 'A+B' or EmployeeName eq 'A B'", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValueorderbyAndsubstringofilterFormEncoding() throws Exception { + UriInfoImpl result = parse("Employees?$orderby=EmployeeId%20asc&$filter=substringof(%27GW%27,EmployeeId)" + + "%20and%20substringof(%27IWBEP%27,EmployeeName)%20and%20substringof(%27%20%27,EmployeeId)" + + "&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("substringof('GW',EmployeeId) and substringof('IWBEP',EmployeeName) and substringof(' ',EmployeeId)", + result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + + @Test + public void parseSystemQueryOptionHavingPlusAsValueORFilterFormEncoding2() throws Exception { + UriInfoImpl result = parse("Employees?$filter=EmployeeId+eq+%27A%20B%27+or+" + + "EmployeeName+eq+%27A+B%27&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("EmployeeId eq 'A B' or EmployeeName eq 'A+B'", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test + public void parseSystemQueryOptionHavingPlusAsValueANDsubsctringofFilterFormEncoding() throws Exception { + UriInfoImpl result = parse("Employees?$filter=substring(EmployeeId,1)+eq+" + + "%27A+B%27+and+EmployeeId+ne+%27C+D%27&odata-accept-forms-encoding=true"); + assertEquals("Employees", result.getTargetEntitySet().getName()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals(UriType.URI1, result.getUriType()); + assertEquals("substring(EmployeeId,1) eq 'A+B' and EmployeeId ne 'C+D'", result.getFilter().getExpressionString()); + assertNull(result.getCustomQueryOptions().get(ACCEPT_FORM_ENCODING)); + } + + @Test public void parseSystemQueryOptionExpand() throws Exception { UriInfoImpl result = parse("Managers('1')?$expand=nm_Employees"); assertEquals("Managers", result.getTargetEntitySet().getName());