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)

Reply via email to