You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2014/06/27 17:39:05 UTC

[6/6] git commit: [OLINGO-328] refactor content negotiation

[OLINGO-328] refactor content negotiation


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

Branch: refs/heads/olingo-328
Commit: acc12ff742cca555dd2732f78582e5cac3056a02
Parents: 0ffc26d
Author: Stephan Klevenz <st...@sap.com>
Authored: Fri Jun 27 17:33:20 2014 +0200
Committer: Stephan Klevenz <st...@sap.com>
Committed: Fri Jun 27 17:33:20 2014 +0200

----------------------------------------------------------------------
 lib/server-api/pom.xml                          |   5 +
 .../olingo/server/api/ODataHttpHandler.java     |   2 -
 .../apache/olingo/server/api/ODataRequest.java  |   2 +-
 .../api/processor/CustomContentTypeSupport.java |  28 ++
 .../server/api/processor/DefaultProcessor.java  |   4 +-
 .../api/processor/FormatContentTypeMapping.java |  53 +++
 .../server/api/processor/MetadataProcessor.java |   2 +-
 .../olingo/server/api/processor/Processor.java  |   2 -
 .../processor/SupportCustomContentTypes.java    |  27 --
 .../olingo/server/api/ODataRequestTest.java     |  66 ++++
 .../olingo/server/core/ContentNegotiator.java   | 132 ++++++++
 .../apache/olingo/server/core/ODataHandler.java |  63 +++-
 .../server/core/ODataHttpHandlerImpl.java       |   2 +-
 .../server/core/ContentNegotiatorTest.java      | 327 +++++++++++++++++++
 .../server/core/ODataHttpHandlerImplTest.java   |   2 +
 .../olingo/server/api/ODataRequestTest.java     |  66 ----
 .../server/core/ContentNegotiationTest.java     | 201 ------------
 17 files changed, 666 insertions(+), 318 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-api/pom.xml b/lib/server-api/pom.xml
index 3d8fa87..6af6456 100644
--- a/lib/server-api/pom.xml
+++ b/lib/server-api/pom.xml
@@ -46,6 +46,11 @@
       <version>2.5</version>
       <scope>provided</scope>
     </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
   </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
index e9d9caa..8372f80 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
@@ -18,8 +18,6 @@
  */
 package org.apache.olingo.server.api;
 
