1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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*<any char except "=", ",", ";", <"> and
55 * white space>
56 * quoted-string = <"> *( text | quoted-char ) <">
57 * text = any char except <">
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
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
158
159 /*** Log object for this class. */
160 private static final Log LOG = LogFactory.getLog(HeaderElement.class);
161
162
163
164 /*** My parameters, if any. */
165 private NameValuePair[] parameters = null;
166
167
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
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