• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/HeaderGroup.java $
3  * $Revision: 659185 $
4  * $Date: 2008-05-22 11:07:36 -0700 (Thu, 22 May 2008) $
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 java.util.ArrayList;
35 import java.util.List;
36 import java.util.Locale;
37 
38 import org.apache.http.Header;
39 import org.apache.http.HeaderIterator;
40 import org.apache.http.util.CharArrayBuffer;
41 
42 /**
43  * A class for combining a set of headers.
44  * This class allows for multiple headers with the same name and
45  * keeps track of the order in which headers were added.
46  *
47  * @author Michael Becke
48  *
49  * @since 4.0
50  */
51 public class HeaderGroup implements Cloneable {
52 
53     /** The list of headers for this group, in the order in which they were added */
54     private List headers;
55 
56     /**
57      * Constructor for HeaderGroup.
58      */
HeaderGroup()59     public HeaderGroup() {
60         this.headers = new ArrayList(16);
61     }
62 
63     /**
64      * Removes any contained headers.
65      */
clear()66     public void clear() {
67         headers.clear();
68     }
69 
70     /**
71      * Adds the given header to the group.  The order in which this header was
72      * added is preserved.
73      *
74      * @param header the header to add
75      */
addHeader(Header header)76     public void addHeader(Header header) {
77         if (header == null) {
78             return;
79         }
80         headers.add(header);
81     }
82 
83     /**
84      * Removes the given header.
85      *
86      * @param header the header to remove
87      */
removeHeader(Header header)88     public void removeHeader(Header header) {
89         if (header == null) {
90             return;
91         }
92         headers.remove(header);
93     }
94 
95     /**
96      * Replaces the first occurence of the header with the same name. If no header with
97      * the same name is found the given header is added to the end of the list.
98      *
99      * @param header the new header that should replace the first header with the same
100      * name if present in the list.
101      */
updateHeader(Header header)102     public void updateHeader(Header header) {
103         if (header == null) {
104             return;
105         }
106         for (int i = 0; i < this.headers.size(); i++) {
107             Header current = (Header) this.headers.get(i);
108             if (current.getName().equalsIgnoreCase(header.getName())) {
109                 this.headers.set(i, header);
110                 return;
111             }
112         }
113         this.headers.add(header);
114     }
115 
116     /**
117      * Sets all of the headers contained within this group overriding any
118      * existing headers. The headers are added in the order in which they appear
119      * in the array.
120      *
121      * @param headers the headers to set
122      */
setHeaders(Header[] headers)123     public void setHeaders(Header[] headers) {
124         clear();
125         if (headers == null) {
126             return;
127         }
128         for (int i = 0; i < headers.length; i++) {
129             this.headers.add(headers[i]);
130         }
131     }
132 
133     /**
134      * Gets a header representing all of the header values with the given name.
135      * If more that one header with the given name exists the values will be
136      * combined with a "," as per RFC 2616.
137      *
138      * <p>Header name comparison is case insensitive.
139      *
140      * @param name the name of the header(s) to get
141      * @return a header with a condensed value or <code>null</code> if no
142      * headers by the given name are present
143      */
getCondensedHeader(String name)144     public Header getCondensedHeader(String name) {
145         Header[] headers = getHeaders(name);
146 
147         if (headers.length == 0) {
148             return null;
149         } else if (headers.length == 1) {
150             return headers[0];
151         } else {
152             CharArrayBuffer valueBuffer = new CharArrayBuffer(128);
153             valueBuffer.append(headers[0].getValue());
154             for (int i = 1; i < headers.length; i++) {
155                 valueBuffer.append(", ");
156                 valueBuffer.append(headers[i].getValue());
157             }
158 
159             return new BasicHeader(name.toLowerCase(Locale.ENGLISH), valueBuffer.toString());
160         }
161     }
162 
163     /**
164      * Gets all of the headers with the given name.  The returned array
165      * maintains the relative order in which the headers were added.
166      *
167      * <p>Header name comparison is case insensitive.
168      *
169      * @param name the name of the header(s) to get
170      *
171      * @return an array of length >= 0
172      */
getHeaders(String name)173     public Header[] getHeaders(String name) {
174         ArrayList headersFound = new ArrayList();
175 
176         for (int i = 0; i < headers.size(); i++) {
177             Header header = (Header) headers.get(i);
178             if (header.getName().equalsIgnoreCase(name)) {
179                 headersFound.add(header);
180             }
181         }
182 
183         return (Header[]) headersFound.toArray(new Header[headersFound.size()]);
184     }
185 
186     /**
187      * Gets the first header with the given name.
188      *
189      * <p>Header name comparison is case insensitive.
190      *
191      * @param name the name of the header to get
192      * @return the first header or <code>null</code>
193      */
getFirstHeader(String name)194     public Header getFirstHeader(String name) {
195         for (int i = 0; i < headers.size(); i++) {
196             Header header = (Header) headers.get(i);
197             if (header.getName().equalsIgnoreCase(name)) {
198                 return header;
199             }
200         }
201         return null;
202     }
203 
204     /**
205      * Gets the last header with the given name.
206      *
207      * <p>Header name comparison is case insensitive.
208      *
209      * @param name the name of the header to get
210      * @return the last header or <code>null</code>
211      */
getLastHeader(String name)212     public Header getLastHeader(String name) {
213         // start at the end of the list and work backwards
214         for (int i = headers.size() - 1; i >= 0; i--) {
215             Header header = (Header) headers.get(i);
216             if (header.getName().equalsIgnoreCase(name)) {
217                 return header;
218             }
219         }
220 
221         return null;
222     }
223 
224     /**
225      * Gets all of the headers contained within this group.
226      *
227      * @return an array of length >= 0
228      */
getAllHeaders()229     public Header[] getAllHeaders() {
230         return (Header[]) headers.toArray(new Header[headers.size()]);
231     }
232 
233     /**
234      * Tests if headers with the given name are contained within this group.
235      *
236      * <p>Header name comparison is case insensitive.
237      *
238      * @param name the header name to test for
239      * @return <code>true</code> if at least one header with the name is
240      * contained, <code>false</code> otherwise
241      */
containsHeader(String name)242     public boolean containsHeader(String name) {
243         for (int i = 0; i < headers.size(); i++) {
244             Header header = (Header) headers.get(i);
245             if (header.getName().equalsIgnoreCase(name)) {
246                 return true;
247             }
248         }
249 
250         return false;
251     }
252 
253     /**
254      * Returns an iterator over this group of headers.
255      *
256      * @return iterator over this group of headers.
257      *
258      * @since 4.0
259      */
iterator()260     public HeaderIterator iterator() {
261         return new BasicListHeaderIterator(this.headers, null);
262     }
263 
264     /**
265      * Returns an iterator over the headers with a given name in this group.
266      *
267      * @param name      the name of the headers over which to iterate, or
268      *                  <code>null</code> for all headers
269      *
270      * @return iterator over some headers in this group.
271      *
272      * @since 4.0
273      */
iterator(final String name)274     public HeaderIterator iterator(final String name) {
275         return new BasicListHeaderIterator(this.headers, name);
276     }
277 
278     /**
279      * Returns a copy of this object
280      *
281      * @return copy of this object
282      */
copy()283     public HeaderGroup copy() {
284         HeaderGroup clone = new HeaderGroup();
285         clone.headers.addAll(this.headers);
286         return clone;
287     }
288 
clone()289     public Object clone() throws CloneNotSupportedException {
290         HeaderGroup clone = (HeaderGroup) super.clone();
291         clone.headers = new ArrayList(this.headers);
292         return clone;
293     }
294 
295 }
296