You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2022/10/23 07:09:18 UTC

[olingo-odata2] branch olingo-1582 updated (dcc8436c -> 4b9b8065)

This is an automated email from the ASF dual-hosted git repository.

mibo pushed a change to branch olingo-1582
in repository https://gitbox.apache.org/repos/asf/olingo-odata2.git


 discard dcc8436c Added 'strictFilter' option for UriParser
     new 4b9b8065 Added 'strictFilter' option for UriParser

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (dcc8436c)
            \
             N -- N -- N   refs/heads/olingo-1582 (4b9b8065)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/olingo/odata2/client/core/ODataClientImpl.java | 3 ++-
 .../org/apache/olingo/odata2/client/core/uri/UriParserTest.java    | 7 ++++---
 2 files changed, 6 insertions(+), 4 deletions(-)


[olingo-odata2] 01/01: Added 'strictFilter' option for UriParser

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mibo pushed a commit to branch olingo-1582
in repository https://gitbox.apache.org/repos/asf/olingo-odata2.git

commit 4b9b80654a182f9ea0a6d3083533e5dd00741e33
Author: mibo <mi...@apache.org>
AuthorDate: Sun Oct 23 08:54:29 2022 +0200

    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)