Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / net / protocol / http / Headers.java
blobb42faaa315de21e81ac2e8025a5105653d0ff017
1 /* Headers.java --
2 Copyright (C) 2004, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.net.protocol.http;
41 import gnu.java.net.LineInputStream;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.text.DateFormat;
46 import java.text.ParseException;
47 import java.util.ArrayList;
48 import java.util.Collections;
49 import java.util.Date;
50 import java.util.Iterator;
51 import java.util.LinkedHashMap;
52 import java.util.Map;
53 import java.util.Set;
55 /**
56 * A collection of HTTP header names and associated values. The
57 * values are {@link ArrayList ArrayLists} of Strings. Retrieval of
58 * values is case insensitive. An iteration over the collection
59 * returns the header names in the order they were received.
61 * @author Chris Burdess (dog@gnu.org)
62 * @author David Daney (ddaney@avtrex.com)
64 class Headers
66 /**
67 * A list of HeaderElements
70 private final ArrayList headers = new ArrayList();
72 static final DateFormat dateFormat = new HTTPDateFormat();
74 static class HeaderElement
76 String name;
77 String value;
79 HeaderElement(String name, String value)
81 this.name = name;
82 this.value = value;
86 public Headers()
90 /**
91 * Return an Iterator over this collection of headers.
92 * Iterator.getNext() returns objects of type {@link HeaderElement}.
94 * @return the Iterator.
96 Iterator iterator()
98 return headers.iterator();
102 * Returns the value of the specified header as a string. If
103 * multiple values are present, the last one is returned.
105 public String getValue(String header)
107 for (int i = headers.size() - 1; i >= 0; i--)
109 HeaderElement e = (HeaderElement)headers.get(i);
110 if (e.name.equalsIgnoreCase(header))
112 return e.value;
115 return null;
119 * Returns the value of the specified header as an integer,
120 * or -1 if the header is not present or not an integer.
122 public int getIntValue(String header)
124 String val = getValue(header);
125 if (val == null)
127 return -1;
131 return Integer.parseInt(val);
133 catch (NumberFormatException e)
136 return -1;
140 * Returns the value of the specified header as a long, or -1 if the
141 * header is not present or cannot be parsed as a long.
143 public long getLongValue(String header)
145 String val = getValue(header);
146 if (val == null)
148 return -1;
152 return Long.parseLong(val);
154 catch (NumberFormatException e)
157 return -1;
161 * Returns the value of the specified header as a date,
162 * or <code>null</code> if the header is not present or not a date.
164 public Date getDateValue(String header)
166 String val = getValue(header);
167 if (val == null)
169 return null;
173 return dateFormat.parse(val);
175 catch (ParseException e)
177 return null;
182 * Add a header to this set of headers. If there is an existing
183 * header with the same name, it is discarded.
185 * @param name the header name
186 * @param value the header value
188 * @see #addValue
190 public void put(String name, String value)
192 remove(name);
193 headers.add(headers.size(), new HeaderElement(name, value));
197 * Add all headers from a set of headers to this set. If any of the
198 * headers to be added have the same name as existing headers, the
199 * existing headers will be discarded.
201 * @param o the headers to be added
203 public void putAll(Headers o)
205 for (Iterator it = o.iterator(); it.hasNext(); )
207 HeaderElement e = (HeaderElement)it.next();
208 remove(e.name);
210 for (Iterator it = o.iterator(); it.hasNext(); )
212 HeaderElement e = (HeaderElement)it.next();
213 addValue(e.name, e.value);
218 * Remove a header from this set of headers. If there is more than
219 * one instance of a header of the given name, they are all removed.
221 * @param name the header name
223 public void remove(String name)
225 for (Iterator it = headers.iterator(); it.hasNext(); )
227 HeaderElement e = (HeaderElement)it.next();
228 if (e.name.equalsIgnoreCase(name))
229 it.remove();
234 * Parse the specified InputStream, adding headers to this collection.
236 * @param in the InputStream.
238 public void parse(InputStream in)
239 throws IOException
241 LineInputStream lin = (in instanceof LineInputStream) ?
242 (LineInputStream) in : new LineInputStream(in);
244 String name = null;
245 StringBuilder value = new StringBuilder();
246 while (true)
248 String line = lin.readLine();
249 if (line == null)
251 if (name != null)
253 addValue(name, value.toString());
255 break;
257 int len = line.length();
258 if (len < 2)
260 if (name != null)
262 addValue(name, value.toString());
264 break;
266 char c1 = line.charAt(0);
267 if (c1 == ' ' || c1 == '\t')
269 // Continuation
270 int last = len - 1;
271 if (line.charAt(last) != '\r')
272 ++last;
273 value.append(line.substring(0, last));
275 else
277 if (name != null)
279 addValue(name, value.toString());
282 int di = line.indexOf(':');
283 name = line.substring(0, di);
284 value.setLength(0);
287 di++;
289 while (di < len && line.charAt(di) == ' ');
290 int last = len - 1;
291 if (line.charAt(last) != '\r')
292 ++last;
293 value.append(line.substring(di, last));
300 * Add a header to this set of headers. If there is an existing
301 * header with the same name, it is not effected.
303 * @param name the header name
304 * @param value the header value
306 * @see #put
308 public void addValue(String name, String value)
310 headers.add(headers.size(), new HeaderElement(name, value));
314 * Get a new Map containing all the headers. The keys of the Map
315 * are Strings (the header names). The values of the Map are
316 * unmodifiable Lists containing Strings (the header values).
318 * <p>
320 * The returned map is modifiable. Changing it will not effect this
321 * collection of Headers in any way.
323 * @return a Map containing all the headers.
325 public Map getAsMap()
327 LinkedHashMap m = new LinkedHashMap();
328 for (Iterator it = headers.iterator(); it.hasNext(); )
330 HeaderElement e = (HeaderElement)it.next();
331 ArrayList l = (ArrayList)m.get(e.name);
332 if (l == null)
334 l = new ArrayList(1);
335 l.add(e.value);
336 m.put(e.name, l);
338 else
339 l.add(0, e.value);
341 for (Iterator it = m.entrySet().iterator(); it.hasNext(); )
343 Map.Entry me = (Map.Entry)it.next();
344 ArrayList l = (ArrayList)me.getValue();
345 me.setValue(Collections.unmodifiableList(l));
347 return m;
351 * Get the name of the Nth header.
353 * @param i the header index.
355 * @return the header name.
357 * @see #getHeaderValue
359 public String getHeaderName(int i)
361 if (i >= headers.size() || i < 0)
362 return null;
364 return ((HeaderElement)headers.get(i)).name;
368 * Get the value of the Nth header.
370 * @param i the header index.
372 * @return the header value.
374 * @see #getHeaderName
376 public String getHeaderValue(int i)
378 if (i >= headers.size() || i < 0)
379 return null;
381 return ((HeaderElement)headers.get(i)).value;