View Javadoc

1   /*
2    * $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 $
3    * $Revision: 155418 $
4    * $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   */
29  
30  package org.apache.commons.httpclient;
31  
32  import java.util.ArrayList;
33  import java.util.List;
34  
35  import org.apache.commons.httpclient.util.ParameterParser;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  /***
40   * <p>One element of an HTTP header's value.</p>
41   * <p>
42   * Some HTTP headers (such as the set-cookie header) have values that
43   * can be decomposed into multiple elements.  Such headers must be in the
44   * following form:
45   * </p>
46   * <pre>
47   * header  = [ element ] *( "," [ element ] )
48   * element = name [ "=" [ value ] ] *( ";" [ param ] )
49   * param   = name [ "=" [ value ] ]
50   *
51   * name    = token
52   * value   = ( token | quoted-string )
53   *
54   * token         = 1*&lt;any char except "=", ",", ";", &lt;"&gt; and
55   *                       white space&gt;
56   * quoted-string = &lt;"&gt; *( text | quoted-char ) &lt;"&gt;
57   * text          = any char except &lt;"&gt;
58   * quoted-char   = "\" char
59   * </pre>
60   * <p>
61   * Any amount of white space is allowed between any part of the
62   * header, element or param and is ignored. A missing value in any
63   * element or param will be stored as the empty {@link String};
64   * if the "=" is also missing <var>null</var> will be stored instead.
65   * </p>
66   * <p>
67   * This class represents an individual header element, containing
68   * both a name/value pair (value may be <tt>null</tt>) and optionally
69   * a set of additional parameters.
70   * </p>
71   * <p>
72   * This class also exposes a {@link #parse} method for parsing a
73   * {@link Header} value into an array of elements.
74   * </p>
75   *
76   * @see Header
77   *
78   * @author <a href="mailto:bcholmes@interlog.com">B.C. Holmes</a>
79   * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
80   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
81   * @author <a href="mailto:oleg@ural.com">Oleg Kalnichevski</a>
82   * 
83   * @since 1.0
84   * @version $Revision: 155418 $ $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
85   */
86  public class HeaderElement extends NameValuePair {
87  
88      // ----------------------------------------------------------- Constructors
89  
90      /***
91       * Default constructor.
92       */
93      public HeaderElement() {
94          this(null, null, null);
95      }
96  
97      /***
98        * Constructor.
99        * @param name my name
100       * @param value my (possibly <tt>null</tt>) value
101       */
102     public HeaderElement(String name, String value) {
103         this(name, value, null);
104     }
105 
106     /***
107      * Constructor with name, value and parameters.
108      *
109      * @param name my name
110      * @param value my (possibly <tt>null</tt>) value
111      * @param parameters my (possibly <tt>null</tt>) parameters
112      */
113     public HeaderElement(String name, String value,
114             NameValuePair[] parameters) {
115         super(name, value);
116         this.parameters = parameters;
117     }
118 
119     /***
120      * Constructor with array of characters.
121      *
122      * @param chars the array of characters
123      * @param offset - the initial offset.
124      * @param length - the length.
125      * 
126      * @since 3.0
127      */
128     public HeaderElement(char[] chars, int offset, int length) {
129         this();
130         if (chars == null) {
131             return;
132         }
133         ParameterParser parser = new ParameterParser();
134         List params = parser.parse(chars, offset, length, ';');
135         if (params.size() > 0) {
136             NameValuePair element = (NameValuePair) params.remove(0);
137             setName(element.getName());  
138             setValue(element.getValue());
139             if (params.size() > 0) {
140                 this.parameters = (NameValuePair[])
141                     params.toArray(new NameValuePair[params.size()]);    
142             }
143         }
144     }
145 
146     /***
147      * Constructor with array of characters.
148      *
149      * @param chars the array of characters
150      * 
151      * @since 3.0
152      */
153     public HeaderElement(char[] chars) {
154         this(chars, 0, chars.length);
155     }
156 
157     // -------------------------------------------------------- Constants
158 
159     /*** Log object for this class. */
160     private static final Log LOG = LogFactory.getLog(HeaderElement.class);
161 
162     // ----------------------------------------------------- Instance Variables
163 
164     /*** My parameters, if any. */
165     private NameValuePair[] parameters = null;
166 
167     // ------------------------------------------------------------- Properties
168 
169     /***
170      * Get parameters, if any.
171      *
172      * @since 2.0
173      * @return parameters as an array of {@link NameValuePair}s
174      */
175     public NameValuePair[] getParameters() {
176         return this.parameters;
177     }
178 
179     // --------------------------------------------------------- Public Methods
180 
181     /***
182      * This parses the value part of a header. The result is an array of
183      * HeaderElement objects.
184      *
185      * @param headerValue  the array of char representation of the header value
186      *                     (as received from the web server).
187      * @return array of {@link HeaderElement}s.
188      * 
189      * @since 3.0
190      */
191     public static final HeaderElement[] parseElements(char[] headerValue) {
192             
193         LOG.trace("enter HeaderElement.parseElements(char[])");
194 
195         if (headerValue == null) {
196             return new HeaderElement[] {};
197         }
198         List elements = new ArrayList(); 
199         
200         int i = 0;
201         int from = 0;
202         int len = headerValue.length;
203         boolean qouted = false;
204         while (i < len) {
205             char ch = headerValue[i];
206             if (ch == '"') {
207                 qouted = !qouted;
208             }
209             HeaderElement element = null;
210             if ((!qouted) && (ch == ',')) {
211                 element = new HeaderElement(headerValue, from, i);
212                 from = i + 1;
213             } else if (i == len - 1) {
214                 element = new HeaderElement(headerValue, from, len);
215             }
216             if ((element != null) && (element.getName() != null)) {
217                 elements.add(element);
218             }
219             i++;
220         }
221         return (HeaderElement[])
222             elements.toArray(new HeaderElement[elements.size()]);
223     }
224 
225     /***
226      * This parses the value part of a header. The result is an array of
227      * HeaderElement objects.
228      *
229      * @param headerValue  the string representation of the header value
230      *                     (as received from the web server).
231      * @return array of {@link HeaderElement}s.
232      * 
233      * @since 3.0
234      */
235     public static final HeaderElement[] parseElements(String headerValue) {
236             
237         LOG.trace("enter HeaderElement.parseElements(String)");
238 
239         if (headerValue == null) {
240             return new HeaderElement[] {};
241         }
242         return parseElements(headerValue.toCharArray());
243     }
244 
245     /***
246      * This parses the value part of a header. The result is an array of
247      * HeaderElement objects.
248      *
249      * @param headerValue  the string representation of the header value
250      *                     (as received from the web server).
251      * @return array of {@link HeaderElement}s.
252      * @throws HttpException if the above syntax rules are violated.
253      * 
254      * @deprecated Use #parseElements(String).
255      */
256     public static final HeaderElement[] parse(String headerValue)
257         throws HttpException {
258             
259         LOG.trace("enter HeaderElement.parse(String)");
260 
261         if (headerValue == null) {
262             return new HeaderElement[] {};
263         }
264         return parseElements(headerValue.toCharArray());
265     }
266          
267 
268     /***
269      * Returns parameter with the given name, if found. Otherwise null 
270      * is returned
271      *
272      * @param name The name to search by.
273      * @return NameValuePair parameter with the given name
274      */
275 
276     public NameValuePair getParameterByName(String name) {
277 
278         LOG.trace("enter HeaderElement.getParameterByName(String)");
279 
280         if (name == null) {
281             throw new IllegalArgumentException("Name may not be null");
282         } 
283         NameValuePair found = null;
284         NameValuePair parameters[] = getParameters();
285         if (parameters != null) {
286             for (int i = 0; i < parameters.length; i++) {
287                 NameValuePair current = parameters[ i ];
288                 if (current.getName().equalsIgnoreCase(name)) {
289                     found = current;
290                     break;
291                 }
292             }
293         }
294         return found;
295     }
296 
297 }
298