
Imported GNU Classpath 0.90 * scripts/makemake.tcl: LocaleData.java moved to gnu/java/locale. * sources.am: Regenerated. * gcj/javaprims.h: Regenerated. * Makefile.in: Regenerated. * gcj/Makefile.in: Regenerated. * include/Makefile.in: Regenerated. * testsuite/Makefile.in: Regenerated. * gnu/java/lang/VMInstrumentationImpl.java: New override. * gnu/java/net/local/LocalSocketImpl.java: Likewise. * gnu/classpath/jdwp/VMMethod.java: Likewise. * gnu/classpath/jdwp/VMVirtualMachine.java: Update to latest interface. * java/lang/Thread.java: Add UncaughtExceptionHandler. * java/lang/reflect/Method.java: Implements GenericDeclaration and isSynthetic(), * java/lang/reflect/Field.java: Likewise. * java/lang/reflect/Constructor.java * java/lang/Class.java: Implements Type, GenericDeclaration, getSimpleName() and getEnclosing*() methods. * java/lang/Class.h: Add new public methods. * java/lang/Math.java: Add signum(), ulp() and log10(). * java/lang/natMath.cc (log10): New function. * java/security/VMSecureRandom.java: New override. * java/util/logging/Logger.java: Updated to latest classpath version. * java/util/logging/LogManager.java: New override. From-SVN: r113887
421 lines
11 KiB
Java
421 lines
11 KiB
Java
/* Headers.java --
|
|
Copyright (C) 2004, 2006 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.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Date;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* 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)
|
|
*/
|
|
class Headers
|
|
{
|
|
/**
|
|
* A list of HeaderElements
|
|
*/
|
|
private final ArrayList headers = new ArrayList();
|
|
|
|
/**
|
|
* The HTTP dateformat used to parse date header fields.
|
|
*/
|
|
private static final DateFormat dateFormat = new HTTPDateFormat();
|
|
|
|
/**
|
|
* Class for a Header element consisting of
|
|
* a name and value String.
|
|
*/
|
|
static class HeaderElement
|
|
{
|
|
String name;
|
|
String value;
|
|
|
|
HeaderElement(String name, String value)
|
|
{
|
|
this.name = name;
|
|
this.value = value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Default constructor.
|
|
*/
|
|
public Headers()
|
|
{
|
|
// nothing to do
|
|
}
|
|
|
|
/**
|
|
* Return an Iterator over this collection of headers.
|
|
* Iterator.getNext() returns objects of type {@link HeaderElement}.
|
|
*
|
|
* @return the Iterator.
|
|
*/
|
|
Iterator iterator()
|
|
{
|
|
return headers.iterator();
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the specified header as a string. If
|
|
* multiple values are present, the last one is returned.
|
|
*
|
|
* @param header the header name (case insensitive search)
|
|
* @return The header value or <code>null</code> if not found.
|
|
*/
|
|
public String getValue(String 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;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the specified header as an integer. If
|
|
* multiple values are present, the last one is returned.
|
|
*
|
|
* @param header the header name (case insensitive search)
|
|
* @return The header value or <code>-1</code> if not present or
|
|
* not an integer value.
|
|
*/
|
|
public int getIntValue(String header)
|
|
{
|
|
String val = getValue(header);
|
|
if (val == null)
|
|
{
|
|
return -1;
|
|
}
|
|
try
|
|
{
|
|
return Integer.parseInt(val);
|
|
}
|
|
catch (NumberFormatException e)
|
|
{
|
|
// fall through
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the specified header as a long. If
|
|
* multiple values are present, the last one is returned.
|
|
*
|
|
* @param header the header name (case insensitive search)
|
|
* @return The header value or <code>-1</code> if not present or
|
|
* not a long value.
|
|
*/
|
|
public long getLongValue(String header)
|
|
{
|
|
String val = getValue(header);
|
|
if (val == null)
|
|
{
|
|
return -1;
|
|
}
|
|
try
|
|
{
|
|
return Long.parseLong(val);
|
|
}
|
|
catch (NumberFormatException e)
|
|
{
|
|
// fall through
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the specified header as a date. If
|
|
* multiple values are present, the last one is returned.
|
|
*
|
|
* @param header the header name (case insensitive search)
|
|
* @return The header value or <code>null</code> if not present or
|
|
* not a date value.
|
|
*/
|
|
public Date getDateValue(String header)
|
|
{
|
|
String val = getValue(header);
|
|
if (val == null)
|
|
{
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
return dateFormat.parse(val);
|
|
}
|
|
catch (ParseException e)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a header to this set of headers. If there is an existing
|
|
* header with the same name it's value is replaced with the new value.
|
|
* If multiple headers of the same name exist only the last one's value
|
|
* is replaced.
|
|
*
|
|
* @param name the header name
|
|
* @param value the header value
|
|
*
|
|
* @see #addValue(String, String)
|
|
*/
|
|
public void put(String name, String value)
|
|
{
|
|
for (int i = headers.size() - 1; i >= 0; i--)
|
|
{
|
|
HeaderElement e = (HeaderElement)headers.get(i);
|
|
if (e.name.equalsIgnoreCase(name))
|
|
{
|
|
e.value = value;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// nothing was replaced so add it as new HeaderElement
|
|
addValue(name, value);
|
|
}
|
|
|
|
/**
|
|
* Add all headers from a set of headers to this set. Any existing header
|
|
* with the same (case insensitive) name as one of the new headers will
|
|
* be overridden.
|
|
*
|
|
* @param o the headers to be added
|
|
*/
|
|
public void putAll(Headers o)
|
|
{
|
|
for (Iterator it = o.iterator(); it.hasNext(); )
|
|
{
|
|
HeaderElement e = (HeaderElement)it.next();
|
|
remove(e.name);
|
|
addValue(e.name, e.value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
for (Iterator it = headers.iterator(); it.hasNext(); )
|
|
{
|
|
HeaderElement e = (HeaderElement)it.next();
|
|
if (e.name.equalsIgnoreCase(name))
|
|
it.remove();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parse the specified InputStream, adding headers to this collection.
|
|
*
|
|
* @param in the InputStream.
|
|
* @throws IOException if I/O error occured.
|
|
*/
|
|
public void parse(InputStream in)
|
|
throws IOException
|
|
{
|
|
LineInputStream lin = (in instanceof LineInputStream) ?
|
|
(LineInputStream) in : new LineInputStream(in);
|
|
|
|
String name = null;
|
|
StringBuilder value = new StringBuilder();
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 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(String, String)
|
|
*/
|
|
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 headers will be included
|
|
* case-sensitive in the map so that querying must be done with the
|
|
* correct case of the needed header name. 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.</p>
|
|
*
|
|
* @return a Map containing all the headers.
|
|
*/
|
|
public Map getAsMap()
|
|
{
|
|
LinkedHashMap m = new LinkedHashMap();
|
|
for (Iterator it = headers.iterator(); it.hasNext(); )
|
|
{
|
|
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);
|
|
}
|
|
for (Iterator it = m.entrySet().iterator(); it.hasNext(); )
|
|
{
|
|
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, or <code>null</code> if index outside of range.
|
|
*
|
|
* @see #getHeaderValue(int)
|
|
*/
|
|
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, or <code>null</code> if index outside of range.
|
|
*
|
|
* @see #getHeaderName(int)
|
|
*/
|
|
public String getHeaderValue(int i)
|
|
{
|
|
if (i >= headers.size() || i < 0)
|
|
return null;
|
|
|
|
return ((HeaderElement)headers.get(i)).value;
|
|
}
|
|
|
|
}
|
|
|