Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 /*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 * ====================================================================
20 *
21 * This software consists of voluntary contributions made by many
22 * individuals on behalf of the Apache Software Foundation. For more
23 * information on the Apache Software Foundation, please see
24 * <http://www.apache.org/>.
25 *
26 */
28 package ch.boye.httpclientandroidlib.message;
30 import java.io.Serializable;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Locale;
35 import ch.boye.httpclientandroidlib.Header;
36 import ch.boye.httpclientandroidlib.HeaderIterator;
37 import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
39 /**
40 * A class for combining a set of headers.
41 * This class allows for multiple headers with the same name and
42 * keeps track of the order in which headers were added.
43 *
44 *
45 * @since 4.0
46 */
47 public class HeaderGroup implements Cloneable, Serializable {
49 private static final long serialVersionUID = 2608834160639271617L;
51 /** The list of headers for this group, in the order in which they were added */
52 private final List headers;
54 /**
55 * Constructor for HeaderGroup.
56 */
57 public HeaderGroup() {
58 this.headers = new ArrayList(16);
59 }
61 /**
62 * Removes any contained headers.
63 */
64 public void clear() {
65 headers.clear();
66 }
68 /**
69 * Adds the given header to the group. The order in which this header was
70 * added is preserved.
71 *
72 * @param header the header to add
73 */
74 public void addHeader(Header header) {
75 if (header == null) {
76 return;
77 }
78 headers.add(header);
79 }
81 /**
82 * Removes the given header.
83 *
84 * @param header the header to remove
85 */
86 public void removeHeader(Header header) {
87 if (header == null) {
88 return;
89 }
90 headers.remove(header);
91 }
93 /**
94 * Replaces the first occurence of the header with the same name. If no header with
95 * the same name is found the given header is added to the end of the list.
96 *
97 * @param header the new header that should replace the first header with the same
98 * name if present in the list.
99 */
100 public void updateHeader(Header header) {
101 if (header == null) {
102 return;
103 }
104 for (int i = 0; i < this.headers.size(); i++) {
105 Header current = (Header) this.headers.get(i);
106 if (current.getName().equalsIgnoreCase(header.getName())) {
107 this.headers.set(i, header);
108 return;
109 }
110 }
111 this.headers.add(header);
112 }
114 /**
115 * Sets all of the headers contained within this group overriding any
116 * existing headers. The headers are added in the order in which they appear
117 * in the array.
118 *
119 * @param headers the headers to set
120 */
121 public void setHeaders(Header[] headers) {
122 clear();
123 if (headers == null) {
124 return;
125 }
126 for (int i = 0; i < headers.length; i++) {
127 this.headers.add(headers[i]);
128 }
129 }
131 /**
132 * Gets a header representing all of the header values with the given name.
133 * If more that one header with the given name exists the values will be
134 * combined with a "," as per RFC 2616.
135 *
136 * <p>Header name comparison is case insensitive.
137 *
138 * @param name the name of the header(s) to get
139 * @return a header with a condensed value or <code>null</code> if no
140 * headers by the given name are present
141 */
142 public Header getCondensedHeader(String name) {
143 Header[] headers = getHeaders(name);
145 if (headers.length == 0) {
146 return null;
147 } else if (headers.length == 1) {
148 return headers[0];
149 } else {
150 CharArrayBuffer valueBuffer = new CharArrayBuffer(128);
151 valueBuffer.append(headers[0].getValue());
152 for (int i = 1; i < headers.length; i++) {
153 valueBuffer.append(", ");
154 valueBuffer.append(headers[i].getValue());
155 }
157 return new BasicHeader(name.toLowerCase(Locale.ENGLISH), valueBuffer.toString());
158 }
159 }
161 /**
162 * Gets all of the headers with the given name. The returned array
163 * maintains the relative order in which the headers were added.
164 *
165 * <p>Header name comparison is case insensitive.
166 *
167 * @param name the name of the header(s) to get
168 *
169 * @return an array of length >= 0
170 */
171 public Header[] getHeaders(String name) {
172 ArrayList headersFound = new ArrayList();
174 for (int i = 0; i < headers.size(); i++) {
175 Header header = (Header) headers.get(i);
176 if (header.getName().equalsIgnoreCase(name)) {
177 headersFound.add(header);
178 }
179 }
181 return (Header[]) headersFound.toArray(new Header[headersFound.size()]);
182 }
184 /**
185 * Gets the first header with the given name.
186 *
187 * <p>Header name comparison is case insensitive.
188 *
189 * @param name the name of the header to get
190 * @return the first header or <code>null</code>
191 */
192 public Header getFirstHeader(String name) {
193 for (int i = 0; i < headers.size(); i++) {
194 Header header = (Header) headers.get(i);
195 if (header.getName().equalsIgnoreCase(name)) {
196 return header;
197 }
198 }
199 return null;
200 }
202 /**
203 * Gets the last header with the given name.
204 *
205 * <p>Header name comparison is case insensitive.
206 *
207 * @param name the name of the header to get
208 * @return the last header or <code>null</code>
209 */
210 public Header getLastHeader(String name) {
211 // start at the end of the list and work backwards
212 for (int i = headers.size() - 1; i >= 0; i--) {
213 Header header = (Header) headers.get(i);
214 if (header.getName().equalsIgnoreCase(name)) {
215 return header;
216 }
217 }
219 return null;
220 }
222 /**
223 * Gets all of the headers contained within this group.
224 *
225 * @return an array of length >= 0
226 */
227 public Header[] getAllHeaders() {
228 return (Header[]) headers.toArray(new Header[headers.size()]);
229 }
231 /**
232 * Tests if headers with the given name are contained within this group.
233 *
234 * <p>Header name comparison is case insensitive.
235 *
236 * @param name the header name to test for
237 * @return <code>true</code> if at least one header with the name is
238 * contained, <code>false</code> otherwise
239 */
240 public boolean containsHeader(String name) {
241 for (int i = 0; i < headers.size(); i++) {
242 Header header = (Header) headers.get(i);
243 if (header.getName().equalsIgnoreCase(name)) {
244 return true;
245 }
246 }
248 return false;
249 }
251 /**
252 * Returns an iterator over this group of headers.
253 *
254 * @return iterator over this group of headers.
255 *
256 * @since 4.0
257 */
258 public HeaderIterator iterator() {
259 return new BasicListHeaderIterator(this.headers, null);
260 }
262 /**
263 * Returns an iterator over the headers with a given name in this group.
264 *
265 * @param name the name of the headers over which to iterate, or
266 * <code>null</code> for all headers
267 *
268 * @return iterator over some headers in this group.
269 *
270 * @since 4.0
271 */
272 public HeaderIterator iterator(final String name) {
273 return new BasicListHeaderIterator(this.headers, name);
274 }
276 /**
277 * Returns a copy of this object
278 *
279 * @return copy of this object
280 *
281 * @since 4.0
282 */
283 public HeaderGroup copy() {
284 HeaderGroup clone = new HeaderGroup();
285 clone.headers.addAll(this.headers);
286 return clone;
287 }
289 public Object clone() throws CloneNotSupportedException {
290 HeaderGroup clone = (HeaderGroup) super.clone();
291 clone.headers.clear();
292 clone.headers.addAll(this.headers);
293 return clone;
294 }
296 public String toString() {
297 return this.headers.toString();
298 }
300 }