1. /*
  2. * $Header: /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: 1.23 $
  4. * $Date: 2004/05/13 04:03:25 $
  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. package org.apache.commons.httpclient;
  30. import java.util.ArrayList;
  31. import java.util.List;
  32. import org.apache.commons.httpclient.util.ParameterParser;
  33. import org.apache.commons.logging.Log;
  34. import org.apache.commons.logging.LogFactory;
  35. /**
  36. * <p>One element of an HTTP header's value.</p>
  37. * <p>
  38. * Some HTTP headers (such as the set-cookie header) have values that
  39. * can be decomposed into multiple elements. Such headers must be in the
  40. * following form:
  41. * </p>
  42. * <pre>
  43. * header = [ element ] *( "," [ element ] )
  44. * element = name [ "=" [ value ] ] *( ";" [ param ] )
  45. * param = name [ "=" [ value ] ]
  46. *
  47. * name = token
  48. * value = ( token | quoted-string )
  49. *
  50. * token = 1*<any char except "=", ",", ";", <"> and
  51. * white space>
  52. * quoted-string = <"> *( text | quoted-char ) <">
  53. * text = any char except <">
  54. * quoted-char = "\" char
  55. * </pre>
  56. * <p>
  57. * Any amount of white space is allowed between any part of the
  58. * header, element or param and is ignored. A missing value in any
  59. * element or param will be stored as the empty {@link String};
  60. * if the "=" is also missing <var>null</var> will be stored instead.
  61. * </p>
  62. * <p>
  63. * This class represents an individual header element, containing
  64. * both a name/value pair (value may be <tt>null</tt>) and optionally
  65. * a set of additional parameters.
  66. * </p>
  67. * <p>
  68. * This class also exposes a {@link #parse} method for parsing a
  69. * {@link Header} value into an array of elements.
  70. * </p>
  71. *
  72. * @see Header
  73. *
  74. * @author <a href="mailto:bcholmes@interlog.com">B.C. Holmes</a>
  75. * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
  76. * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
  77. * @author <a href="mailto:oleg@ural.com">Oleg Kalnichevski</a>
  78. *
  79. * @since 1.0
  80. * @version $Revision: 1.23 $ $Date: 2004/05/13 04:03:25 $
  81. */
  82. public class HeaderElement extends NameValuePair {
  83. // ----------------------------------------------------------- Constructors
  84. /**
  85. * Default constructor.
  86. */
  87. public HeaderElement() {
  88. this(null, null, null);
  89. }
  90. /**
  91. * Constructor.
  92. * @param name my name
  93. * @param value my (possibly <tt>null</tt>) value
  94. */
  95. public HeaderElement(String name, String value) {
  96. this(name, value, null);
  97. }
  98. /**
  99. * Constructor with name, value and parameters.
  100. *
  101. * @param name my name
  102. * @param value my (possibly <tt>null</tt>) value
  103. * @param parameters my (possibly <tt>null</tt>) parameters
  104. */
  105. public HeaderElement(String name, String value,
  106. NameValuePair[] parameters) {
  107. super(name, value);
  108. this.parameters = parameters;
  109. }
  110. /**
  111. * Constructor with array of characters.
  112. *
  113. * @param chars the array of characters
  114. * @param offset - the initial offset.
  115. * @param length - the length.
  116. *
  117. * @since 3.0
  118. */
  119. public HeaderElement(char[] chars, int offset, int length) {
  120. this();
  121. if (chars == null) {
  122. return;
  123. }
  124. ParameterParser parser = new ParameterParser();
  125. List params = parser.parse(chars, offset, length, ';');
  126. if (params.size() > 0) {
  127. NameValuePair element = (NameValuePair) params.remove(0);
  128. setName(element.getName());
  129. setValue(element.getValue());
  130. if (params.size() > 0) {
  131. this.parameters = (NameValuePair[])
  132. params.toArray(new NameValuePair[params.size()]);
  133. }
  134. }
  135. }
  136. /**
  137. * Constructor with array of characters.
  138. *
  139. * @param chars the array of characters
  140. *
  141. * @since 3.0
  142. */
  143. public HeaderElement(char[] chars) {
  144. this(chars, 0, chars.length);
  145. }
  146. // -------------------------------------------------------- Constants
  147. /** Log object for this class. */
  148. private static final Log LOG = LogFactory.getLog(HeaderElement.class);
  149. // ----------------------------------------------------- Instance Variables
  150. /** My parameters, if any. */
  151. private NameValuePair[] parameters = null;
  152. // ------------------------------------------------------------- Properties
  153. /**
  154. * Get parameters, if any.
  155. *
  156. * @since 2.0
  157. * @return parameters as an array of {@link NameValuePair}s
  158. */
  159. public NameValuePair[] getParameters() {
  160. return this.parameters;
  161. }
  162. // --------------------------------------------------------- Public Methods
  163. /**
  164. * This parses the value part of a header. The result is an array of
  165. * HeaderElement objects.
  166. *
  167. * @param headerValue the array of char representation of the header value
  168. * (as received from the web server).
  169. * @return array of {@link HeaderElement}s.
  170. *
  171. * @since 3.0
  172. */
  173. public static final HeaderElement[] parseElements(char[] headerValue) {
  174. LOG.trace("enter HeaderElement.parseElements(char[])");
  175. if (headerValue == null) {
  176. return new HeaderElement[] {};
  177. }
  178. List elements = new ArrayList();
  179. int i = 0;
  180. int from = 0;
  181. int len = headerValue.length;
  182. boolean qouted = false;
  183. while (i < len) {
  184. char ch = headerValue[i];
  185. if (ch == '"') {
  186. qouted = !qouted;
  187. }
  188. HeaderElement element = null;
  189. if ((!qouted) && (ch == ',')) {
  190. element = new HeaderElement(headerValue, from, i);
  191. from = i + 1;
  192. } else if (i == len - 1) {
  193. element = new HeaderElement(headerValue, from, len);
  194. }
  195. if ((element != null) && (element.getName() != null)) {
  196. elements.add(element);
  197. }
  198. i++;
  199. }
  200. return (HeaderElement[])
  201. elements.toArray(new HeaderElement[elements.size()]);
  202. }
  203. /**
  204. * This parses the value part of a header. The result is an array of
  205. * HeaderElement objects.
  206. *
  207. * @param headerValue the string representation of the header value
  208. * (as received from the web server).
  209. * @return array of {@link HeaderElement}s.
  210. *
  211. * @since 3.0
  212. */
  213. public static final HeaderElement[] parseElements(String headerValue) {
  214. LOG.trace("enter HeaderElement.parseElements(String)");
  215. if (headerValue == null) {
  216. return new HeaderElement[] {};
  217. }
  218. return parseElements(headerValue.toCharArray());
  219. }
  220. /**
  221. * This parses the value part of a header. The result is an array of
  222. * HeaderElement objects.
  223. *
  224. * @param headerValue the string representation of the header value
  225. * (as received from the web server).
  226. * @return array of {@link HeaderElement}s.
  227. * @throws HttpException if the above syntax rules are violated.
  228. *
  229. * @deprecated Use #parseElements(String).
  230. */
  231. public static final HeaderElement[] parse(String headerValue)
  232. throws HttpException {
  233. LOG.trace("enter HeaderElement.parse(String)");
  234. if (headerValue == null) {
  235. return new HeaderElement[] {};
  236. }
  237. return parseElements(headerValue.toCharArray());
  238. }
  239. /**
  240. * Returns parameter with the given name, if found. Otherwise null
  241. * is returned
  242. *
  243. * @param name The name to search by.
  244. * @return NameValuePair parameter with the given name
  245. */
  246. public NameValuePair getParameterByName(String name) {
  247. LOG.trace("enter HeaderElement.getParameterByName(String)");
  248. if (name == null) {
  249. throw new IllegalArgumentException("Name may not be null");
  250. }
  251. NameValuePair found = null;
  252. NameValuePair parameters[] = getParameters();
  253. if (parameters != null) {
  254. for (int i = 0; i < parameters.length; i++) {
  255. NameValuePair current = parameters[ i ];
  256. if (current.getName().equalsIgnoreCase(name)) {
  257. found = current;
  258. break;
  259. }
  260. }
  261. }
  262. return found;
  263. }
  264. }