/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/HeaderElement.java,v 1.23 2004/05/13 04:03:25 mbecke Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.httpclient;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.httpclient.util.ParameterParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <p>One element of an HTTP header's value.</p>
* <p>
* Some HTTP headers (such as the set-cookie header) have values that
* can be decomposed into multiple elements. Such headers must be in the
* following form:
* </p>
* <pre>
* header = [ element ] *( "," [ element ] )
* element = name [ "=" [ value ] ] *( ";" [ param ] )
* param = name [ "=" [ value ] ]
*
* name = token
* value = ( token | quoted-string )
*
* token = 1*<any char except "=", ",", ";", <"> and
* white space>
* quoted-string = <"> *( text | quoted-char ) <">
* text = any char except <">
* quoted-char = "\" char
* </pre>
* <p>
* Any amount of white space is allowed between any part of the
* header, element or param and is ignored. A missing value in any
* element or param will be stored as the empty {@link String};
* if the "=" is also missing <var>null</var> will be stored instead.
* </p>
* <p>
* This class represents an individual header element, containing
* both a name/value pair (value may be <tt>null</tt>) and optionally
* a set of additional parameters.
* </p>
* <p>
* This class also exposes a {@link #parse} method for parsing a
* {@link Header} value into an array of elements.
* </p>
*
* @see Header
*
* @author <a href="mailto:[email protected]">B.C. Holmes</a>
* @author <a href="mailto:[email protected]">Park, Sung-Gu</a>
* @author <a href="mailto:[email protected]">Mike Bowler</a>
* @author <a href="mailto:[email protected]">Oleg Kalnichevski</a>
*
* @since 1.0
* @version $Revision: 480424 $ $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*/
public class HeaderElement extends NameValuePair {
// ----------------------------------------------------------- Constructors
/**
* Default constructor.
*/
public HeaderElement() {
this(null, null, null);
}
/**
* Constructor.
* @param name my name
* @param value my (possibly <tt>null</tt>) value
*/
public HeaderElement(String name, String value) {
this(name, value, null);
}
/**
* Constructor with name, value and parameters.
*
* @param name my name
* @param value my (possibly <tt>null</tt>) value
* @param parameters my (possibly <tt>null</tt>) parameters
*/
public HeaderElement(String name, String value,
NameValuePair[] parameters) {
super(name, value);
this.parameters = parameters;
}
/**
* Constructor with array of characters.
*
* @param chars the array of characters
* @param offset - the initial offset.
* @param length - the length.
*
* @since 3.0
*/
public HeaderElement(char[] chars, int offset, int length) {
this();
if (chars == null) {
return;
}
ParameterParser parser = new ParameterParser();
List params = parser.parse(chars, offset, length, ';');
if (params.size() > 0) {
NameValuePair element = (NameValuePair) params.remove(0);
setName(element.getName());
setValue(element.getValue());
if (params.size() > 0) {
this.parameters = (NameValuePair[])
params.toArray(new NameValuePair[params.size()]);
}
}
}
/**
* Constructor with array of characters.
*
* @param chars the array of characters
*
* @since 3.0
*/
public HeaderElement(char[] chars) {
this(chars, 0, chars.length);
}
// -------------------------------------------------------- Constants
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(HeaderElement.class);
// ----------------------------------------------------- Instance Variables
/** My parameters, if any. */
private NameValuePair[] parameters = null;
// ------------------------------------------------------------- Properties
/**
* Get parameters, if any.
*
* @since 2.0
* @return parameters as an array of {@link NameValuePair}s
*/
public NameValuePair[] getParameters() {
return this.parameters;
}
// --------------------------------------------------------- Public Methods
/**
* This parses the value part of a header. The result is an array of
* HeaderElement objects.
*
* @param headerValue the array of char representation of the header value
* (as received from the web server).
* @return array of {@link HeaderElement}s.
*
* @since 3.0
*/
public static final HeaderElement[] parseElements(char[] headerValue) {
LOG.trace("enter HeaderElement.parseElements(char[])");
if (headerValue == null) {
return new HeaderElement[] {};
}
List elements = new ArrayList();
int i = 0;
int from = 0;
int len = headerValue.length;
boolean qouted = false;
while (i < len) {
char ch = headerValue[i];
if (ch == '"') {
qouted = !qouted;
}
HeaderElement element = null;
if ((!qouted) && (ch == ',')) {
element = new HeaderElement(headerValue, from, i);
from = i + 1;
} else if (i == len - 1) {
element = new HeaderElement(headerValue, from, len);
}
if ((element != null) && (element.getName() != null)) {
elements.add(element);
}
i++;
}
return (HeaderElement[])
elements.toArray(new HeaderElement[elements.size()]);
}
/**
* This parses the value part of a header. The result is an array of
* HeaderElement objects.
*
* @param headerValue the string representation of the header value
* (as received from the web server).
* @return array of {@link HeaderElement}s.
*
* @since 3.0
*/
public static final HeaderElement[] parseElements(String headerValue) {
LOG.trace("enter HeaderElement.parseElements(String)");
if (headerValue == null) {
return new HeaderElement[] {};
}
return parseElements(headerValue.toCharArray());
}
/**
* This parses the value part of a header. The result is an array of
* HeaderElement objects.
*
* @param headerValue the string representation of the header value
* (as received from the web server).
* @return array of {@link HeaderElement}s.
* @throws HttpException if the above syntax rules are violated.
*
* @deprecated Use #parseElements(String).
*/
public static final HeaderElement[] parse(String headerValue)
throws HttpException {
LOG.trace("enter HeaderElement.parse(String)");
if (headerValue == null) {
return new HeaderElement[] {};
}
return parseElements(headerValue.toCharArray());
}
/**
* Returns parameter with the given name, if found. Otherwise null
* is returned
*
* @param name The name to search by.
* @return NameValuePair parameter with the given name
*/
public NameValuePair getParameterByName(String name) {
LOG.trace("enter HeaderElement.getParameterByName(String)");
if (name == null) {
throw new IllegalArgumentException("Name may not be null");
}
NameValuePair found = null;
NameValuePair parameters[] = getParameters();
if (parameters != null) {
for (int i = 0; i < parameters.length; i++) {
NameValuePair current = parameters[ i ];
if (current.getName().equalsIgnoreCase(name)) {
found = current;
break;
}
}
}
return found;
}
}
|