Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/http/HeaderElement.java


1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/tags/4.0-alpha2/src/java/org/apache/http/HeaderElement.java $
3    * $Revision: 409980 $
4    * $Date: 2006-05-28 21:45:06 +0200 (Sun, 28 May 2006) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2006 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.http;
31  
32  import java.util.ArrayList;
33  import java.util.List;
34  
35  import org.apache.http.io.CharArrayBuffer;
36  import org.apache.http.util.LangUtils;
37  
38  /**
39   * <p>One element of an HTTP header's value.</p>
40   * <p>
41   * Some HTTP headers (such as the set-cookie header) have values that
42   * can be decomposed into multiple elements.  Such headers must be in the
43   * following form:
44   * </p>
45   * <pre>
46   * header  = [ element ] *( "," [ element ] )
47   * element = name [ "=" [ value ] ] *( ";" [ param ] )
48   * param   = name [ "=" [ value ] ]
49   *
50   * name    = token
51   * value   = ( token | quoted-string )
52   *
53   * token         = 1*&lt;any char except "=", ",", ";", &lt;"&gt; and
54   *                       white space&gt;
55   * quoted-string = &lt;"&gt; *( text | quoted-char ) &lt;"&gt;
56   * text          = any char except &lt;"&gt;
57   * quoted-char   = "\" char
58   * </pre>
59   * <p>
60   * Any amount of white space is allowed between any part of the
61   * header, element or param and is ignored. A missing value in any
62   * element or param will be stored as the empty {@link String};
63   * if the "=" is also missing <var>null</var> will be stored instead.
64   * </p>
65   * <p>
66   * This class represents an individual header element, containing
67   * both a name/value pair (value may be <tt>null</tt>) and optionally
68   * a set of additional parameters.
69   * </p>
70   * <p>
71   * This class also exposes a {@link #parse} method for parsing a
72   * {@link Header} value into an array of elements.
73   * </p>
74   *
75   * @see Header
76   *
77   * @author <a href="mailto:bcholmes@interlog.com">B.C. Holmes</a>
78   * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
79   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
80   * @author <a href="mailto:oleg at ural.com">Oleg Kalnichevski</a>
81   * 
82   * @since 1.0
83   * @version $Revision: 409980 $ $Date: 2006-05-28 21:45:06 +0200 (Sun, 28 May 2006) $
84   */
85  public class HeaderElement {
86  
87      private final String name;
88      private final String value;
89      private final NameValuePair[] parameters;
90  
91      private HeaderElement(final NameValuePair[] nvps) {
92          super();
93          if (nvps.length > 0) {
94              NameValuePair nvp = nvps[0];
95              this.name = nvp.getName();
96              this.value = nvp.getValue();
97              int len = nvps.length - 1; 
98              if (len > 0) {
99                  this.parameters = new NameValuePair[len];
100                 System.arraycopy(nvps, 1, this.parameters, 0, len);
101             } else {
102                 this.parameters = new NameValuePair[] {}; 
103             }
104         } else {
105             this.name = "";
106             this.value = null;
107             this.parameters = new NameValuePair[] {}; 
108         }
109     }
110     
111     /**
112      * Constructor with name, value and parameters.
113      *
114      * @param name header element name
115      * @param value header element value. May be <tt>null</tt>
116      * @param parameters header element parameters. May be <tt>null</tt>
117      */
118     public HeaderElement(
119             final String name, 
120             final String value,
121             final NameValuePair[] parameters) {
122         super();
123         if (name == null) {
124             throw new IllegalArgumentException("Name may not be null");
125         }
126         this.name = name;
127         this.value = value;
128         if (parameters != null) {
129             this.parameters = (NameValuePair[])parameters.clone();
130         } else {
131             this.parameters = new NameValuePair[] {};
132         }
133     }
134 
135     /**
136      * Constructor with name and value.
137      * 
138      * @param name header element name
139      * @param value header element value. May be <tt>null</tt>
140      */
141     public HeaderElement(final String name, final String value) {
142        this(name, value, null);
143     }
144 
145     /**
146      * Returns the name.
147      *
148      * @return String name The name
149      */
150     public String getName() {
151         return this.name;
152     }
153 
154     /**
155      * Returns the value.
156      *
157      * @return String value The current value.
158      */
159     public String getValue() {
160         return this.value;
161     }
162 
163     /**
164      * Get parameters, if any.
165      *
166      * @since 2.0
167      * @return parameters as an array of {@link NameValuePair}s
168      */
169     public NameValuePair[] getParameters() {
170         return (NameValuePair[])this.parameters.clone();
171     }
172 
173     // --------------------------------------------------------- Public Methods
174 
175     /**
176      * This parses the value part of a header. The result is an array of
177      * HeaderElement objects.
178      *
179      * @param buffer    the buffer from which to parse
180      * @param indexFrom where to start parsing in the buffer
181      * @param indexTo   where to stop parsing in the buffer
182      *
183      * @return array of {@link HeaderElement}s.
184      * 
185      * @since 3.0
186      */
187     public static final HeaderElement[] parseAll(
188             final CharArrayBuffer buffer, final int indexFrom, final int indexTo) {
189         if (buffer == null) {
190             throw new IllegalArgumentException("Char array buffer may not be null");
191         }
192         if (indexFrom < 0) {
193             throw new IndexOutOfBoundsException();
194         }
195         if (indexTo > buffer.length()) {
196             throw new IndexOutOfBoundsException();
197         }
198         if (indexFrom > indexTo) {
199             throw new IndexOutOfBoundsException();
200         }
201         List elements = new ArrayList(); 
202         int cur = indexFrom;
203         int from = indexFrom;
204         boolean qouted = false;
205         boolean escaped = false;
206         while (cur < indexTo) {
207             char ch = buffer.charAt(cur);
208             if (ch == '"' && !escaped) {
209                 qouted = !qouted;
210             }
211             HeaderElement element = null;
212             if ((!qouted) && (ch == ',')) {
213                 element = parse(buffer, from, cur);
214                 from = cur + 1;
215             } else if (cur == indexTo - 1) {
216                 element = parse(buffer, from, indexTo);
217             }
218             if (element != null && !(element.getName().equals("") && element.getValue() == null)) {
219                 elements.add(element);
220             }
221             if (escaped) {
222                 escaped = false;
223             } else {
224                 escaped = qouted && ch == '\\';
225             }
226             cur++;
227         }
228         return (HeaderElement[])
229             elements.toArray(new HeaderElement[elements.size()]);
230     }
231 
232     /**
233      * This parses the value part of a header. The result is an array of
234      * HeaderElement objects.
235      *
236      * @param s  the string representation of the header value
237      *                     (as received from the web server).
238      * @return array of {@link HeaderElement}s.
239      * 
240      * @since 3.0
241      */
242     public static final HeaderElement[] parseAll(final String s) {
243         if (s == null) {
244             throw new IllegalArgumentException("String may not be null");
245         }
246         CharArrayBuffer buffer = new CharArrayBuffer(s.length()); 
247         buffer.append(s);
248         return parseAll(buffer, 0, buffer.length());
249     }
250 
251     public static HeaderElement parse(
252             final CharArrayBuffer buffer, final int indexFrom, final int indexTo) {
253         if (buffer == null) {
254             throw new IllegalArgumentException("Char array buffer may not be null");
255         }
256         if (indexFrom < 0) {
257             throw new IndexOutOfBoundsException();
258         }
259         if (indexTo > buffer.length()) {
260             throw new IndexOutOfBoundsException();
261         }
262         if (indexFrom > indexTo) {
263             throw new IndexOutOfBoundsException();
264         }
265         NameValuePair[] nvps = NameValuePair.parseAll(buffer, indexFrom, indexTo);
266         return new HeaderElement(nvps);
267     }
268 
269     public static final HeaderElement parse(final String s) {
270         if (s == null) {
271             throw new IllegalArgumentException("String may not be null");
272         }
273         CharArrayBuffer buffer = new CharArrayBuffer(s.length());
274         buffer.append(s);
275         return parse(buffer, 0, buffer.length());
276     }
277 
278     public static void format(
279             final CharArrayBuffer buffer, 
280             final HeaderElement element) {
281         if (buffer == null) {
282             throw new IllegalArgumentException("String buffer may not be null");
283         }
284         if (element == null) {
285             throw new IllegalArgumentException("Header element may not be null");
286         }
287         buffer.append(element.getName());
288         if (element.getValue() != null) {
289             buffer.append("=");
290             buffer.append(element.getValue());
291         }
292         NameValuePair[] params = element.getParameters();
293         for (int i = 0; i < params.length; i++) {
294             buffer.append("; ");
295             NameValuePair.format(buffer, params[i], false);
296         }
297     }
298     
299     public static String format(final HeaderElement element) {
300         CharArrayBuffer buffer = new CharArrayBuffer(32);
301         format(buffer, element);
302         return buffer.toString();
303     }
304     
305     public static void formatAll(
306             final CharArrayBuffer buffer, 
307             final HeaderElement[] elements) {
308         if (buffer == null) {
309             throw new IllegalArgumentException("String buffer may not be null");
310         }
311         if (elements == null) {
312             throw new IllegalArgumentException("Array of header element may not be null");
313         }
314         for (int i = 0; i < elements.length; i++) {
315             if (i > 0) {
316                 buffer.append(", ");
317             }
318             format(buffer, elements[i]);
319         }
320     }
321     
322     public static String formatAll(final HeaderElement[] elements) {
323         CharArrayBuffer buffer = new CharArrayBuffer(64);
324         formatAll(buffer, elements);
325         return buffer.toString();
326     }
327     
328     /**
329      * Returns parameter with the given name, if found. Otherwise null 
330      * is returned
331      *
332      * @param name The name to search by.
333      * @return NameValuePair parameter with the given name
334      */
335     public NameValuePair getParameterByName(final String name) {
336         if (name == null) {
337             throw new IllegalArgumentException("Name may not be null");
338         } 
339         NameValuePair found = null;
340         for (int i = 0; i < this.parameters.length; i++) {
341             NameValuePair current = this.parameters[ i ];
342             if (current.getName().equalsIgnoreCase(name)) {
343                 found = current;
344                 break;
345             }
346         }
347         return found;
348     }
349 
350     public boolean equals(final Object object) {
351         if (object == null) return false;
352         if (this == object) return true;
353         if (object instanceof HeaderElement) {
354             HeaderElement that = (HeaderElement) object;
355             return this.name.equals(that.name)
356                 && LangUtils.equals(this.value, that.value)
357                 && LangUtils.equals(this.parameters, that.parameters);
358         } else {
359             return false;
360         }
361     }
362 
363     public int hashCode() {
364         int hash = LangUtils.HASH_SEED;
365         hash = LangUtils.hashCode(hash, this.name);
366         hash = LangUtils.hashCode(hash, this.value);
367         for (int i = 0; i < this.parameters.length; i++) {
368             hash = LangUtils.hashCode(hash, this.parameters[i]);
369         }
370         return hash;
371     }
372     
373     public String toString() {
374         CharArrayBuffer buffer = new CharArrayBuffer(64);
375         buffer.append(this.name);
376         if (this.value != null) {
377             buffer.append("=");
378             buffer.append(this.value);
379         }
380         for (int i = 0; i < this.parameters.length; i++) {
381             buffer.append("; ");
382             buffer.append(this.parameters[i]);
383         }
384         return buffer.toString();
385     }
386     
387 }
388