diff options
Diffstat (limited to 'gnu/java/net/protocol/http/Headers.java')
-rw-r--r-- | gnu/java/net/protocol/http/Headers.java | 282 |
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; } } |