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 <[email protected]>
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());