-import java.util.List;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
index 5be8b96..45cf503 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
@@ -54,7 +54,7 @@ public class ODataRequest {
     String key = name.toUpperCase();
     if (headers.containsKey(key)) {
       List<String> oldValues = headers.get(key);
-      
+
       List<String> newValues = new ArrayList<String>();
       newValues.addAll(oldValues);
       newValues.addAll(values);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CustomContentTypeSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CustomContentTypeSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CustomContentTypeSupport.java
new file mode 100644
index 0000000..75a57b1
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CustomContentTypeSupport.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.processor;
+
+import java.util.List;
+
+public interface CustomContentTypeSupport {
+
+  public List<FormatContentTypeMapping> modifySupportedContentTypes(
+      List<FormatContentTypeMapping> supportedContentTypes, Class<? extends Processor> processorClass);
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
index 4d1a94d..3ce2570 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
@@ -19,8 +19,6 @@
 package org.apache.olingo.server.api.processor;
 
 import java.io.InputStream;
-import java.util.Collections;
-import java.util.List;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.format.ODataFormat;
@@ -33,7 +31,7 @@ import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.api.uri.UriInfo;
 
 public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProcessor {
-  
+
   private OData odata;
   private Edm edm;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/FormatContentTypeMapping.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/FormatContentTypeMapping.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/FormatContentTypeMapping.java
new file mode 100644
index 0000000..2fe69b6
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/FormatContentTypeMapping.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.processor;
+
+public class FormatContentTypeMapping {
+
+  private String formatAlias;
+  private String contentType;
+
+  public FormatContentTypeMapping(String formatAlias, String contentType) {
+    super();
+    this.formatAlias = formatAlias;
+    this.contentType = contentType;
+  }
+
+  public String getFormatAlias() {
+    return formatAlias;
+  }
+
+  public String getContentType() {
+    return contentType;
+  }
+
+  public void setFormatAlias(String formatAlias) {
+    this.formatAlias = formatAlias;
+  }
+
+  public void setContentType(String contentType) {
+    this.contentType = contentType;
+  }
+
+  @Override
+  public String toString() {
+    return "('" + formatAlias + "', '" + contentType + "')";
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MetadataProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MetadataProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MetadataProcessor.java
index 64d5c16..89f8e53 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MetadataProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MetadataProcessor.java
@@ -22,7 +22,7 @@ import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.uri.UriInfo;
 
-public interface MetadataProcessor extends Processor{
+public interface MetadataProcessor extends Processor {
 
   void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/Processor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/Processor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/Processor.java
index ef2b8a0..014fba7 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/Processor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/Processor.java
@@ -18,8 +18,6 @@
  */
 package org.apache.olingo.server.api.processor;
 
-import java.util.List;
-
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.server.api.OData;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/SupportCustomContentTypes.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/SupportCustomContentTypes.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/SupportCustomContentTypes.java
deleted file mode 100644
index 0a032e1..0000000
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/SupportCustomContentTypes.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.server.api.processor;
-
-import java.util.List;
-
-public interface SupportCustomContentTypes {
-
-  public List<String> getSupportedContentTypes(Class<? extends Processor> processorClass);
-  
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-api/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java b/lib/server-api/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java
new file mode 100644
index 0000000..d740731
--- /dev/null
+++ b/lib/server-api/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class ODataRequestTest {
+
+  @Test
+  public void testHeader() {
+    ODataRequest r = new ODataRequest();
+
+    r.addHeader("aa", Arrays.asList("cc"));
+
+    assertEquals("cc", r.getHeader("aa").get(0));
+    assertEquals("cc", r.getHeader("aA").get(0));
+    assertEquals("cc", r.getHeader("AA").get(0));
+
+  }
+
+  @Test
+  public void testHeader2() {
+    ODataRequest r = new ODataRequest();
+    r.addHeader("AA", Arrays.asList("dd"));
+
+    assertEquals("dd", r.getHeader("aa").get(0));
+    assertEquals("dd", r.getHeader("aA").get(0));
+    assertEquals("dd", r.getHeader("AA").get(0));
+  }
+
+  @Test
+  public void testMultiValueHeader() {
+    ODataRequest r = new ODataRequest();
+
+    r.addHeader("aa", Arrays.asList("a", "b"));
+
+    assertEquals("a", r.getHeader("aa").get(0));
+    assertEquals("b", r.getHeader("aA").get(1));
+
+    r.addHeader("Aa", Arrays.asList("c"));
+
+    assertEquals("a", r.getHeader("aa").get(0));
+    assertEquals("b", r.getHeader("aA").get(1));
+    assertEquals("c", r.getHeader("aA").get(2));
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
new file mode 100644
index 0000000..baf6d7b
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
+import org.apache.olingo.server.api.processor.FormatContentTypeMapping;
+import org.apache.olingo.server.api.processor.MetadataProcessor;
+import org.apache.olingo.server.api.processor.Processor;
+import org.apache.olingo.server.api.uri.queryoption.FormatOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ContentNegotiator {
+
+  private final static Logger LOG = LoggerFactory.getLogger(ContentNegotiator.class);
+
+  private List<FormatContentTypeMapping> getDefaultSupportedContentTypes(Class<? extends Processor> processorClass) {
+    List<FormatContentTypeMapping> defaults = new ArrayList<FormatContentTypeMapping>();
+
+    if (processorClass == MetadataProcessor.class) {
+      defaults.add(new FormatContentTypeMapping("xml", ContentType.APPLICATION_XML.toContentTypeString()));
+    }
+    else {
+      defaults.add(new FormatContentTypeMapping("json", ContentType.APPLICATION_JSON.toContentTypeString()));
+    }
+
+    return defaults;
+  }
+
+  public List<FormatContentTypeMapping> getSupportedContentTypes(Processor processor,
+      Class<? extends Processor> processorClass) {
+
+    List<FormatContentTypeMapping> supportedContentTypes = getDefaultSupportedContentTypes(processorClass);
+
+    if (processor instanceof CustomContentTypeSupport) {
+      supportedContentTypes =
+          ((CustomContentTypeSupport) processor).modifySupportedContentTypes(supportedContentTypes, processorClass);
+    }
+
+    return supportedContentTypes;
+  }
+
+  public String doContentNegotiation(FormatOption formatOption, ODataRequest request,
+      List<FormatContentTypeMapping> supportedContentTypes) {
+    String requestedContentType = null;
+
+    List<String> acceptHeaderValues = request.getHeader(HttpHeader.ACCEPT);
+
+    boolean supported = false;
+
+    if (formatOption != null) {
+
+      if ("json".equalsIgnoreCase(formatOption.getText())) {
+        requestedContentType = HttpContentType.APPLICATION_JSON;
+        for (FormatContentTypeMapping entry : supportedContentTypes) {
+          if (requestedContentType.equalsIgnoreCase(entry.getContentType())){
+            supported = true;
+            break;
+          }
+        }
+      } else {
+        requestedContentType = formatOption.getText();
+        for (FormatContentTypeMapping entry : supportedContentTypes) {
+          if (requestedContentType.equalsIgnoreCase(entry.getFormatAlias())){
+            supported = true;
+            break;
+          }
+        }
+      }
+    } else if (acceptHeaderValues != null) {
+      List<String> acceptedContentTypes = new ArrayList<String>();
+
+//      for (String acceptHeaderValue : acceptHeaderValues) {
+//        acceptedContentTypes.addAll(parseAcceptHeader(acceptHeaderValue));
+//      }
+
+      for (String acceptedContentType : acceptedContentTypes) {
+//        if (isContentTypeSupported(acceptedContentType, supportedContentTypes)) {
+//          requestedContentType = acceptedContentType;
+//        }
+      }
+
+      if (requestedContentType == null) {
+        throw new RuntimeException("unsupported accept content type: " + acceptedContentTypes + " != "
+            + supportedContentTypes);
+      }
+
+      requestedContentType = null;
+    } else {
+      requestedContentType = HttpContentType.APPLICATION_JSON;
+      for (FormatContentTypeMapping entry : supportedContentTypes) {
+        if (requestedContentType.equalsIgnoreCase(entry.getContentType())){
+          supported = true;
+          break;
+        }
+      }
+    }
+
+    if (!supported) {
+      throw new RuntimeException("unsupported accept content type: " + requestedContentType + " != "
+          + supportedContentTypes);
+    }
+
+    LOG.debug("requested content type: " + requestedContentType);
+
+    return requestedContentType;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index f7248c3..28bc559 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -18,6 +18,10 @@
  */
 package org.apache.olingo.server.core;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -25,6 +29,8 @@ import java.util.Map;
 import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.format.AcceptType;
+import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.http.HttpContentType;
 import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpMethod;
@@ -32,20 +38,27 @@ import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.processor.CollectionProcessor;
+import org.apache.olingo.server.api.processor.FormatContentTypeMapping;
 import org.apache.olingo.server.api.processor.DefaultProcessor;
 import org.apache.olingo.server.api.processor.EntityProcessor;
 import org.apache.olingo.server.api.processor.MetadataProcessor;
 import org.apache.olingo.server.api.processor.Processor;
 import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
+import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
 import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.FormatOption;
 import org.apache.olingo.server.core.uri.parser.Parser;
 import org.apache.olingo.server.core.uri.validator.UriValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ODataHandler {
 
+  private final static Logger LOG = LoggerFactory.getLogger(ODataHandler.class);
+
   private final OData odata;
   private final Edm edm;
   private Map<Class<? extends Processor>, Processor> processors = new HashMap<Class<? extends Processor>, Processor>();
@@ -72,12 +85,17 @@ public class ODataHandler {
       UriValidator validator = new UriValidator();
       validator.validate(uriInfo, request.getMethod());
 
-      String requestedContentType = doContentNegotiation();
+      String requestedContentType = null;
+      List<FormatContentTypeMapping> supportedContentTypes = null;
 
       switch (uriInfo.getKind()) {
       case metadata:
         MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
-        mp.readMetadata(request, response, uriInfo, HttpContentType.APPLICATION_XML);
+
+        /* TODO content negotiation */
+        requestedContentType = ContentType.APPLICATION_XML.toContentTypeString();
+
+        mp.readMetadata(request, response, uriInfo, requestedContentType);
         break;
       case service:
         if ("".equals(request.getRawODataPath())) {
@@ -85,11 +103,15 @@ public class ODataHandler {
           rdp.redirect(request, response);
         } else {
           ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class);
+
+          /* TODO content negotiation */
+          requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
+
           sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
         }
         break;
       case resource:
-        handleResourceDispatching(request, response, uriInfo, requestedContentType);
+        handleResourceDispatching(request, response, uriInfo);
         break;
       default:
         throw new ODataRuntimeException("not implemented");
@@ -102,27 +124,32 @@ public class ODataHandler {
     }
   }
 
-  private String doContentNegotiation() {
-    // TODO: Content Negotiation
-    return HttpContentType.APPLICATION_JSON;
-  }
-
-  private void handleResourceDispatching(final ODataRequest request, ODataResponse response, UriInfo uriInfo,
-      String requestedContentType) {
+  private void handleResourceDispatching(final ODataRequest request, ODataResponse response, UriInfo uriInfo) {
     int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
     UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
+    String requestedContentType = null;
+    List<String> supportedContentTypes = null;
+
     switch (lastPathSegment.getKind()) {
     case entitySet:
       if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
         if (request.getMethod().equals(HttpMethod.GET)) {
-          CollectionProcessor esp = selectProcessor(CollectionProcessor.class);
-          esp.readCollection(request, response, uriInfo, requestedContentType);
+          CollectionProcessor cp = selectProcessor(CollectionProcessor.class);
+
+          /* TODO content negotiation */
+          requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
+
+          cp.readCollection(request, response, uriInfo, requestedContentType);
         } else {
           throw new ODataRuntimeException("not implemented");
         }
       } else {
         if (request.getMethod().equals(HttpMethod.GET)) {
           EntityProcessor ep = selectProcessor(EntityProcessor.class);
+
+          /* TODO content negotiation */
+          requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
+
           ep.readEntity(request, response, uriInfo, requestedContentType);
         } else {
           throw new ODataRuntimeException("not implemented");
@@ -132,14 +159,22 @@ public class ODataHandler {
     case navigationProperty:
       if (((UriResourceNavigation) lastPathSegment).isCollection()) {
         if (request.getMethod().equals(HttpMethod.GET)) {
-          CollectionProcessor esp = selectProcessor(CollectionProcessor.class);
-          esp.readCollection(request, response, uriInfo, requestedContentType);
+          CollectionProcessor cp = selectProcessor(CollectionProcessor.class);
+
+          /* TODO content negotiation */
+          requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
+
+          cp.readCollection(request, response, uriInfo, requestedContentType);
         } else {
           throw new ODataRuntimeException("not implemented");
         }
       } else {
         if (request.getMethod().equals(HttpMethod.GET)) {
           EntityProcessor ep = selectProcessor(EntityProcessor.class);
+
+          /* TODO content negotiation */
+          requestedContentType = ContentType.APPLICATION_JSON.toContentTypeString();
+
           ep.readEntity(request, response, uriInfo, requestedContentType);
         } else {
           throw new ODataRuntimeException("not implemented");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 36ef5c5..1b15995 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -182,7 +182,7 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
     odRequest.setRawServiceResolutionUri(rawServiceResolutionUri);
   }
 
-  private void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) {
+  static void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) {
     for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
       String headerName = (String) headerNames.nextElement();
       List<String> headerValues = new ArrayList<String>();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
new file mode 100644
index 0000000..ba5802b
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core;
+
+import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.processor.CollectionProcessor;
+import org.apache.olingo.server.api.processor.CustomContentTypeSupport;
+import org.apache.olingo.server.api.processor.FormatContentTypeMapping;
+import org.apache.olingo.server.api.processor.MetadataProcessor;
+import org.apache.olingo.server.api.processor.Processor;
+import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.queryoption.FormatOption;
+import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ContentNegotiatorTest {
+
+  static final private String ACCEPT_CASE_JSON = "application/json;odata=verbose;q=0.2";
+  static final private String ACCEPT_CASE_XML = "application/xml";
+  static final private String ACCEPT_CASE_TEXT = "text/plain;q=0.5";
+  static final private String ACCEPT_CASE_MULTI = "text/plain;q=0.5,application/aaa;q=0.4";
+
+  //@formatter:off (Eclipse formatter)
+  //CHECKSTYLE:OFF (Maven checkstyle)
+
+  String[][] casesServiceDocument = {
+      /* expected               $format           accept                 alias        ct mapping    */
+      { "application/json",     null,             null,                  null         ,null             },
+      { "application/json",     "json",           null,                  null         ,null             },
+      { "application/json",     "json",           "application/json",    null         ,null             },
+      { "a",                    "a",              null,                  "a"          ,"a/a"            },
+
+//      { "application/json",     null,             "application/json",    null         ,null             },
+//      { "application/json",     null,             ACCEPT_CASE_JSON,      null         ,null             },
+//      { "application/json",     null,             "*/*",                 null         ,null             },
+//      { "a/a",                  "a",               null,                 "a, b"       ,"a/a,b/b"        },
+//      { "a",                    null,             "*/*",                 "a, b"       ,null             },
+//      { "a",                    "a",              "*/*",                 "a, b"       ,null             },
+  };                                                                                          
+
+  String[][] casesMetadata = {                                                                 
+      /* expected               $format           accept                 alias        ct mapping    */
+      { "application/xml",      null,             null,                  null         ,null             },
+      { "application/xml",      "xml",            null,                  null         ,null             },
+      { "application/xml",      null,             "application/xml",     null         ,null             },
+      { "application/xml",      "xml",            "application/xml",     null         ,null             },
+      { "application/xml",      null,             ACCEPT_CASE_XML,       null         ,null             },
+      { "application/xml",      null,             "*/*",                 null         ,null             },
+      { "a",                    "a",              null,                  "a, b"       ,null             },
+      { "a",                    "a",              null,                  "a, b"       ,null             },
+      { "a",                    null,             "*/*",                 "a, b"       ,null             },
+      { "a",                    "a",              "*/*",                 "a, b"       ,null             },
+  };
+
+//  String[][] casesEntitySet = {                                                               
+//      /* expected               $format           accept                 supported    $formatmapping    */
+//      { "application/json",     null,             null,                  null         ,null             },
+//      { "application/json",     "json",           null,                  null         ,null             },
+//      { "application/json",     "json",           "application/json",    null         ,null             },
+//      { "application/json",     null,             "application/json",    null         ,null             },
+//      { "application/json",     null,             ACCEPT_CASE_JSON,      null         ,null             },
+//      { "application/json",     null,             "*/*",                 null         ,null             },
+//      { "a",                    "a",              null,                  "a, b"       ,null             },
+//      { "a",                    null,             "*/*",                 "a, b"       ,null             },
+//      { "a",                    "a",              "*/*",                 "a, b"       ,null             },
+//  };  
+  //CHECKSTYLE:ON
+  //@formatter:on
+
+  private final static Logger LOG = LoggerFactory.getLogger(ContentNegotiatorTest.class);
+
+  @Test
+  public void testServiceDocumentSingleCase() {
+    String[] useCase = { "application/json", null, null, null, null };
+
+    testContentNegotiation(useCase, ServiceDocumentProcessor.class);
+  }
+
+  @Test
+  public void testServiceDocumentDefault() {
+    for (String[] useCase : casesServiceDocument) {
+      testContentNegotiation(useCase, ServiceDocumentProcessor.class);
+    }
+  }
+
+  public void testContentNegotiation(String[] useCase, Class<ServiceDocumentProcessor> processorClass) {
+
+    LOG.debug(Arrays.asList(useCase).toString());
+
+    ODataRequest request = new ODataRequest();
+    request.setMethod(HttpMethod.GET);
+    request.setRawODataPath("/" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
+
+    ContentNegotiator cn = new ContentNegotiator();
+
+    ProcessorStub p = new ProcessorStub(createCustomContentTypeMapping(useCase[3], useCase[4]));
+
+    List<FormatContentTypeMapping> supportedContentTypes =
+        cn.getSupportedContentTypes(p, processorClass);
+
+    FormatOption fo = null;
+    if (useCase[1] != null) {
+      fo = mock(FormatOption.class);
+      when(fo.getText()).thenReturn(useCase[1]);
+    }
+
+    String requestedContentType = cn.doContentNegotiation(fo, request, supportedContentTypes);
+
+    assertNotNull(requestedContentType);
+    assertEquals(useCase[0], requestedContentType);
+  }
+
+  private List<FormatContentTypeMapping> createCustomContentTypeMapping(String formatString, String contentTypeString) {
+    List<FormatContentTypeMapping> map = null;
+
+    assertTrue(!(formatString == null ^ contentTypeString == null));
+
+    if (formatString != null) {
+      String[] formats = formatString.split(",");
+      String[] contentTypes = contentTypeString.split(",");
+
+      assertEquals(formats.length, contentTypes.length);
+
+      map = new ArrayList<FormatContentTypeMapping>();
+      for (int i = 0; i < formats.length; i++) {
+        map.add(new FormatContentTypeMapping(formats[i], contentTypes[i]));
+      }
+    }
+
+    return map;
+  }
+
+  @Test
+  @Ignore
+  public void testMetadataDefault() {
+
+    for (String[] useCase : casesMetadata) {
+      ODataRequest request = new ODataRequest();
+      request.setMethod(HttpMethod.GET);
+      request.setRawODataPath("/$metadata" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
+
+//      ODataResponse response = callHandler(useCase, request);
+//
+//      assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
+    }
+  }
+
+//  @Test
+//  public void testEntitySet() {
+//
+//    for (String[] useCase : casesEntitySet) {
+//      ODataRequest request = new ODataRequest();
+//      request.setMethod(HttpMethod.GET);
+//      request.setRawODataPath("/ESAllPrim" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
+//
+//      ODataResponse response = callHandler(useCase, request, new CollectionProcessorStub());
+//
+//      assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
+//    }
+//  }
+
+//  private ODataResponse callHandler(String[] useCase, ODataRequest request,
+//      Processor defaultProcessor) {
+//    ODataHandler handler = createHandler();
+//
+//    if (useCase[2] != null) {
+//      request.addHeader(HttpHeader.ACCEPT, Arrays.asList(useCase[2]));
+//    }
+//
+//    if (useCase[3] != null) {
+//        String[] aliase = useCase[3].split(",");
+//        String[] mappings = useCase[4].split(",");
+//
+//        FormatContentTypeMapping[] formatCTMap = new FormatContentTypeMapping[aliase.length];
+//        
+//        for(int i=0; i< formatCTMap.length; i++) {
+//          formatCTMap[i] = new FormatContentTypeMapping(aliase[i], mappings[i]);
+//        }
+//    
+//
+//      ProcessorStub stub = new ProcessorStub(formatCTMap);
+//      handler.register(stub);
+//    } else {
+//      if (defaultProcessor != null) {
+//        handler.register(defaultProcessor);
+//      }
+//    }
+//
+//    ODataResponse response = handler.process(request);
+//    return response;
+//  }
+
+//  ODataResponse callHandler(String[] useCase, ODataRequest request) {
+//    return callHandler(useCase, request, null);
+//  }
+
+  private class CollectionProcessorStub implements CollectionProcessor {
+
+    @Override
+    public void init(OData odata, Edm edm) {}
+
+    @Override
+    public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+      response.setHeader(HttpHeader.CONTENT_TYPE, format);
+    }
+  }
+
+  @Test
+  public void testDefaultSupportedContentTypesServiceDocument() {
+    ContentNegotiator cn = new ContentNegotiator();
+
+    ProcessorStub p = new ProcessorStub(null);
+
+    List<FormatContentTypeMapping> supportedContentTypes =
+        cn.getSupportedContentTypes(p, ServiceDocumentProcessor.class);
+
+    assertNotNull(supportedContentTypes);
+    assertEquals(1, supportedContentTypes.size());
+    assertEquals("json", supportedContentTypes.get(0).getFormatAlias());
+    assertEquals("application/json", supportedContentTypes.get(0).getContentType());
+  }
+
+  @Test
+  public void testDefaultSupportedContentTypesMetadata() {
+    ContentNegotiator cn = new ContentNegotiator();
+
+    ProcessorStub p = new ProcessorStub(null);
+
+    List<FormatContentTypeMapping> supportedContentTypes = cn.getSupportedContentTypes(p, MetadataProcessor.class);
+
+    assertNotNull(supportedContentTypes);
+    assertEquals(1, supportedContentTypes.size());
+    assertEquals("xml", supportedContentTypes.get(0).getFormatAlias());
+    assertEquals("application/xml", supportedContentTypes.get(0).getContentType());
+  }
+
+  @Test
+  public void testCustomSupportedContentTypesServiceDocument() {
+    ContentNegotiator cn = new ContentNegotiator();
+
+    ProcessorStub p = new ProcessorStub(Arrays.asList(new FormatContentTypeMapping("a", "a/a")));
+
+    List<FormatContentTypeMapping> supportedContentTypes =
+        cn.getSupportedContentTypes(p, ServiceDocumentProcessor.class);
+
+    assertNotNull(supportedContentTypes);
+    assertEquals(2, supportedContentTypes.size());
+    assertEquals("json", supportedContentTypes.get(0).getFormatAlias());
+    assertEquals("application/json", supportedContentTypes.get(0).getContentType());
+    assertEquals("a", supportedContentTypes.get(1).getFormatAlias());
+    assertEquals("a/a", supportedContentTypes.get(1).getContentType());
+  }
+
+  private class ProcessorStub implements ServiceDocumentProcessor, MetadataProcessor,
+      CollectionProcessor,
+      CustomContentTypeSupport {
+
+    List<FormatContentTypeMapping> customMapping;
+
+    ProcessorStub(List<FormatContentTypeMapping> mapping) {
+      this.customMapping = mapping;
+    }
+
+    @Override
+    public void init(OData odata, Edm edm) {}
+
+    @Override
+    public List<FormatContentTypeMapping> modifySupportedContentTypes(
+        List<FormatContentTypeMapping> supportedContentTypes,
+        Class<? extends Processor> processorClass) {
+      if (customMapping != null) {
+        supportedContentTypes.addAll(customMapping);
+      }
+      return supportedContentTypes;
+    }
+
+    @Override
+    public void readServiceDocument(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+      response.setHeader(HttpHeader.CONTENT_TYPE, format);
+    }
+
+    @Override
+    public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+      response.setHeader(HttpHeader.CONTENT_TYPE, format);
+    }
+
+    @Override
+    public void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+      response.setHeader(HttpHeader.CONTENT_TYPE, format);
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
index faa82e3..3715076 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.Arrays;
+
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.olingo.commons.api.ODataRuntimeException;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-test/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java
deleted file mode 100644
index d740731..0000000
--- a/lib/server-test/src/test/java/org/apache/olingo/server/api/ODataRequestTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.server.api;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-
-import org.junit.Test;
-
-public class ODataRequestTest {
-
-  @Test
-  public void testHeader() {
-    ODataRequest r = new ODataRequest();
-
-    r.addHeader("aa", Arrays.asList("cc"));
-
-    assertEquals("cc", r.getHeader("aa").get(0));
-    assertEquals("cc", r.getHeader("aA").get(0));
-    assertEquals("cc", r.getHeader("AA").get(0));
-
-  }
-
-  @Test
-  public void testHeader2() {
-    ODataRequest r = new ODataRequest();
-    r.addHeader("AA", Arrays.asList("dd"));
-
-    assertEquals("dd", r.getHeader("aa").get(0));
-    assertEquals("dd", r.getHeader("aA").get(0));
-    assertEquals("dd", r.getHeader("AA").get(0));
-  }
-
-  @Test
-  public void testMultiValueHeader() {
-    ODataRequest r = new ODataRequest();
-
-    r.addHeader("aa", Arrays.asList("a", "b"));
-
-    assertEquals("a", r.getHeader("aa").get(0));
-    assertEquals("b", r.getHeader("aA").get(1));
-
-    r.addHeader("Aa", Arrays.asList("c"));
-
-    assertEquals("a", r.getHeader("aa").get(0));
-    assertEquals("b", r.getHeader("aA").get(1));
-    assertEquals("c", r.getHeader("aA").get(2));
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/acc12ff7/lib/server-test/src/test/java/org/apache/olingo/server/core/ContentNegotiationTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ContentNegotiationTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ContentNegotiationTest.java
deleted file mode 100644
index db5b984..0000000
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ContentNegotiationTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.server.core;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataRequest;
-import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.processor.CollectionProcessor;
-import org.apache.olingo.server.api.processor.MetadataProcessor;
-import org.apache.olingo.server.api.processor.Processor;
-import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
-import org.apache.olingo.server.api.processor.SupportCustomContentTypes;
-import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class ContentNegotiationTest {
-
-//  static final private String ACCEPT_CASE1 = "text/plain;q=0.5";
-//  static final private String ACCEPT_CASE2 = "application/json;odata=verbose;q=0.2";
-
-  //@formatter:off (Eclipse formatter)
-  //CHECKSTYLE:OFF (Maven checkstyle)
-
-  String[][] casesServiceDocument = {
-      /* expected            $format          accept              supported */
-      { "application/json",  null,            null,               null },
-      { "application/json",  "json",          null,               null },
-      { "application/json",  "json",          "application/json", null },
-      { "application/json",  null,            "application/json", null },
-      { "application/json",  null,            "*/*",              null },
-//    { "aaa",               "aaa",           null,               "aaa, bbb" },
-//    { "aaa",               null,            "*/*",              "aaa, bbb" },
-  };
-
-  String[][] casesMetadata = {
-      /* expected            $format          accept              supported */
-      { "application/xml", null,            null,              null },
-      { "application/xml", "xml",           null,              null },
-      { "application/xml", null,            "application/xml", null },
-      { "application/xml", "xml",           "application/xml", null },
-      { "application/xml",  null,            "*/*",              null },
-//    { "aaa",             "aaa",           null,              "aaa, bbb" },
-  };
-
-  String[][] casesEntitySet = {
-      /* expected            $format          accept              supported */
-      { "application/json",  null,            null,               null },
-      { "application/json",  "json",          null,               null },
-      { "application/json",  "json",          "application/json", null },
-      { "application/json",  null,            "*/*",              null },
-  };
-  
-  //CHECKSTYLE:ON
-  //@formatter:on
-
-  private ODataHandler createHandler() {
-    OData odata = OData.newInstance();
-    Edm edm = odata.createEdm(new EdmTechProvider());
-    return new ODataHandler(odata, edm);
-
-  }
-
-  @Test
-  public void testServiceDocumentDefault() {
-
-    for (String[] useCase : casesServiceDocument) {
-      ODataRequest request = new ODataRequest();
-      request.setMethod(HttpMethod.GET);
-      request.setRawODataPath("/" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
-
-      ODataResponse response = callHandler(useCase, request);
-
-      assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
-    }
-  }
-
-  @Test
-  public void testMetadataDefault() {
-
-    for (String[] useCase : casesMetadata) {
-      ODataRequest request = new ODataRequest();
-      request.setMethod(HttpMethod.GET);
-      request.setRawODataPath("/$metadata" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
-
-      ODataResponse response = callHandler(useCase, request);
-
-      assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
-    }
-  }
-
-  @Test
-  public void testEntitySet() {
-
-    for (String[] useCase : casesEntitySet) {
-      ODataRequest request = new ODataRequest();
-      request.setMethod(HttpMethod.GET);
-      request.setRawODataPath("/ESAllPrim" + (useCase[1] == null ? "" : "?$format=" + useCase[1]));
-
-      ODataResponse response = callHandler(useCase, request, new CollectionProcessorStub());
-
-      assertEquals(useCase[0], response.getHeaders().get(HttpHeader.CONTENT_TYPE));
-    }
-  }
-
-  private ODataResponse callHandler(String[] useCase, ODataRequest request,
-      Processor defaultProcessor) {
-    ODataHandler handler = createHandler();
-
-    if (useCase[3] != null) {
-      ProcessorStub stub = new ProcessorStub(useCase[3].split(","));
-      handler.register(stub);
-    } else {
-      if (defaultProcessor != null) {
-        handler.register(defaultProcessor);
-      }
-    }
-
-    ODataResponse response = handler.process(request);
-    return response;
-  }
-
-  ODataResponse callHandler(String[] useCase, ODataRequest request) {
-    return callHandler(useCase, request, null);
-  }
-
-  private class ProcessorStub implements ServiceDocumentProcessor, MetadataProcessor, CollectionProcessor,
-      SupportCustomContentTypes {
-
-    String[] formats;
-
-    ProcessorStub(String[] strings) {
-      this.formats = strings;
-    }
-
-    @Override
-    public void init(OData odata, Edm edm) {}
-
-    @Override
-    public List<String> getSupportedContentTypes(Class<? extends Processor> processorClass) {
-      return Arrays.asList(formats);
-    }
-
-    @Override
-    public void readServiceDocument(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
-      response.setHeader(HttpHeader.CONTENT_TYPE, format);
-    }
-
-    @Override
-    public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
-      response.setHeader(HttpHeader.CONTENT_TYPE, format);
-    }
-
-    @Override
-    public void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
-      response.setHeader(HttpHeader.CONTENT_TYPE, format);
-    }
-
-  }
-
-  private class CollectionProcessorStub implements CollectionProcessor {
-
-    @Override
-    public void init(OData odata, Edm edm) {}
-
-    @Override
-    public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
-      response.setHeader(HttpHeader.CONTENT_TYPE, format);
-    }
-  }
-
-}