001: /*
002: * $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 $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient;
032:
033: import java.util.ArrayList;
034: import java.util.List;
035:
036: import org.apache.commons.httpclient.util.ParameterParser;
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039:
040: /**
041: * <p>One element of an HTTP header's value.</p>
042: * <p>
043: * Some HTTP headers (such as the set-cookie header) have values that
044: * can be decomposed into multiple elements. Such headers must be in the
045: * following form:
046: * </p>
047: * <pre>
048: * header = [ element ] *( "," [ element ] )
049: * element = name [ "=" [ value ] ] *( ";" [ param ] )
050: * param = name [ "=" [ value ] ]
051: *
052: * name = token
053: * value = ( token | quoted-string )
054: *
055: * token = 1*<any char except "=", ",", ";", <"> and
056: * white space>
057: * quoted-string = <"> *( text | quoted-char ) <">
058: * text = any char except <">
059: * quoted-char = "\" char
060: * </pre>
061: * <p>
062: * Any amount of white space is allowed between any part of the
063: * header, element or param and is ignored. A missing value in any
064: * element or param will be stored as the empty {@link String};
065: * if the "=" is also missing <var>null</var> will be stored instead.
066: * </p>
067: * <p>
068: * This class represents an individual header element, containing
069: * both a name/value pair (value may be <tt>null</tt>) and optionally
070: * a set of additional parameters.
071: * </p>
072: * <p>
073: * This class also exposes a {@link #parse} method for parsing a
074: * {@link Header} value into an array of elements.
075: * </p>
076: *
077: * @see Header
078: *
079: * @author <a href="mailto:bcholmes@interlog.com">B.C. Holmes</a>
080: * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
081: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
082: * @author <a href="mailto:oleg@ural.com">Oleg Kalnichevski</a>
083: *
084: * @since 1.0
085: * @version $Revision: 480424 $ $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
086: */
087: public class HeaderElement extends NameValuePair {
088:
089: // ----------------------------------------------------------- Constructors
090:
091: /**
092: * Default constructor.
093: */
094: public HeaderElement() {
095: this (null, null, null);
096: }
097:
098: /**
099: * Constructor.
100: * @param name my name
101: * @param value my (possibly <tt>null</tt>) value
102: */
103: public HeaderElement(String name, String value) {
104: this (name, value, null);
105: }
106:
107: /**
108: * Constructor with name, value and parameters.
109: *
110: * @param name my name
111: * @param value my (possibly <tt>null</tt>) value
112: * @param parameters my (possibly <tt>null</tt>) parameters
113: */
114: public HeaderElement(String name, String value,
115: NameValuePair[] parameters) {
116: super (name, value);
117: this .parameters = parameters;
118: }
119:
120: /**
121: * Constructor with array of characters.
122: *
123: * @param chars the array of characters
124: * @param offset - the initial offset.
125: * @param length - the length.
126: *
127: * @since 3.0
128: */
129: public HeaderElement(char[] chars, int offset, int length) {
130: this ();
131: if (chars == null) {
132: return;
133: }
134: ParameterParser parser = new ParameterParser();
135: List params = parser.parse(chars, offset, length, ';');
136: if (params.size() > 0) {
137: NameValuePair element = (NameValuePair) params.remove(0);
138: setName(element.getName());
139: setValue(element.getValue());
140: if (params.size() > 0) {
141: this .parameters = (NameValuePair[]) params
142: .toArray(new NameValuePair[params.size()]);
143: }
144: }
145: }
146:
147: /**
148: * Constructor with array of characters.
149: *
150: * @param chars the array of characters
151: *
152: * @since 3.0
153: */
154: public HeaderElement(char[] chars) {
155: this (chars, 0, chars.length);
156: }
157:
158: // -------------------------------------------------------- Constants
159:
160: /** Log object for this class. */
161: private static final Log LOG = LogFactory
162: .getLog(HeaderElement.class);
163:
164: // ----------------------------------------------------- Instance Variables
165:
166: /** My parameters, if any. */
167: private NameValuePair[] parameters = null;
168:
169: // ------------------------------------------------------------- Properties
170:
171: /**
172: * Get parameters, if any.
173: *
174: * @since 2.0
175: * @return parameters as an array of {@link NameValuePair}s
176: */
177: public NameValuePair[] getParameters() {
178: return this .parameters;
179: }
180:
181: // --------------------------------------------------------- Public Methods
182:
183: /**
184: * This parses the value part of a header. The result is an array of
185: * HeaderElement objects.
186: *
187: * @param headerValue the array of char representation of the header value
188: * (as received from the web server).
189: * @return array of {@link HeaderElement}s.
190: *
191: * @since 3.0
192: */
193: public static final HeaderElement[] parseElements(char[] headerValue) {
194:
195: LOG.trace("enter HeaderElement.parseElements(char[])");
196:
197: if (headerValue == null) {
198: return new HeaderElement[] {};
199: }
200: List elements = new ArrayList();
201:
202: int i = 0;
203: int from = 0;
204: int len = headerValue.length;
205: boolean qouted = false;
206: while (i < len) {
207: char ch = headerValue[i];
208: if (ch == '"') {
209: qouted = !qouted;
210: }
211: HeaderElement element = null;
212: if ((!qouted) && (ch == ',')) {
213: element = new HeaderElement(headerValue, from, i);
214: from = i + 1;
215: } else if (i == len - 1) {
216: element = new HeaderElement(headerValue, from, len);
217: }
218: if ((element != null) && (element.getName() != null)) {
219: elements.add(element);
220: }
221: i++;
222: }
223: return (HeaderElement[]) elements
224: .toArray(new HeaderElement[elements.size()]);
225: }
226:
227: /**
228: * This parses the value part of a header. The result is an array of
229: * HeaderElement objects.
230: *
231: * @param headerValue the string representation of the header value
232: * (as received from the web server).
233: * @return array of {@link HeaderElement}s.
234: *
235: * @since 3.0
236: */
237: public static final HeaderElement[] parseElements(String headerValue) {
238:
239: LOG.trace("enter HeaderElement.parseElements(String)");
240:
241: if (headerValue == null) {
242: return new HeaderElement[] {};
243: }
244: return parseElements(headerValue.toCharArray());
245: }
246:
247: /**
248: * This parses the value part of a header. The result is an array of
249: * HeaderElement objects.
250: *
251: * @param headerValue the string representation of the header value
252: * (as received from the web server).
253: * @return array of {@link HeaderElement}s.
254: * @throws HttpException if the above syntax rules are violated.
255: *
256: * @deprecated Use #parseElements(String).
257: */
258: public static final HeaderElement[] parse(String headerValue)
259: throws HttpException {
260:
261: LOG.trace("enter HeaderElement.parse(String)");
262:
263: if (headerValue == null) {
264: return new HeaderElement[] {};
265: }
266: return parseElements(headerValue.toCharArray());
267: }
268:
269: /**
270: * Returns parameter with the given name, if found. Otherwise null
271: * is returned
272: *
273: * @param name The name to search by.
274: * @return NameValuePair parameter with the given name
275: */
276:
277: public NameValuePair getParameterByName(String name) {
278:
279: LOG.trace("enter HeaderElement.getParameterByName(String)");
280:
281: if (name == null) {
282: throw new IllegalArgumentException("Name may not be null");
283: }
284: NameValuePair found = null;
285: NameValuePair parameters[] = getParameters();
286: if (parameters != null) {
287: for (int i = 0; i < parameters.length; i++) {
288: NameValuePair current = parameters[i];
289: if (current.getName().equalsIgnoreCase(name)) {
290: found = current;
291: break;
292: }
293: }
294: }
295: return found;
296: }
297:
298: }
|