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 2015/08/13 15:32:58 UTC

[2/2] olingo-odata4 git commit: [OLINGO-659] Introduced HttpHeader for ODataResponse/Request

[OLINGO-659] Introduced HttpHeader for ODataResponse/Request


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

Branch: refs/heads/master
Commit: f2c7be2d128b9689f0f8b93741a1f1582b883c63
Parents: b82294e
Author: Michael Bolz <mi...@sap.com>
Authored: Thu Aug 13 13:59:13 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Aug 13 15:32:24 2015 +0200

----------------------------------------------------------------------
 .../olingo/commons/api/http/HttpHeader.java     | 110 ++++++++++++++-
 .../olingo/commons/api/http/HttpHeaders.java    | 134 +++++++++++++++++++
 .../apache/olingo/server/api/ODataRequest.java  |  33 ++---
 .../apache/olingo/server/api/ODataResponse.java |  14 +-
 .../server/core/debug/DebugTabRequestTest.java  |  10 +-
 5 files changed, 277 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f2c7be2d/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
index d9ebe1b..6d047e2 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
@@ -18,10 +18,15 @@
  ******************************************************************************/
 package org.apache.olingo.commons.api.http;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Locale;
+
 /**
  * HTTP header constants.
  */
-public interface HttpHeader {
+public class HttpHeader {
 
   /**
    * See {@link <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">HTTP/1.1 documentation</a>}.
@@ -176,4 +181,107 @@ public interface HttpHeader {
   public static final String ODATA_MAX_VERSION = "OData-MaxVersion";
   /** Custom Header defined in the OData standard. */
   public static final String ODATA_ENTITY_ID = "OData-EntityID";
+
+  private final String name;
+  private final Collection<String> values;
+
+  /**
+   * Create header for given name
+   * @param name of header
+   */
+  public HttpHeader(String name) {
+    this.name = name;
+    this.values = new ArrayList<String>();
+  }
+
+  /**
+   * Create header for given name and add given values
+   * @param name of header
+   * @param values values for header
+   */
+  public HttpHeader(String name, Collection<String> values) {
+    this(name);
+    this.values.addAll(values);
+  }
+
+  /**
+   * Get name of header (not the canonical name)
+   * @return name of header
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Get all values for this header
+   * @return all header values
+   */
+  public Collection<String> getValues() {
+    return Collections.unmodifiableCollection(values);
+  }
+
+  /**
+   * Add header value
+   *
+   * @param value value to be added
+   * @return this header object (fluent interface)
+   */
+  public HttpHeader addValue(String value) {
+    this.values.add(value);
+    return this;
+  }
+
+  /**
+   * Add header values
+   *
+   * @param values values to be added
+   * @return this header object (fluent interface)
+   */
+  public HttpHeader addValues(Collection<String> values) {
+    this.values.addAll(values);
+    return this;
+  }
+
+  /**
+   * Get the canonical name of header
+   * @return canonical name of header
+   */
+  public String getCanonicalName() {
+    return createCanonicalName(name);
+  }
+
+  /**
+   * Create the canonical name based on given name parameter
+   *
+   * @param name name which is canonicalised
+   * @return canonical name
+   */
+  public static String createCanonicalName(String name) {
+    return name.toLowerCase(Locale.ROOT);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    HttpHeader that = (HttpHeader) o;
+
+    if (!name.equals(that.name)) {
+      return false;
+    }
+    return values.equals(that.values);
+
+  }
+
+  @Override
+  public int hashCode() {
+    int result = name.hashCode();
+    result = 31 * result + values.hashCode();
+    return result;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f2c7be2d/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeaders.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeaders.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeaders.java
new file mode 100644
index 0000000..54d0e30
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeaders.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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.commons.api.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * HttpHeader container
+ */
+public class HttpHeaders {
+  private final Map<String, HttpHeader> headers = new TreeMap<String, HttpHeader>();
+
+  /**
+   * Add a header with given name and value.
+   * If header with name already exists the value is added to this header.
+   *
+   * @param name name of header
+   * @param value value for header
+   * @return this container (fluent interface)
+   */
+  public HttpHeaders addHeader(String name, String value) {
+    HttpHeader eh = grantHeader(name);
+    eh.addValue(value);
+    return this;
+  }
+
+  /**
+   * Add a header with given name and values.
+   * If header with name already exists the values are added to this header.
+   *
+   * @param name name of header
+   * @param values values for header
+   * @return this container (fluent interface)
+   */
+  public HttpHeaders addHeader(String name, Collection<String> values) {
+    HttpHeader eh = grantHeader(name);
+    eh.addValues(values);
+    return this;
+  }
+
+  /**
+   * Set a header with given name and value.
+   * If header with name already exists the old header is replaced with the new one.
+   *
+   * @param name name of header
+   * @param value value for header
+   * @return this container (fluent interface)
+   */
+  public HttpHeaders setHeader(String name, String value) {
+    removeHeader(name);
+
+    HttpHeader eh = grantHeader(name);
+    eh.addValue(value);
+    return this;
+  }
+
+  /**
+   * Get header for given name.
+   *
+   * @param name name of header requested
+   * @return corresponding header
+   */
+  public HttpHeader getHeader(String name) {
+    return headers.get(HttpHeader.createCanonicalName(name));
+  }
+
+  /**
+   * Remove header for given name.
+   *
+   * @param name name of header to be removed
+   * @return header which was removed or null if no header was known for this name
+   */
+  public HttpHeader removeHeader(String name) {
+    return headers.remove(HttpHeader.createCanonicalName(name));
+  }
+
+
+  /**
+   * Get all headers.
+   *
+   * @return all headers
+   */
+  public Collection<HttpHeader> getHeaders() {
+    return Collections.unmodifiableCollection(headers.values());
+  }
+
+  /**
+   * Get all header names.
+   *
+   * @return all header names
+   */
+  public Collection<String> getHeaderNames() {
+    Collection<String> headerNames = new ArrayList<String>();
+    for (HttpHeader header : headers.values()) {
+      headerNames.add(header.getName());
+    }
+    return headerNames;
+  }
+
+  /**
+   * Get or create a header for given name.
+   *
+   * @return new or known header
+   */
+  private HttpHeader grantHeader(String name) {
+    String key = HttpHeader.createCanonicalName(name);
+    HttpHeader eh = headers.get(key);
+    if(eh == null) {
+      eh = new HttpHeader(name);
+      headers.put(key, eh);
+    }
+    return eh;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f2c7be2d/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 ed34e96..5b734ec 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
@@ -20,11 +20,14 @@ package org.apache.olingo.server.api;
 
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpHeaders;
 import org.apache.olingo.commons.api.http.HttpMethod;
 
 /**
@@ -32,7 +35,7 @@ import org.apache.olingo.commons.api.http.HttpMethod;
  */
 public class ODataRequest {
   private HttpMethod method;
-  private Map<String, List<String>> headers = new HashMap<String, List<String>>();
+  private HttpHeaders headers = new HttpHeaders();
   private InputStream body;
   private String rawQueryPath;
   private String rawRequestUri;
@@ -66,18 +69,7 @@ public class ODataRequest {
    * @see <a href="http://ietf.org/rfc/rfc7230.txt">RFC 7230, section 3.2.2</a>
    */
   public void addHeader(final String name, final List<String> values) {
-    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);
-
-      headers.put(name.toUpperCase(), newValues);
-    } else {
-      headers.put(name.toUpperCase(), values);
-    }
+    headers.addHeader(name, values);
   }
 
   /**
@@ -86,7 +78,11 @@ public class ODataRequest {
    * @return the header value(s) or null if not found
    */
   public List<String> getHeaders(final String name) {
-    return headers.get(name.toUpperCase());
+    HttpHeader h = headers.getHeader(name);
+    if(h == null) {
+      return null;//Collections.emptyList();
+    }
+    return new ArrayList<String>(h.getValues());
   }
 
   /**
@@ -104,7 +100,14 @@ public class ODataRequest {
    * @return an unmodifiable Map of header names/values
    */
   public Map<String, List<String>> getAllHeaders() {
-    return Collections.unmodifiableMap(headers);
+    Collection<HttpHeader> allHeader = headers.getHeaders();
+    Map<String, List<String>> result = new HashMap<String, List<String>>();
+
+    for (HttpHeader httpHeader : allHeader) {
+      result.put(httpHeader.getName(), new ArrayList<String>(httpHeader.getValues()));
+    }
+
+    return Collections.unmodifiableMap(result);
   }
 
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f2c7be2d/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
index 7b9e9c9..b104ff7 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
@@ -19,10 +19,13 @@
 package org.apache.olingo.server.api;
 
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpHeaders;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 
 /**
@@ -31,7 +34,7 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
 public class ODataResponse {
 
   private int statusCode = HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode();
-  private final Map<String, String> headers = new HashMap<String, String>();
+  private final HttpHeaders headers = new HttpHeaders();
   private InputStream content;
 
   /**
@@ -56,7 +59,7 @@ public class ODataResponse {
    * @param value the value
    */
   public void setHeader(final String name, final String value) {
-    headers.put(name, value);
+    headers.setHeader(name, value);
   }
 
   /**
@@ -64,7 +67,12 @@ public class ODataResponse {
    * @return an unmodifiable Map of header names/values
    */
   public Map<String, String> getHeaders() {
-    return Collections.unmodifiableMap(headers);
+    Map<String, String> result = new HashMap<String, String>();
+    Collection<HttpHeader> allHeaders = headers.getHeaders();
+    for (HttpHeader header : allHeaders) {
+      result.put(header.getName(), header.getValues().iterator().next());
+    }
+    return Collections.unmodifiableMap(result);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f2c7be2d/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
index 3689301..906adbd 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
@@ -86,7 +86,7 @@ public class DebugTabRequestTest extends AbstractDebugTabTest {
   @Test
   public void singleHeaderValue() throws Exception {
     String expectedJson =
-        "{\"method\":\"GET\",\"uri\":\"def&\",\"protocol\":\"def&\",\"headers\":{\"HEADERNAME\":\"Value1\"}}";
+        "{\"method\":\"GET\",\"uri\":\"def&\",\"protocol\":\"def&\",\"headers\":{\"HeaderName\":\"Value1\"}}";
     String expectedHtml = "<h2>Request Method</h2>\n"
         + "<p>GET</p>\n"
         + "<h2>Request URI</h2>\n"
@@ -99,7 +99,7 @@ public class DebugTabRequestTest extends AbstractDebugTabTest {
         + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
         + "</thead>\n"
         + "<tbody>\n"
-        + "<tr><td class=\"name\">HEADERNAME</td><td class=\"value\">Value1</td></tr>\n"
+        + "<tr><td class=\"name\">HeaderName</td><td class=\"value\">Value1</td></tr>\n"
         + "</tbody>\n"
         + "</table>\n";
 
@@ -120,7 +120,7 @@ public class DebugTabRequestTest extends AbstractDebugTabTest {
   @Test
   public void multiHeaderValueResultsInMap() throws Exception {
     String expectedJson = "{\"method\":\"GET\",\"uri\":\"def&\",\"protocol\":\"def&\","
-        + "\"headers\":{\"HEADERNAME\":[\"Value1\",\"Value2\"]}}";
+        + "\"headers\":{\"HeaderName\":[\"Value1\",\"Value2\"]}}";
     String expectedHtml = "<h2>Request Method</h2>\n"
         + "<p>GET</p>\n"
         + "<h2>Request URI</h2>\n"
@@ -133,8 +133,8 @@ public class DebugTabRequestTest extends AbstractDebugTabTest {
         + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
         + "</thead>\n"
         + "<tbody>\n"
-        + "<tr><td class=\"name\">HEADERNAME</td><td class=\"value\">Value1</td></tr>\n"
-        + "<tr><td class=\"name\">HEADERNAME</td><td class=\"value\">Value2</td></tr>\n"
+        + "<tr><td class=\"name\">HeaderName</td><td class=\"value\">Value1</td></tr>\n"
+        + "<tr><td class=\"name\">HeaderName</td><td class=\"value\">Value2</td></tr>\n"
         + "</tbody>\n"
         + "</table>\n";