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)
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
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
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
;
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)
67 * A list of HeaderElements
70 private final ArrayList headers
= new ArrayList();
72 static final DateFormat dateFormat
= new HTTPDateFormat();
74 static class HeaderElement
79 HeaderElement(String name
, String value
)
91 * Return an Iterator over this collection of headers.
92 * Iterator.getNext() returns objects of type {@link HeaderElement}.
94 * @return the 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
))
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
);
131 return Integer
.parseInt(val
);
133 catch (NumberFormatException e
)
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
);
152 return Long
.parseLong(val
);
154 catch (NumberFormatException e
)
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
);
173 return dateFormat
.parse(val
);
175 catch (ParseException e
)
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
190 public void put(String name
, String value
)
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();
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
))
234 * Parse the specified InputStream, adding headers to this collection.
236 * @param in the InputStream.
238 public void parse(InputStream in
)
241 LineInputStream lin
= (in
instanceof LineInputStream
) ?
242 (LineInputStream
) in
: new LineInputStream(in
);
245 StringBuilder value
= new StringBuilder();
248 String line
= lin
.readLine();
253 addValue(name
, value
.toString());
257 int len
= line
.length();
262 addValue(name
, value
.toString());
266 char c1
= line
.charAt(0);
267 if (c1
== ' ' || c1
== '\t')
271 if (line
.charAt(last
) != '\r')
273 value
.append(line
.substring(0, last
));
279 addValue(name
, value
.toString());
282 int di
= line
.indexOf(':');
283 name
= line
.substring(0, di
);
289 while (di
< len
&& line
.charAt(di
) == ' ');
291 if (line
.charAt(last
) != '\r')
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
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).
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
);
334 l
= new ArrayList(1);
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
));
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)
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)
381 return ((HeaderElement
)headers
.get(i
)).value
;