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