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());

Reply via email to