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 2013/09/12 23:16:15 UTC

git commit: Refactored to one content negotiation method

Updated Branches:
  refs/heads/master 6174b7c28 -> b53806707


Refactored to one content negotiation method


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

Branch: refs/heads/master
Commit: b538067071d69d62cfad06a31f8f96693d368f5c
Parents: 6174b7c
Author: Michael Bolz <mi...@apache.org>
Authored: Thu Sep 12 16:40:02 2013 +0200
Committer: Michael Bolz <mi...@apache.org>
Committed: Thu Sep 12 23:11:23 2013 +0200

----------------------------------------------------------------------
 .../olingo/odata2/core/ContentNegotiator.java   | 106 +++++--------------
 .../olingo/odata2/core/ODataRequestHandler.java |  18 ++--
 .../olingo/odata2/core/commons/ContentType.java |   7 +-
 .../odata2/core/ContentNegotiatorTest.java      |  28 +++--
 .../BasicContentNegotiationTest.java            |   4 +-
 5 files changed, 64 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b5380670/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
index d9fe2fe..309a79f 100644
--- a/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
@@ -20,19 +20,15 @@ package org.apache.olingo.odata2.core;
 
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
-import org.apache.olingo.odata2.api.commons.HttpContentType;
-import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
 import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
 import org.apache.olingo.odata2.api.processor.ODataRequest;
 import org.apache.olingo.odata2.api.uri.UriInfo;
 import org.apache.olingo.odata2.core.commons.ContentType;
-import org.apache.olingo.odata2.core.commons.ContentType.ODataFormat;
 import org.apache.olingo.odata2.core.uri.UriInfoImpl;
 import org.apache.olingo.odata2.core.uri.UriType;
 
