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: 480424 $
    4    * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
    5    *
    6    * ====================================================================
    7    *
    8    *  Licensed to the Apache Software Foundation (ASF) under one or more
    9    *  contributor license agreements.  See the NOTICE file distributed with
    10   *  this work for additional information regarding copyright ownership.
    11   *  The ASF licenses this file to You under the Apache License, Version 2.0
    12   *  (the "License"); you may not use this file except in compliance with
    13   *  the License.  You may obtain a copy of the License at
    14   *
    15   *      http://www.apache.org/licenses/LICENSE-2.0
    16   *
    17   *  Unless required by applicable law or agreed to in writing, software
    18   *  distributed under the License is distributed on an "AS IS" BASIS,
    19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    20   *  See the License for the specific language governing permissions and
    21   *  limitations under the License.
    22   * ====================================================================
    23   *
    24   * This software consists of voluntary contributions made by many
    25   * individuals on behalf of the Apache Software Foundation.  For more
    26   * information on the Apache Software Foundation, please see
    27   * <http://www.apache.org/>.
    28   *
    29   */
    30
    31  package org.apache.commons.httpclient;
    32
    33  import java.util.ArrayList;
    34  import java.util.List;
    35
    36  import org.apache.commons.httpclient.util.ParameterParser;
    37  import org.apache.commons.logging.Log;
    38  import org.apache.commons.logging.LogFactory;
    39
    40  /**
    41   * <p>One element of an HTTP header's value.</p>
    42   * <p>
    43   * Some HTTP headers (such as the set-cookie header) have values that
    44   * can be decomposed into multiple elements.  Such headers must be in the
    45   * following form:
    46   * </p>
    47   * <pre>
    48   * header  = [ element ] *( "," [ element ] )
    49   * element = name [ "=" [ value ] ] *( ";" [ param ] )
    50   * param   = name [ "=" [ value ] ]
    51   *
    52   * name    = token
    53   * value   = ( token | quoted-string )
    54   *
    55   * token         = 1*&lt;any char except "=", ",", ";", &lt;"&gt; and
    56   *                       white space&gt;
    57   * quoted-string = &lt;"&gt; *( text | quoted-char ) &lt;"&gt;
    58   * text          = any char except &lt;"&gt;
    59   * quoted-char   = "\" char
    60   * </pre>
    61   * <p>
    62   * Any amount of white space is allowed between any part of the
    63   * header, element or param and is ignored. A missing value in any
    64   * element or param will be stored as the empty {@link String};
    65   * if the "=" is also missing <var>null</var> will be stored instead.
    66   * </p>
    67   * <p>
    68   * This class represents an individual header element, containing
    69   * both a name/value pair (value may be <tt>null</tt>) and optionally
    70   * a set of additional parameters.
    71   * </p>
    72   * <p>
    73   * This class also exposes a {@link #parse} method for parsing a
    74   * {@link Header} value into an array of elements.
    75   * </p>
    76   *
    77   * @see Header
    78   *
    79   * @author <a href="mailto:bcholmes@interlog.com">B.C. Holmes</a>
    80   * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
    81   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
    82   * @author <a href="mailto:oleg@ural.com">Oleg Kalnichevski</a>
    83   *
    84   * @since 1.0
    85   * @version $Revision: 480424 $ $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
    86   */
    87  public class HeaderElement extends NameValuePair {
    88
    89      // ----------------------------------------------------------- Constructors
    90
    91      /**
    92       * Default constructor.
    93       */
    94      public HeaderElement() {
    95          this(null, null, null);
    96      }
    97
    98      /**
    99        * 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[])
    142                     params.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.getLog(HeaderElement.class);
    162
    163     // ----------------------------------------------------- Instance Variables
    164
    165     /** My parameters, if any. */
    166     private NameValuePair[] parameters = null;
    167
    168     // ------------------------------------------------------------- Properties
    169
    170     /**
    171      * Get parameters, if any.
    172      *
    173      * @since 2.0
    174      * @return parameters as an array of {@link NameValuePair}s
    175      */
    176     public NameValuePair[] getParameters() {
    177         return this.parameters;
    178     }
    179
    180     // --------------------------------------------------------- Public Methods
    181
    182     /**
    183      * This parses the value part of a header. The result is an array of
    184      * HeaderElement objects.
    185      *
    186      * @param headerValue  the array of char representation of the header value
    187      *                     (as received from the web server).
    188      * @return array of {@link HeaderElement}s.
    189      *
    190      * @since 3.0
    191      */
    192     public static final HeaderElement[] parseElements(char[] headerValue) {
    193
    194         LOG.trace("enter HeaderElement.parseElements(char[])");
    195
    196         if (headerValue == null) {
    197             return new HeaderElement[] {};
    198         }
    199         List elements = new ArrayList();
    200
    201         int i = 0;
    202         int from = 0;
    203         int len = headerValue.length;
    204         boolean qouted = false;
    205         while (i < len) {
    206             char ch = headerValue[i];
    207             if (ch == '"') {
    208                 qouted = !qouted;
    209             }
    210             HeaderElement element = null;
    211             if ((!qouted) && (ch == ',')) {
    212                 element = new HeaderElement(headerValue, from, i);
    213                 from = i + 1;
    214             } else if (i == len - 1) {
    215                 element = new HeaderElement(headerValue, from, len);
    216             }
    217             if ((element != null) && (element.getName() != null)) {
    218                 elements.add(element);
    219             }
    220             i++;
    221         }
    222         return (HeaderElement[])
    223             elements.toArray(new HeaderElement[elements.size()]);
    224     }
    225
    226     /**
    227      * This parses the value part of a header. The result is an array of
    228      * HeaderElement objects.
    229      *
    230      * @param headerValue  the string representation of the header value
    231      *                     (as received from the web server).
    232      * @return array of {@link HeaderElement}s.
    233      *
    234      * @since 3.0
    235      */
    236     public static final HeaderElement[] parseElements(String headerValue) {
    237
    238         LOG.trace("enter HeaderElement.parseElements(String)");
    239
    240         if (headerValue == null) {
    241             return new HeaderElement[] {};
    242         }
    243         return parseElements(headerValue.toCharArray());
    244     }
    245
    246     /**
    247      * This parses the value part of a header. The result is an array of
    248      * HeaderElement objects.
    249      *
    250      * @param headerValue  the string representation of the header value
    251      *                     (as received from the web server).
    252      * @return array of {@link HeaderElement}s.
    253      * @throws HttpException if the above syntax rules are violated.
    254      *
    255      * @deprecated Use #parseElements(String).
    256      */
    257     public static final HeaderElement[] parse(String headerValue)
    258         throws HttpException {
    259
    260         LOG.trace("enter HeaderElement.parse(String)");
    261
    262         if (headerValue == null) {
    263             return new HeaderElement[] {};
    264         }
    265         return parseElements(headerValue.toCharArray());
    266     }
    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 }
    299