summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/net/protocol/http/Headers.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/net/protocol/http/Headers.java')
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/Headers.java369
1 files changed, 369 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/net/protocol/http/Headers.java b/libjava/classpath/gnu/java/net/protocol/http/Headers.java
new file mode 100644
index 00000000000..847ebefc1f6
--- /dev/null
+++ b/libjava/classpath/gnu/java/net/protocol/http/Headers.java
@@ -0,0 +1,369 @@
+/* Headers.java --
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.net.protocol.http;
+
+import gnu.java.net.LineInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Collection;
+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
+ * returns the header names in the order they were received.
+ *
+ * @author Chris Burdess (dog@gnu.org)
+ */
+public class Headers
+ implements Map
+{
+
+ static final DateFormat dateFormat = new HTTPDateFormat();
+
+ static class Header
+ {
+
+ final String name;
+
+ Header(String name)
+ {
+ if (name == null || name.length() == 0)
+ {
+ throw new IllegalArgumentException(name);
+ }
+ this.name = name;
+ }
+
+ 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();
+ }
+
+ }
+
+ private LinkedHashMap headers;
+
+ public Headers()
+ {
+ headers = new LinkedHashMap();
+ }
+
+ public int size()
+ {
+ return headers.size();
+ }
+
+ public boolean isEmpty()
+ {
+ return headers.isEmpty();
+ }
+
+ public boolean containsKey(Object key)
+ {
+ return headers.containsKey(new Header((String) key));
+ }
+
+ public boolean containsValue(Object value)
+ {
+ return headers.containsValue(value);
+ }
+
+ public Object get(Object key)
+ {
+ return headers.get(new Header((String) key));
+ }
+
+ /**
+ * Returns the value of the specified header as a string.
+ */
+ public String getValue(String header)
+ {
+ return (String) headers.get(new Header(header));
+ }
+
+ /**
+ * Returns the value of the specified header as an integer,
+ * or -1 if the header is not present or not an integer.
+ */
+ public int getIntValue(String header)
+ {
+ String val = getValue(header);
+ if (val == null)
+ {
+ return -1;
+ }
+ try
+ {
+ return Integer.parseInt(val);
+ }
+ catch (NumberFormatException e)
+ {
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the value of the specified header as a date,
+ * or <code>null</code> if the header is not present or not a date.
+ */
+ public Date getDateValue(String header)
+ {
+ String val = getValue(header);
+ if (val == null)
+ {
+ return null;
+ }
+ try
+ {
+ return dateFormat.parse(val);
+ }
+ catch (ParseException e)
+ {
+ return null;
+ }
+ }
+
+ public Object put(Object key, Object value)
+ {
+ return headers.put(new Header((String) key), value);
+ }
+
+ public Object remove(Object key)
+ {
+ return headers.remove(new Header((String) key));
+ }
+
+ public void putAll(Map t)
+ {
+ for (Iterator i = t.keySet().iterator(); i.hasNext(); )
+ {
+ String key = (String) i.next();
+ String value = (String) t.get(key);
+ headers.put(new Header(key), value);
+ }
+ }
+
+ public void clear()
+ {
+ headers.clear();
+ }
+
+ public Set keySet()
+ {
+ Set keys = headers.keySet();
+ Set ret = new LinkedHashSet();
+ for (Iterator i = keys.iterator(); i.hasNext(); )
+ {
+ ret.add(((Header) i.next()).name);
+ }
+ return ret;
+ }
+
+ public Collection values()
+ {
+ return headers.values();
+ }
+
+ public Set entrySet()
+ {
+ Set entries = headers.entrySet();
+ Set ret = new LinkedHashSet();
+ for (Iterator i = entries.iterator(); i.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) i.next();
+ ret.add(new HeaderEntry(entry));
+ }
+ return ret;
+ }
+
+ public boolean equals(Object other)
+ {
+ return headers.equals(other);
+ }
+
+ public int hashCode()
+ {
+ return headers.hashCode();
+ }
+
+ /**
+ * Parse the specified input stream, adding headers to this collection.
+ */
+ public void parse(InputStream in)
+ throws IOException
+ {
+ LineInputStream lin = (in instanceof LineInputStream) ?
+ (LineInputStream) in : new LineInputStream(in);
+
+ String name = null;
+ StringBuffer value = new StringBuffer();
+ while (true)
+ {
+ String line = lin.readLine();
+ if (line == null)
+ {
+ if (name != null)
+ {
+ addValue(name, value.toString());
+ }
+ break;
+ }
+ int len = line.length();
+ if (len < 2)
+ {
+ if (name != null)
+ {
+ addValue(name, value.toString());
+ }
+ break;
+ }
+ char c1 = line.charAt(0);
+ if (c1 == ' ' || c1 == '\t')
+ {
+ // Continuation
+ int last = len - 1;
+ if (line.charAt(last) != '\r')
+ ++last;
+ value.append(line.substring(0, last));
+ }
+ else
+ {
+ if (name != null)
+ {
+ addValue(name, value.toString());
+ }
+
+ int di = line.indexOf(':');
+ name = line.substring(0, di);
+ value.setLength(0);
+ do
+ {
+ di++;
+ }
+ while (di < len && line.charAt(di) == ' ');
+ int last = len - 1;
+ if (line.charAt(last) != '\r')
+ ++last;
+ value.append(line.substring(di, last));
+ }
+ }
+ }
+
+ private void addValue(String name, String value)
+ {
+ Header key = new Header(name);
+ String old = (String) headers.get(key);
+ if (old == null)
+ {
+ headers.put(key, value);
+ }
+ else
+ {
+ headers.put(key, old + ", " + value);
+ }
+ }
+
+}
+