@@ -45,96 +41,47 @@ public class ContentNegotiator {
   private static final String URI_INFO_FORMAT_XML = "xml";
   static final String DEFAULT_CHARSET = "utf-8";
   
-  private final UriInfoImpl uriInfo;
-  private final ODataRequest odataRequest;
-
-  /**
-   * Creates a {@link ContentNegotiator} for given {@link ODataRequest} and {@link UriInfoImpl}
-   * which then can be used for a <code>accept content type</code> ({@link #doAcceptContentNegotiation(List)})
-   * and <code>response content type</code> ({@link #doResponseContentNegotiation(ContentType)}) negotiation.
-   * 
-   * @param request specific request
-   * @param uriInfo specific uri information
-   * @throws IllegalArgumentException if at least one of both parameters is <code>NULL</code>
-   */
-  public ContentNegotiator(ODataRequest request, UriInfoImpl uriInfo) {
-    if(request == null) {
-      throw new IllegalArgumentException("Parameter ODataRequest MUST NOT be null.");
-    }
-    if(uriInfo == null) {
-      throw new IllegalArgumentException("Parameter UriInfoImpl MUST NOT be null.");
-    }
-    this.odataRequest = request;
-    this.uriInfo = uriInfo;
-  }
-  
   /**
    * Do the content negotiation for <code>accept header value</code> based on 
-   * requested content type (in HTTP accept header from {@link ODataRequest} 
-   * set on {@link ContentNegotiator} creation) in combination with uri information 
-   * (from {@link UriInfo} set on {@link ContentNegotiator} creation)
+   * requested content type (in HTTP accept header from {@link ODataRequest}) 
+   * in combination with uri information from {@link UriInfo}
    * and from given supported content types (via <code>supportedContentTypes</code>).
    * 
+   * @param request specific request
+   * @param uriInfo specific uri information
    * @param supportedContentTypes list of supported content types
    * @return best fitting content type or <code>NULL</code> if content type is not set and for given {@link UriInfo} is ignored
    * @throws ODataException if no supported content type was found
+   * @throws IllegalArgumentException if one of the input parameter is <code>NULL</code>
    */
-  public ContentType doAcceptContentNegotiation(List<String> supportedContentTypes) throws ODataException {
+  public ContentType doContentNegotiation(ODataRequest odataRequest, UriInfoImpl uriInfo, List<String> supportedContentTypes) throws ODataException {
+    validateNotNull(odataRequest, uriInfo, supportedContentTypes);
 
-    if(uriInfo.isCount() || uriInfo.isValue()) {
-      String rawAcceptHeader = odataRequest.getRequestHeaderValue("Accept");
-      if(rawAcceptHeader == null) {
-        return ContentType.WILDCARD;
+    if(uriInfo.isCount()) {
+      return ContentType.TEXT_PLAIN_CS_UTF_8;
+    } else if(uriInfo.isValue()) {
+      if(uriInfo.getUriType() == UriType.URI5 || uriInfo.getUriType() == UriType.URI4) {
+        return ContentType.TEXT_PLAIN_CS_UTF_8;        
       }
-      return ContentType.createAsCustom(rawAcceptHeader);
     } 
-
-    List<String> usedContentTypes = supportedContentTypes;
-    if(ODataHttpMethod.POST.equals(odataRequest.getMethod()) && 
-        (uriInfo.getUriType() == UriType.URI1 || uriInfo.getUriType() == UriType.URI6B)) {
-
-      usedContentTypes = new LinkedList<String>(supportedContentTypes);
-      usedContentTypes.add(0, HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8);
-//      usedContentTypes.add(1, HttpContentType.APPLICATION_ATOM_XML_ENTRY);
-//      usedContentTypes.remove(HttpContentType.APPLICATION_ATOM_XML_FEED);
-      usedContentTypes.remove(HttpContentType.APPLICATION_ATOM_XML_FEED_UTF8);
-    }
     
     if (uriInfo.getFormat() == null) {
-      return doContentNegotiationForAcceptHeader(odataRequest.getAcceptHeaders(), ContentType.create(usedContentTypes));
+      return doContentNegotiationForAcceptHeader(odataRequest.getAcceptHeaders(), ContentType.create(supportedContentTypes));
     } else {
-      return doContentNegotiationForFormat(uriInfo, ContentType.createAsCustom(usedContentTypes));
+      return doContentNegotiationForFormat(uriInfo, ContentType.createAsCustom(supportedContentTypes));
     }
   }
 
-  /**
-   * Do the content negotiation for <code>response content type header value</code> based on 
-   * HTTP request method (from {@link ODataRequest} set on {@link ContentNegotiator} creation) 
-   * in combination with uri information (from {@link UriInfo} set on {@link ContentNegotiator} creation)
-   * and from given <code>accepted content type</code> (via <code>acceptContentType</code> parameter).
-   * 
-   * @param acceptContentType accepted content type for {@link ODataRequest} and {@link UriInfo} combination (which both 
-   *                          were set on {@link ContentNegotiator} creation).
-   * @return best correct response content type based on accepted content type, {@link ODataRequest} and {@link UriInfo} combination 
-   */
-  public ContentType doResponseContentNegotiation(ContentType acceptContentType) {
-    UriType uriType = uriInfo.getUriType();
-    
-    if(uriInfo.isCount() || uriInfo.isValue()) {
-      return ContentType.TEXT_PLAIN_CS_UTF_8;
-    } else if(acceptContentType != null && acceptContentType.getODataFormat() == ODataFormat.ATOM) {
-      if(uriType == UriType.URI1 || uriType == UriType.URI6B) {
-        if(ODataHttpMethod.GET.equals(odataRequest.getMethod())) {
-          return ContentType.create(acceptContentType, ContentType.PARAMETER_TYPE, "feed");
-        } else {
-          return ContentType.create(acceptContentType, ContentType.PARAMETER_TYPE, "entry");          
-        }
-      } else if(uriType == UriType.URI2 || uriType == UriType.URI6A) {
-        return ContentType.create(acceptContentType, ContentType.PARAMETER_TYPE, "entry");
-      }
-    } 
-
-    return acceptContentType;
+  private void validateNotNull(ODataRequest odataRequest, UriInfoImpl uriInfo, List<String> supportedContentTypes) {
+    if(uriInfo == null) {
+      throw new IllegalArgumentException("Parameter uriInfo MUST NOT be null.");
+    }
+    if(odataRequest == null) {
+      throw new IllegalArgumentException("Parameter odataRequest MUST NOT be null.");
+    }
+    if(supportedContentTypes == null) {
+      throw new IllegalArgumentException("Parameter supportedContentTypes MUST NOT be null.");
+    }
   }
 
 
@@ -173,8 +120,11 @@ public class ContentNegotiator {
       if (uriInfo.getUriType() == UriType.URI0) {
         // special handling for serviceDocument uris (UriType.URI0)
         return ContentType.APPLICATION_ATOM_SVC;
+      } else if(uriInfo.getUriType() == UriType.URI1) {
+        return ContentType.APPLICATION_ATOM_XML_FEED;        
+      } else if(uriInfo.getUriType()==UriType.URI2) {
+        return ContentType.APPLICATION_ATOM_XML_ENTRY;
       }
-      return ContentType.APPLICATION_ATOM_XML;
     } else if (URI_INFO_FORMAT_JSON.equals(format)) {
       return ContentType.APPLICATION_JSON;
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b5380670/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
index 9bbe1b2..eed7a12 100644
--- a/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
@@ -107,8 +107,8 @@ public class ODataRequestHandler {
         checkRequestContentType(uriInfo, request.getContentType());
       }
 
-      ContentNegotiator contentNegotiator = new ContentNegotiator(request, uriInfo);
-      final ContentType acceptContentType = contentNegotiator.doAcceptContentNegotiation(getSupportedContentTypes(uriInfo));
+      List<String> supportedContentTypes = getSupportedContentTypes(uriInfo, method);
+      ContentType acceptContentType = new ContentNegotiator().doContentNegotiation(request, uriInfo, supportedContentTypes);
 
       timingHandle2 = context.startRuntimeMeasurement("Dispatcher", "dispatch");
       odataResponse = dispatcher.dispatch(method, uriInfo, request.getBody(), request.getContentType(), acceptContentType.toContentTypeString());
@@ -120,8 +120,7 @@ public class ODataRequestHandler {
         extendedResponse = extendedResponse.header(ODataHttpHeaders.DATASERVICEVERSION, serverDataServiceVersion);
       }
       if(!odataResponse.containsHeader(HttpHeaders.CONTENT_TYPE)) {
-        ContentType responseContentType = contentNegotiator.doResponseContentNegotiation(acceptContentType);
-        extendedResponse.header(HttpHeaders.CONTENT_TYPE, responseContentType.toContentTypeString());
+        extendedResponse.header(HttpHeaders.CONTENT_TYPE, acceptContentType.toContentTypeString());
       }
       
       final UriType uriType = uriInfo.getUriType();
@@ -408,8 +407,15 @@ public class ODataRequestHandler {
     return property.getType() == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance() ? Arrays.asList(property.getMimeType() == null ? ContentType.WILDCARD : ContentType.create(property.getMimeType())) : Arrays.asList(ContentType.TEXT_PLAIN, ContentType.TEXT_PLAIN_CS_UTF_8);
   }
 
-  private List<String> getSupportedContentTypes(final UriInfoImpl uriInfo) throws ODataException {
-    return service.getSupportedContentTypes(Dispatcher.mapUriTypeToProcessorFeature(uriInfo));
+  private List<String> getSupportedContentTypes(final UriInfoImpl uriInfo, ODataHttpMethod method) throws ODataException {
+    Class<? extends ODataProcessor> processorFeature = Dispatcher.mapUriTypeToProcessorFeature(uriInfo);
+    if (ODataHttpMethod.POST.equals(method)) {
+      UriType uriType = uriInfo.getUriType();
+      if (uriType == UriType.URI1 || uriType == UriType.URI6B) {
+        processorFeature = EntityProcessor.class;
+      }
+    }
+    return service.getSupportedContentTypes(processorFeature);
   }
 
   private List<ContentType> getSupportedContentTypes(final Class<? extends ODataProcessor> processorFeature) throws ODataException {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b5380670/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/ContentType.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/ContentType.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/ContentType.java
index 80ab262..037f70c 100644
--- a/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/ContentType.java
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/ContentType.java
@@ -168,8 +168,11 @@ public class ContentType {
     if (type == null || type.isEmpty()) {
       return MEDIA_TYPE_WILDCARD;
     }
-    if (type.charAt(0) == WHITESPACE_CHAR || type.charAt(type.length() - 1) == WHITESPACE_CHAR) {
-      throw new IllegalArgumentException("Illegal leading/trailing whitespace found for type '" + type + "'.");
+    int len = type.length();
+    for (int i = 0; i < len; i++) {
+      if (type.charAt(i) == WHITESPACE_CHAR) {
+        throw new IllegalArgumentException("Illegal whitespace found for type '" + type + "'.");
+      }
     }
     return type;
   }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b5380670/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
index a77f4f9..475ffb6 100644
--- a/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
@@ -42,29 +42,35 @@ import org.mockito.Mockito;
 public class ContentNegotiatorTest {
   
   private void negotiateContentType(final List<ContentType> contentTypes, final List<ContentType> supportedTypes, final String expected) throws ODataException {
-    UriInfoImpl uriInfo = Mockito.mock(UriInfoImpl.class);
-    ODataRequest request = Mockito.mock(ODataRequest.class);
-    final ContentType contentType = new ContentNegotiator(request, uriInfo).contentNegotiation(contentTypes, supportedTypes);
+    final ContentType contentType = new ContentNegotiator().contentNegotiation(contentTypes, supportedTypes);
     assertEquals(expected, contentType.toContentTypeString());
   }
 
   @Test(expected=IllegalArgumentException.class)
-  public void invalidContentNegotiatorCreation() {
-    final ContentNegotiator contentType = new ContentNegotiator(null, null);
+  public void invalidContentNegotiatorCreation() throws ODataException {
+    final ContentType contentType = new ContentNegotiator().doContentNegotiation(null, null, null);
     assertNull(contentType);
   }
 
   @Test(expected=IllegalArgumentException.class)
-  public void invalidContentNegotiatorCreationNullRequest() {
+  public void invalidContentNegotiatorCreationNullRequest() throws ODataException {
     UriInfoImpl uriInfo = Mockito.mock(UriInfoImpl.class);
-    final ContentNegotiator contentType = new ContentNegotiator(null, uriInfo);
+    final ContentType contentType = new ContentNegotiator().doContentNegotiation(null, uriInfo, new ArrayList<String>());
+    assertNull(contentType);
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void invalidContentNegotiatorCreationNullUri() throws ODataException {
+    ODataRequest request = Mockito.mock(ODataRequest.class);
+    final ContentType contentType = new ContentNegotiator().doContentNegotiation(request, null, new ArrayList<String>());
     assertNull(contentType);
   }
 
   @Test(expected=IllegalArgumentException.class)
-  public void invalidContentNegotiatorCreationNullUri() {
+  public void invalidContentNegotiatorCreationNullSupported() throws ODataException {
     ODataRequest request = Mockito.mock(ODataRequest.class);
-    final ContentNegotiator contentType = new ContentNegotiator(request, null);
+    UriInfoImpl uriInfo = Mockito.mock(UriInfoImpl.class);
+    final ContentType contentType = new ContentNegotiator().doContentNegotiation(request, uriInfo, null);
     assertNull(contentType);
   }
 
@@ -195,8 +201,8 @@ public class ContentNegotiatorTest {
     
     
     // perform
-    ContentNegotiator negotiator = new ContentNegotiator(request, uriInfo);
-    String negotiatedContentType = negotiator.doAcceptContentNegotiation(supportedContentTypes).toContentTypeString();
+    ContentNegotiator negotiator = new ContentNegotiator();
+    String negotiatedContentType = negotiator.doContentNegotiation(request, uriInfo, supportedContentTypes).toContentTypeString();
 
     // verify
     assertEquals(supportedType, negotiatedContentType);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b5380670/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/BasicContentNegotiationTest.java
----------------------------------------------------------------------
diff --git a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/BasicContentNegotiationTest.java b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/BasicContentNegotiationTest.java
index 529693c..4ce1eea 100644
--- a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/BasicContentNegotiationTest.java
+++ b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/BasicContentNegotiationTest.java
@@ -19,7 +19,7 @@
 package org.apache.olingo.odata2.fit.ref.contentnegotiation;
 
 import static org.apache.olingo.odata2.api.commons.HttpContentType.APPLICATION_ATOM_XML;
-import static org.apache.olingo.odata2.api.commons.HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8;
+import static org.apache.olingo.odata2.api.commons.HttpContentType.APPLICATION_ATOM_XML_UTF8;
 import static org.apache.olingo.odata2.api.commons.HttpContentType.APPLICATION_JSON;
 import static org.apache.olingo.odata2.api.commons.HttpContentType.APPLICATION_JSON_UTF8;
 import static org.apache.olingo.odata2.api.commons.HttpContentType.APPLICATION_XML;
@@ -52,7 +52,7 @@ public class BasicContentNegotiationTest extends AbstractContentNegotiationTest
   
   @Test
   public void acceptHeaderAppAtomXml() throws Exception {
-    performRequestAndValidateResponseForAcceptHeader("Rooms('1')", APPLICATION_ATOM_XML, APPLICATION_ATOM_XML_ENTRY_UTF8);
+    performRequestAndValidateResponseForAcceptHeader("Rooms('1')", APPLICATION_ATOM_XML, APPLICATION_ATOM_XML_UTF8);
   }
 
   @Test