1 /* 2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElement.java $ 3 * $Revision: 604625 $ 4 * $Date: 2007-12-16 06:11:11 -0800 (Sun, 16 Dec 2007) $ 5 * 6 * ==================================================================== 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with 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, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 * ==================================================================== 24 * 25 * This software consists of voluntary contributions made by many 26 * individuals on behalf of the Apache Software Foundation. For more 27 * information on the Apache Software Foundation, please see 28 * <http://www.apache.org/>. 29 * 30 */ 31 32 package org.apache.http.message; 33 34 import org.apache.http.HeaderElement; 35 import org.apache.http.NameValuePair; 36 import org.apache.http.util.CharArrayBuffer; 37 import org.apache.http.util.LangUtils; 38 39 /** 40 * One element of an HTTP header's value. 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 * 72 * @author <a href="mailto:bcholmes (at) interlog.com">B.C. Holmes</a> 73 * @author <a href="mailto:jericho (at) thinkfree.com">Park, Sung-Gu</a> 74 * @author <a href="mailto:mbowler (at) GargoyleSoftware.com">Mike Bowler</a> 75 * @author <a href="mailto:oleg at ural.com">Oleg Kalnichevski</a> 76 * 77 * 78 * <!-- empty lines above to avoid 'svn diff' context problems --> 79 * @version $Revision: 604625 $ $Date: 2007-12-16 06:11:11 -0800 (Sun, 16 Dec 2007) $ 80 * 81 * @since 4.0 82 */ 83 public class BasicHeaderElement implements HeaderElement, Cloneable { 84 85 private final String name; 86 private final String value; 87 private final NameValuePair[] parameters; 88 89 /** 90 * Constructor with name, value and parameters. 91 * 92 * @param name header element name 93 * @param value header element value. May be <tt>null</tt> 94 * @param parameters header element parameters. May be <tt>null</tt>. 95 * Parameters are copied by reference, not by value 96 */ 97 public BasicHeaderElement( 98 final String name, 99 final String value, 100 final NameValuePair[] parameters) { 101 super(); 102 if (name == null) { 103 throw new IllegalArgumentException("Name may not be null"); 104 } 105 this.name = name; 106 this.value = value; 107 if (parameters != null) { 108 this.parameters = parameters; 109 } else { 110 this.parameters = new NameValuePair[] {}; 111 } 112 } 113 114 /** 115 * Constructor with name and value. 116 * 117 * @param name header element name 118 * @param value header element value. May be <tt>null</tt> 119 */ 120 public BasicHeaderElement(final String name, final String value) { 121 this(name, value, null); 122 } 123 124 /** 125 * Returns the name. 126 * 127 * @return String name The name 128 */ 129 public String getName() { 130 return this.name; 131 } 132 133 /** 134 * Returns the value. 135 * 136 * @return String value The current value. 137 */ 138 public String getValue() { 139 return this.value; 140 } 141 142 /** 143 * Get parameters, if any. 144 * The returned array is created for each invocation and can 145 * be modified by the caller without affecting this header element. 146 * 147 * @return parameters as an array of {@link NameValuePair}s 148 */ 149 public NameValuePair[] getParameters() { 150 return (NameValuePair[])this.parameters.clone(); 151 } 152 153 154 /** 155 * Obtains the number of parameters. 156 * 157 * @return the number of parameters 158 */ 159 public int getParameterCount() { 160 return this.parameters.length; 161 } 162 163 164 /** 165 * Obtains the parameter with the given index. 166 * 167 * @param index the index of the parameter, 0-based 168 * 169 * @return the parameter with the given index 170 */ 171 public NameValuePair getParameter(int index) { 172 // ArrayIndexOutOfBoundsException is appropriate 173 return this.parameters[index]; 174 } 175 176 177 /** 178 * Returns parameter with the given name, if found. Otherwise null 179 * is returned 180 * 181 * @param name The name to search by. 182 * @return NameValuePair parameter with the given name 183 */ 184 public NameValuePair getParameterByName(final String name) { 185 if (name == null) { 186 throw new IllegalArgumentException("Name may not be null"); 187 } 188 NameValuePair found = null; 189 for (int i = 0; i < this.parameters.length; i++) { 190 NameValuePair current = this.parameters[ i ]; 191 if (current.getName().equalsIgnoreCase(name)) { 192 found = current; 193 break; 194 } 195 } 196 return found; 197 } 198 199 public boolean equals(final Object object) { 200 if (object == null) return false; 201 if (this == object) return true; 202 if (object instanceof HeaderElement) { 203 BasicHeaderElement that = (BasicHeaderElement) object; 204 return this.name.equals(that.name) 205 && LangUtils.equals(this.value, that.value) 206 && LangUtils.equals(this.parameters, that.parameters); 207 } else { 208 return false; 209 } 210 } 211 212 public int hashCode() { 213 int hash = LangUtils.HASH_SEED; 214 hash = LangUtils.hashCode(hash, this.name); 215 hash = LangUtils.hashCode(hash, this.value); 216 for (int i = 0; i < this.parameters.length; i++) { 217 hash = LangUtils.hashCode(hash, this.parameters[i]); 218 } 219 return hash; 220 } 221 222 public String toString() { 223 CharArrayBuffer buffer = new CharArrayBuffer(64); 224 buffer.append(this.name); 225 if (this.value != null) { 226 buffer.append("="); 227 buffer.append(this.value); 228 } 229 for (int i = 0; i < this.parameters.length; i++) { 230 buffer.append("; "); 231 buffer.append(this.parameters[i]); 232 } 233 return buffer.toString(); 234 } 235 236 public Object clone() throws CloneNotSupportedException { 237 // parameters array is considered immutable 238 // no need to make a copy of it 239 return super.clone(); 240 } 241 242 } 243 244