Source for org.apache.commons.httpclient.HeaderElement

   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:}