>> entrySet() {
+ return super.entrySet();
+ }
+
+ @Override
+ public String toString() {
+ return super.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return super.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+}
diff --git a/runtime/httpwhiteboard/src/main/java/org/eclipse/osgi/technology/webservices/httpwhiteboard/wsri/Headers.java b/runtime/httpwhiteboard/src/main/java/org/eclipse/osgi/technology/webservices/httpwhiteboard/wsri/Headers.java
new file mode 100644
index 0000000..0de624d
--- /dev/null
+++ b/runtime/httpwhiteboard/src/main/java/org/eclipse/osgi/technology/webservices/httpwhiteboard/wsri/Headers.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 1997, 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.osgi.technology.webservices.httpwhiteboard.wsri;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * HTTP request and response headers are represented by this class which implements
+ * the interface {@link java.util.Map}<
+ * {@link String},{@link java.util.List}<{@link String}>>.
+ * The keys are case-insensitive Strings representing the header names and
+ * the value associated with each key is a {@link java.util.List}<{@link String}> with one
+ * element for each occurence of the header name in the request or response.
+ *
+ * For example, if a response header instance contains one key "HeaderName" with two values "value1 and value2"
+ * then this object is output as two header lines:
+ *
+ * HeaderName: value1
+ * HeaderName: value2
+ *
+ *
+ * All the normal {@link java.util.Map} methods are provided, but the following
+ * additional convenience methods are most likely to be used:
+ *
+ * - {@link #getFirst(String)} returns a single valued header or the first value of
+ * a multi-valued header.
+ * - {@link #add(String,String)} adds the given header value to the list for the given key
+ * - {@link #set(String,String)} sets the given header field to the single value given
+ * overwriting any existing values in the value list.
+ *
+ * All methods in this class accept null
values for keys and values. However, null
+ * keys will never will be present in HTTP request headers, and will not be output/sent in response headers.
+ * Null values can be represented as either a null entry for the key (i.e. the list is null) or
+ * where the key has a list, but one (or more) of the list's values is null. Null values are output
+ * as a header line containing the key but no associated value.
+ * @since 1.6
+ */
+public class Headers implements Map> {
+
+ HashMap> map;
+
+ public Headers() {
+ map = new HashMap<>(32);
+ }
+
+ /* Normalize the key by converting to following form.
+ * First char upper case, rest lower case.
+ * key is presumed to be ASCII
+ */
+ private String normalize (String key) {
+ if (key == null) {
+ return null;
+ }
+ int len = key.length();
+ if (len == 0) {
+ return key;
+ }
+ char[] b;
+ String s;
+ b = key.toCharArray();
+ if (b[0] >= 'a' && b[0] <= 'z') {
+ b[0] = (char) (b[0] - ('a' - 'A'));
+ }
+ for (int i = 1; i < len; i++) {
+ if (b[i] >= 'A' && b[i] <= 'Z') {
+ b[i] = (char) (b[i] + ('a' - 'A'));
+ }
+ }
+ s = new String(b);
+ return s;
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ if (key == null) {
+ return false;
+ }
+ if (!(key instanceof String)) {
+ return false;
+ }
+ return map.containsKey (normalize((String)key));
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return map.containsValue(value);
+ }
+
+ @Override
+ public List get(Object key) {
+ return map.get(normalize((String)key));
+ }
+
+ /**
+ * returns the first value from the List of String values
+ * for the given key (if at least one exists).
+ * @param key the key to search for
+ * @return the first string value associated with the key
+ */
+ public String getFirst (String key) {
+ List l = map.get(normalize(key));
+ if (l == null) {
+ return null;
+ }
+ return l.get(0);
+ }
+
+ @Override
+ public List put(String key, List value) {
+ return map.put (normalize(key), value);
+ }
+
+ /**
+ * adds the given value to the list of headers
+ * for the given key. If the mapping does not
+ * already exist, then it is created
+ * @param key the header name
+ * @param value the header value to add to the header
+ */
+ public void add (String key, String value) {
+ String k = normalize(key);
+ List l = map.get(k);
+ if (l == null) {
+ l = new LinkedList<>();
+ map.put(k,l);
+ }
+ l.add (value);
+ }
+
+ /**
+ * sets the given value as the sole header value
+ * for the given key. If the mapping does not
+ * already exist, then it is created
+ * @param key the header name
+ * @param value the header value to set.
+ */
+ public void set (String key, String value) {
+ LinkedList l = new LinkedList<>();
+ l.add (value);
+ put (key, l);
+ }
+
+
+ @Override
+ public List remove(Object key) {
+ return map.remove(normalize((String)key));
+ }
+
+ @Override
+ public void putAll(Map extends String,? extends List> t) {
+ for(Entry extends String, ? extends List> entry : t.entrySet()) {
+ put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public Set keySet() {
+ return map.keySet();
+ }
+
+ @Override
+ public Collection> values() {
+ return map.values();
+ }
+
+ @Override
+ public Set>> entrySet() {
+ return map.entrySet();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return map.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return map.toString();
+ }
+}
diff --git a/runtime/pom.xml b/runtime/pom.xml
index e8fecb5..ab73308 100644
--- a/runtime/pom.xml
+++ b/runtime/pom.xml
@@ -23,5 +23,6 @@
pom
registrar
-
+ httpwhiteboard
+