summaryrefslogtreecommitdiff
path: root/gnu/java/net/protocol/http/Headers.java
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/java/net/protocol/http/Headers.java')
-rw-r--r--gnu/java/net/protocol/http/Headers.java282
1 files changed, 158 insertions, 124 deletions
diff --git a/gnu/java/net/protocol/http/Headers.java b/gnu/java/net/protocol/http/Headers.java
index f130237ad..b42faaa31 100644
--- a/gnu/java/net/protocol/http/Headers.java
+++ b/gnu/java/net/protocol/http/Headers.java
@@ -1,5 +1,5 @@
/* Headers.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,124 +44,75 @@ import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
- * A collection of HTTP header names and associated values.
- * Retrieval of values is case insensitive. An iteration over the keys
+ * A collection of HTTP header names and associated values. The
+ * values are {@link ArrayList ArrayLists} of Strings. Retrieval of
+ * values is case insensitive. An iteration over the collection
* returns the header names in the order they were received.
*
* @author Chris Burdess (dog@gnu.org)
+ * @author David Daney (ddaney@avtrex.com)
*/
-public class Headers
- extends LinkedHashMap
+class Headers
{
-
+ /**
+ * A list of HeaderElements
+ *
+ */
+ private final ArrayList headers = new ArrayList();
+
static final DateFormat dateFormat = new HTTPDateFormat();
- static class Header
+ static class HeaderElement
{
+ String name;
+ String value;
- final String name;
-
- Header(String name)
+ HeaderElement(String name, String value)
{
- if (name == null || name.length() == 0)
- {
- throw new IllegalArgumentException(name);
- }
this.name = name;
+ this.value = value;
}
-
- public int hashCode()
- {
- return name.toLowerCase().hashCode();
- }
-
- public boolean equals(Object other)
- {
- if (other instanceof Header)
- {
- return ((Header) other).name.equalsIgnoreCase(name);
- }
- return false;
- }
-
- public String toString()
- {
- return name;
- }
-
- }
-
- static class HeaderEntry
- implements Map.Entry
- {
-
- final Map.Entry entry;
-
- HeaderEntry(Map.Entry entry)
- {
- this.entry = entry;
- }
-
- public Object getKey()
- {
- return ((Header) entry.getKey()).name;
- }
-
- public Object getValue()
- {
- return entry.getValue();
- }
-
- public Object setValue(Object value)
- {
- return entry.setValue(value);
- }
-
- public int hashCode()
- {
- return entry.hashCode();
- }
-
- public boolean equals(Object other)
- {
- return entry.equals(other);
- }
-
- public String toString()
- {
- return getKey().toString() + "=" + getValue();
- }
-
}
public Headers()
{
}
- public boolean containsKey(Object key)
- {
- return super.containsKey(new Header((String) key));
- }
-
- public Object get(Object key)
+ /**
+ * Return an Iterator over this collection of headers.
+ * Iterator.getNext() returns objects of type {@link HeaderElement}.
+ *
+ * @return the Iterator.
+ */
+ Iterator iterator()
{
- return super.get(new Header((String) key));
+ return headers.iterator();
}
-
+
/**
- * Returns the value of the specified header as a string.
+ * Returns the value of the specified header as a string. If
+ * multiple values are present, the last one is returned.
*/
public String getValue(String header)
{
- return (String) super.get(new Header(header));
+ for (int i = headers.size() - 1; i >= 0; i--)
+ {
+ HeaderElement e = (HeaderElement)headers.get(i);
+ if (e.name.equalsIgnoreCase(header))
+ {
+ return e.value;
+ }
+ }
+ return null;
}
/**
@@ -227,51 +178,62 @@ public class Headers
}
}
- public Object put(Object key, Object value)
- {
- return super.put(new Header((String) key), value);
- }
-
- public Object remove(Object key)
+ /**
+ * Add a header to this set of headers. If there is an existing
+ * header with the same name, it is discarded.
+ *
+ * @param name the header name
+ * @param value the header value
+ *
+ * @see #addValue
+ */
+ public void put(String name, String value)
{
- return super.remove(new Header((String) key));
+ remove(name);
+ headers.add(headers.size(), new HeaderElement(name, value));
}
- public void putAll(Map t)
+ /**
+ * Add all headers from a set of headers to this set. If any of the
+ * headers to be added have the same name as existing headers, the
+ * existing headers will be discarded.
+ *
+ * @param o the headers to be added
+ */
+ public void putAll(Headers o)
{
- for (Iterator i = t.keySet().iterator(); i.hasNext(); )
+ for (Iterator it = o.iterator(); it.hasNext(); )
{
- String key = (String) i.next();
- String value = (String) t.get(key);
- put(key, value);
+ HeaderElement e = (HeaderElement)it.next();
+ remove(e.name);
}
- }
-
- public Set keySet()
- {
- Set keys = super.keySet();
- Set ret = new LinkedHashSet();
- for (Iterator i = keys.iterator(); i.hasNext(); )
+ for (Iterator it = o.iterator(); it.hasNext(); )
{
- ret.add(((Header) i.next()).name);
+ HeaderElement e = (HeaderElement)it.next();
+ addValue(e.name, e.value);
}
- return ret;
}
- public Set entrySet()
+ /**
+ * Remove a header from this set of headers. If there is more than
+ * one instance of a header of the given name, they are all removed.
+ *
+ * @param name the header name
+ */
+ public void remove(String name)
{
- Set entries = super.entrySet();
- Set ret = new LinkedHashSet();
- for (Iterator i = entries.iterator(); i.hasNext(); )
+ for (Iterator it = headers.iterator(); it.hasNext(); )
{
- Map.Entry entry = (Map.Entry) i.next();
- ret.add(new HeaderEntry(entry));
+ HeaderElement e = (HeaderElement)it.next();
+ if (e.name.equalsIgnoreCase(name))
+ it.remove();
}
- return ret;
}
/**
- * Parse the specified input stream, adding headers to this collection.
+ * Parse the specified InputStream, adding headers to this collection.
+ *
+ * @param in the InputStream.
*/
public void parse(InputStream in)
throws IOException
@@ -333,18 +295,90 @@ public class Headers
}
}
- private void addValue(String name, String value)
+
+ /**
+ * Add a header to this set of headers. If there is an existing
+ * header with the same name, it is not effected.
+ *
+ * @param name the header name
+ * @param value the header value
+ *
+ * @see #put
+ */
+ public void addValue(String name, String value)
+ {
+ headers.add(headers.size(), new HeaderElement(name, value));
+ }
+
+ /**
+ * Get a new Map containing all the headers. The keys of the Map
+ * are Strings (the header names). The values of the Map are
+ * unmodifiable Lists containing Strings (the header values).
+ *
+ * <p>
+ *
+ * The returned map is modifiable. Changing it will not effect this
+ * collection of Headers in any way.
+ *
+ * @return a Map containing all the headers.
+ */
+ public Map getAsMap()
{
- Header key = new Header(name);
- String old = (String) super.get(key);
- if (old == null)
+ LinkedHashMap m = new LinkedHashMap();
+ for (Iterator it = headers.iterator(); it.hasNext(); )
{
- super.put(key, value);
+ HeaderElement e = (HeaderElement)it.next();
+ ArrayList l = (ArrayList)m.get(e.name);
+ if (l == null)
+ {
+ l = new ArrayList(1);
+ l.add(e.value);
+ m.put(e.name, l);
+ }
+ else
+ l.add(0, e.value);
}
- else
+ for (Iterator it = m.entrySet().iterator(); it.hasNext(); )
{
- super.put(key, old + ", " + value);
+ Map.Entry me = (Map.Entry)it.next();
+ ArrayList l = (ArrayList)me.getValue();
+ me.setValue(Collections.unmodifiableList(l));
}
+ return m;
+ }
+
+ /**
+ * Get the name of the Nth header.
+ *
+ * @param i the header index.
+ *
+ * @return the header name.
+ *
+ * @see #getHeaderValue
+ */
+ public String getHeaderName(int i)
+ {
+ if (i >= headers.size() || i < 0)
+ return null;
+
+ return ((HeaderElement)headers.get(i)).name;
+ }
+
+ /**
+ * Get the value of the Nth header.
+ *
+ * @param i the header index.
+ *
+ * @return the header value.
+ *
+ * @see #getHeaderName
+ */
+ public String getHeaderValue(int i)
+ {
+ if (i >= headers.size() || i < 0)
+ return null;
+
+ return ((HeaderElement)headers.get(i)).value;
}
}