Repository: olingo-odata2
Updated Branches:
  refs/heads/URIParser [created] 39e774ba4


Uri parser considers percent encoded resource paths with $batch, $value, 
$links, $value, $metadata


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/39e774ba
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/39e774ba
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/39e774ba

Branch: refs/heads/URIParser
Commit: 39e774ba45e899ebbdf58493654b1464ea13ffd6
Parents: e26395f
Author: Christian Holzer <[email protected]>
Authored: Thu Apr 16 17:37:54 2015 +0200
Committer: Christian Holzer <[email protected]>
Committed: Thu Apr 16 17:37:54 2015 +0200

----------------------------------------------------------------------
 .../olingo/odata2/core/uri/UriParserImpl.java   | 29 +++----
 .../olingo/odata2/core/uri/UriParserTest.java   | 81 ++++++++++++++++++--
 .../olingo/odata2/fit/basic/BasicBatchTest.java | 24 ++++++
 .../ContentNegotiationDollarFormatTest.java     | 23 ++++++
 .../olingo/odata2/fit/basic/MetadataTest.java   |  8 ++
 5 files changed, 146 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e774ba/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java
----------------------------------------------------------------------
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 c58f7ae..d9ae0a5 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
@@ -167,12 +167,13 @@ public class UriParserImpl extends UriParser {
     } else {
 
       currentPathSegment = pathSegments.remove(0);
-
-      if ("$metadata".equals(currentPathSegment)) {
+      final String encodedPath = percentDecode(currentPathSegment);
+      
+      if ("$metadata".equals(encodedPath)) {
         ensureLastSegment();
         uriResult.setUriType(UriType.URI8);
 
-      } else if ("$batch".equals(currentPathSegment)) {
+      } else if ("$batch".equals(encodedPath)) {
         ensureLastSegment();
         uriResult.setUriType(UriType.URI9);
 
@@ -245,12 +246,13 @@ public class UriParserImpl extends UriParser {
 
   private void handleNavigationPathOptions() throws UriSyntaxException, 
UriNotMatchingException, EdmException {
     currentPathSegment = pathSegments.remove(0);
-
+    final String decodedPath = percentDecode(currentPathSegment);
+    
     checkCount();
     if (uriResult.isCount()) {
       uriResult.setUriType(UriType.URI16); // Count of multiple entities is 
handled elsewhere
 
-    } else if ("$value".equals(currentPathSegment)) {
+    } else if ("$value".equals(decodedPath)) {
       if (uriResult.getTargetEntitySet().getEntityType().hasStream()) {
         ensureLastSegment();
         uriResult.setUriType(UriType.URI17);
@@ -259,7 +261,7 @@ public class UriParserImpl extends UriParser {
         throw new UriSyntaxException(UriSyntaxException.NOMEDIARESOURCE);
       }
 
-    } else if ("$links".equals(currentPathSegment)) {
+    } else if ("$links".equals(decodedPath)) {
       uriResult.setLinks(true);
       if (pathSegments.isEmpty()) {
         throw new 
UriSyntaxException(UriSyntaxException.MUSTNOTBELASTSEGMENT.addContent(currentPathSegment));
@@ -392,7 +394,7 @@ public class UriParserImpl extends UriParser {
       currentPathSegment = percentDecode(pathSegments.remove(0));
       switch (type.getKind()) {
       case SIMPLE:
-        if ("$value".equals(currentPathSegment)) {
+        if ("$value".equals(percentDecode(currentPathSegment))) {
           ensureLastSegment();
           uriResult.setValue(true);
           if (uriResult.getPropertyPath().size() == 1) {
@@ -428,7 +430,7 @@ public class UriParserImpl extends UriParser {
   }
 
   private void checkCount() throws UriSyntaxException {
-    if ("$count".equals(currentPathSegment)) {
+    if ("$count".equals(percentDecode(currentPathSegment))) {
       if (pathSegments.isEmpty()) {
         uriResult.setCount(true);
       } else {
@@ -520,7 +522,7 @@ public class UriParserImpl extends UriParser {
     if (!pathSegments.isEmpty()) {
       if (uriResult.getUriType() == UriType.URI14) {
         currentPathSegment = pathSegments.remove(0);
-        if ("$value".equals(currentPathSegment)) {
+        if ("$value".equals(percentDecode(currentPathSegment))) {
           uriResult.setValue(true);
         } else {
           throw new 
UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment));
@@ -532,15 +534,16 @@ public class UriParserImpl extends UriParser {
 
   private void distributeQueryParameters(final Map<String, List<String>> 
queryParameters) throws UriSyntaxException {
     for (final String queryOptionString : queryParameters.keySet()) {
+      final String decodedString = percentDecode(queryOptionString);
       final List<String> valueList = queryParameters.get(queryOptionString);
 
       if (valueList.size() >= 1) {
         String value = valueList.get(0);
-
-        if (queryOptionString.startsWith("$")) {
+        
+        if (decodedString.startsWith("$")) {
           SystemQueryOption queryOption;
           try {
-            queryOption = SystemQueryOption.valueOf(queryOptionString);
+            queryOption = SystemQueryOption.valueOf(decodedString);
           } catch (IllegalArgumentException e) {
             throw new 
UriSyntaxException(UriSyntaxException.INVALIDSYSTEMQUERYOPTION.addContent(queryOptionString),
 e);
           }
@@ -555,7 +558,7 @@ public class UriParserImpl extends UriParser {
             }
           }
         } else {
-          otherQueryParameters.put(queryOptionString, value);
+          otherQueryParameters.put(decodedString, value);
         }
       } else {
         throw new 
UriSyntaxException(UriSyntaxException.INVALIDNULLVALUE.addContent(queryOptionString));

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e774ba/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java
----------------------------------------------------------------------
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 0c64844..d2b57d2 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
@@ -130,7 +130,17 @@ public class UriParserTest extends BaseTest {
     assertEquals(1, pathSegments.size());
     assertEquals("$metadata", pathSegments.get(0).getPath());
   }
-
+  
+  @Test
+  public void copyPathSegmentsTestEncoded() throws Exception {
+    List<PathSegment> pathSegments = new ArrayList<PathSegment>();
+    pathSegments.add(new ODataPathSegmentImpl("$metadata", null));
+    UriInfoImpl result = (UriInfoImpl) new 
UriParserImpl(edm).parse(pathSegments, 
+        Collections.<String, String> emptyMap());
+    assertNotNull(result);
+    assertEquals(UriType.URI8, result.getUriType());
+  }
+  
   @Test
   public void parseNonsense() throws Exception {
     parseWrongUri("/bla", UriNotMatchingException.NOTFOUND);
@@ -291,7 +301,19 @@ public class UriParserTest extends BaseTest {
     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");
+    assertEquals("Employees", result.getTargetEntitySet().getName());
+    assertEquals(UriType.URI16, result.getUriType());
+    assertTrue(result.isCount());
 
+    assertEquals(1, result.getKeyPredicates().size());
+    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");
@@ -310,7 +332,17 @@ public class UriParserTest extends BaseTest {
     assertEquals("EmployeeName", result.getPropertyPath().get(0).getName());
     assertTrue(result.isValue());
   }
-
+  
+  @Test
+  public void parseEmployeesSimplePropertyValueEncoded() throws Exception {
+    UriInfoImpl result = parse("/Employees('1')/EmployeeName/%24value");
+    assertNull(result.getEntityContainer().getName());
+    assertEquals("Employees", result.getTargetEntitySet().getName());
+    assertEquals(UriType.URI5, result.getUriType());
+    assertEquals("EmployeeName", result.getPropertyPath().get(0).getName());
+    assertTrue(result.isValue());
+  }
+  
   @Test
   public void parseEmployeesComplexProperty() throws Exception {
     UriInfoImpl result = parse("/Employees('1')/Location");
@@ -403,7 +435,15 @@ public class UriParserTest extends BaseTest {
     assertTrue(result.isLinks());
     assertEquals(UriType.URI7B, result.getUriType());
   }
-
+  
+  @Test
+  public void parseNavigationPropertyWithLinksManyEncoded() throws Exception {
+    UriInfoImpl result = parse("/Managers('1')/%24links/nm_Employees");
+    assertEquals("Employees", result.getTargetEntitySet().getName());
+    assertTrue(result.isLinks());
+    assertEquals(UriType.URI7B, result.getUriType());
+  }
+  
   @Test
   public void parseNavigationPropertyWithManagersCount() throws Exception {
     UriInfoImpl result = parse("/Employees('1')/ne_Manager/$count");
@@ -591,7 +631,12 @@ public class UriParserTest extends BaseTest {
     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());
@@ -646,7 +691,16 @@ public class UriParserTest extends BaseTest {
     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());
+    assertEquals("json", result.getFormat());
+    assertEquals(InlineCount.ALLPAGES, result.getInlineCount());
+    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());
@@ -824,7 +878,13 @@ public class UriParserTest extends BaseTest {
     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());
@@ -910,6 +970,15 @@ public class UriParserTest extends BaseTest {
     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());
+    assertEquals(1, result.getExpand().size());
+    assertEquals(1, result.getExpand().get(0).size());
+    assertEquals("Employees", 
result.getExpand().get(0).get(0).getTargetEntitySet().getName());
+    
assertEquals(result.getTargetEntitySet().getEntityType().getProperty("nm_Employees"),
 result.getExpand().get(0)
+        .get(0).getNavigationProperty());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e774ba/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
 
b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
index b57e1e6..0dfec68 100644
--- 
a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
+++ 
b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
@@ -135,6 +135,30 @@ public class BasicBatchTest extends AbstractBasicTest {
   }
 
   @Test
+  public void testBatchUriEncoded() throws Exception {
+    final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + 
"%24batch"));
+    post.setHeader("Content-Type", 
"multipart/mixed;boundary=batch_98c1-8b13-36bb");
+    HttpEntity entity = new StringEntity(REQUEST_PAYLOAD);
+    post.setEntity(entity);
+    HttpResponse response = getHttpClient().execute(post);
+
+    assertNotNull(response);
+    assertEquals(202, response.getStatusLine().getStatusCode());
+    assertEquals("HTTP/1.1", response.getProtocolVersion().toString());
+    assertTrue(response.containsHeader("Content-Length"));
+    assertTrue(response.containsHeader("Content-Type"));
+    assertTrue(response.containsHeader("DataServiceVersion"));
+    
assertTrue(response.getEntity().getContentType().getValue().matches(REG_EX));
+    assertNotNull(response.getEntity().getContent());
+
+    String body = 
StringHelper.inputStreamToString(response.getEntity().getContent(), true);
+    assertTrue(body.contains("Content-Id: mimeHeaderContentId1"));
+    assertTrue(body.contains("Content-Id: requestHeaderContentId1"));
+    assertTrue(body.contains("Content-Id: mimeHeaderContentId2"));
+    assertTrue(body.contains("Content-Id: requestHeaderContentId2"));
+  }
+  
+  @Test
   public void testBatchInvalidContentTypeForPut() throws Exception {
     final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + 
"$batch"));
     post.setHeader("Content-Type", 
"multipart/mixed;boundary=batch_98c1-8b13-36bb");

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e774ba/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/ContentNegotiationDollarFormatTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/ContentNegotiationDollarFormatTest.java
 
b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/ContentNegotiationDollarFormatTest.java
index 5831f82..f8aee5b 100644
--- 
a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/ContentNegotiationDollarFormatTest.java
+++ 
b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/ContentNegotiationDollarFormatTest.java
@@ -91,6 +91,18 @@ public class ContentNegotiationDollarFormatTest extends 
AbstractBasicTest {
   }
 
   @Test
+  public void atomFormatForServiceDocumentEncoded() throws Exception {
+    final HttpResponse response = executeGetRequest("?%24format=atom");
+
+    final String responseEntity = 
StringHelper.httpEntityToString(response.getEntity());
+    assertEquals("Test passed.", responseEntity);
+    assertEquals(HttpStatusCodes.OK.getStatusCode(), 
response.getStatusLine().getStatusCode());
+
+    final Header header = response.getFirstHeader(HttpHeaders.CONTENT_TYPE);
+    assertEquals(HttpContentType.APPLICATION_ATOM_SVC_UTF8, header.getValue());
+  }
+  
+  @Test
   public void formatCustom() throws Exception {
     final HttpResponse response = executeGetRequest("?$format=csv");
 
@@ -102,6 +114,17 @@ public class ContentNegotiationDollarFormatTest extends 
AbstractBasicTest {
   }
 
   @Test
+  public void formatCustomEncoded() throws Exception {
+    final HttpResponse response = executeGetRequest("?%24format=csv");
+
+    assertEquals(HttpStatusCodes.OK.getStatusCode(), 
response.getStatusLine().getStatusCode());
+
+    final Header header = response.getFirstHeader(HttpHeaders.CONTENT_TYPE);
+    assertNotNull(header);
+    assertEquals(CUSTOM_CONTENT_TYPE, header.getValue());
+  }
+  
+  @Test
   public void formatNotAccepted() throws Exception {
     final HttpResponse response = 
executeGetRequest("?$format=csvOrSomethingElse");
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/39e774ba/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/MetadataTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/MetadataTest.java
 
b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/MetadataTest.java
index 2168086..af71ed2 100644
--- 
a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/MetadataTest.java
+++ 
b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/MetadataTest.java
@@ -62,5 +62,13 @@ public class MetadataTest extends AbstractBasicTest {
     final String payload = 
StringHelper.inputStreamToString(response.getEntity().getContent());
     assertEquals("metadata", payload);
   }
+  
+  @Test
+  public void readMetadataEncoded() throws ClientProtocolException, 
IOException, ODataException {
+    final HttpResponse response = executeGetRequest("%24metadata");
+    assertEquals(HttpStatusCodes.OK.getStatusCode(), 
response.getStatusLine().getStatusCode());
 
+    final String payload = 
StringHelper.inputStreamToString(response.getEntity().getContent());
+    assertEquals("metadata", payload);
+  }
 }

Reply via email to