001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-main/src/main/java/org/apache/http/message/HeaderGroup.java $
003: * $Revision: 604625 $
004: * $Date: 2007-12-16 15:11:11 +0100 (Sun, 16 Dec 2007) $
005: *
006: * ====================================================================
007: * Licensed to the Apache Software Foundation (ASF) under one
008: * or more contributor license agreements. See the NOTICE file
009: * distributed with this work for additional information
010: * regarding copyright ownership. The ASF licenses this file
011: * to you under the Apache License, Version 2.0 (the
012: * "License"); you may not use this file except in compliance
013: * with the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing,
018: * software distributed under the License is distributed on an
019: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020: * KIND, either express or implied. See the License for the
021: * specific language governing permissions and limitations
022: * under the License.
023: * ====================================================================
024: *
025: * This software consists of voluntary contributions made by many
026: * individuals on behalf of the Apache Software Foundation. For more
027: * information on the Apache Software Foundation, please see
028: * <http://www.apache.org/>.
029: *
030: */
031:
032: package org.apache.http.message;
033:
034: import java.util.ArrayList;
035: import java.util.List;
036:
037: import org.apache.http.Header;
038: import org.apache.http.HeaderIterator;
039: import org.apache.http.util.CharArrayBuffer;
040:
041: /**
042: * A class for combining a set of headers.
043: * This class allows for multiple headers with the same name and
044: * keeps track of the order in which headers were added.
045: *
046: * @author Michael Becke
047: *
048: * @since 4.0
049: */
050: public class HeaderGroup implements Cloneable {
051:
052: /** The list of headers for this group, in the order in which they were added */
053: private List headers;
054:
055: /**
056: * Constructor for HeaderGroup.
057: */
058: public HeaderGroup() {
059: this .headers = new ArrayList(16);
060: }
061:
062: /**
063: * Removes any contained headers.
064: */
065: public void clear() {
066: headers.clear();
067: }
068:
069: /**
070: * Adds the given header to the group. The order in which this header was
071: * added is preserved.
072: *
073: * @param header the header to add
074: */
075: public void addHeader(Header header) {
076: if (header == null) {
077: return;
078: }
079: headers.add(header);
080: }
081:
082: /**
083: * Removes the given header.
084: *
085: * @param header the header to remove
086: */
087: public void removeHeader(Header header) {
088: if (header == null) {
089: return;
090: }
091: headers.remove(header);
092: }
093:
094: /**
095: * Replaces the first occurence of the header with the same name. If no header with
096: * the same name is found the given header is added to the end of the list.
097: *
098: * @param header the new header that should replace the first header with the same
099: * name if present in the list.
100: */
101: public void updateHeader(Header header) {
102: if (header == null) {
103: return;
104: }
105: for (int i = 0; i < this .headers.size(); i++) {
106: Header current = (Header) this .headers.get(i);
107: if (current.getName().equalsIgnoreCase(header.getName())) {
108: this .headers.set(i, header);
109: return;
110: }
111: }
112: this .headers.add(header);
113: }
114:
115: /**
116: * Sets all of the headers contained within this group overriding any
117: * existing headers. The headers are added in the order in which they appear
118: * in the array.
119: *
120: * @param headers the headers to set
121: */
122: public void setHeaders(Header[] headers) {
123: clear();
124: if (headers == null) {
125: return;
126: }
127: for (int i = 0; i < headers.length; i++) {
128: this .headers.add(headers[i]);
129: }
130: }
131:
132: /**
133: * Gets a header representing all of the header values with the given name.
134: * If more that one header with the given name exists the values will be
135: * combined with a "," as per RFC 2616.
136: *
137: * <p>Header name comparison is case insensitive.
138: *
139: * @param name the name of the header(s) to get
140: * @return a header with a condensed value or <code>null</code> if no
141: * headers by the given name are present
142: */
143: public Header getCondensedHeader(String name) {
144: Header[] headers = getHeaders(name);
145:
146: if (headers.length == 0) {
147: return null;
148: } else if (headers.length == 1) {
149: return headers[0];
150: } else {
151: CharArrayBuffer valueBuffer = new CharArrayBuffer(128);
152: valueBuffer.append(headers[0].getValue());
153: for (int i = 1; i < headers.length; i++) {
154: valueBuffer.append(", ");
155: valueBuffer.append(headers[i].getValue());
156: }
157:
158: return new BasicHeader(name.toLowerCase(), valueBuffer
159: .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: */
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
184: .size()]);
185: }
186:
187: /**
188: * Gets the first header with the given name.
189: *
190: * <p>Header name comparison is case insensitive.
191: *
192: * @param name the name of the header to get
193: * @return the first header or <code>null</code>
194: */
195: public Header getFirstHeader(String name) {
196: for (int i = 0; i < headers.size(); i++) {
197: Header header = (Header) headers.get(i);
198: if (header.getName().equalsIgnoreCase(name)) {
199: return header;
200: }
201: }
202: return null;
203: }
204:
205: /**
206: * Gets the last header with the given name.
207: *
208: * <p>Header name comparison is case insensitive.
209: *
210: * @param name the name of the header to get
211: * @return the last header or <code>null</code>
212: */
213: public Header getLastHeader(String name) {
214: // start at the end of the list and work backwards
215: for (int i = headers.size() - 1; i >= 0; i--) {
216: Header header = (Header) headers.get(i);
217: if (header.getName().equalsIgnoreCase(name)) {
218: return header;
219: }
220: }
221:
222: return null;
223: }
224:
225: /**
226: * Gets all of the headers contained within this group.
227: *
228: * @return an array of length >= 0
229: */
230: public Header[] getAllHeaders() {
231: return (Header[]) headers.toArray(new Header[headers.size()]);
232: }
233:
234: /**
235: * Tests if headers with the given name are contained within this group.
236: *
237: * <p>Header name comparison is case insensitive.
238: *
239: * @param name the header name to test for
240: * @return <code>true</code> if at least one header with the name is
241: * contained, <code>false</code> otherwise
242: */
243: public boolean containsHeader(String name) {
244: for (int i = 0; i < headers.size(); i++) {
245: Header header = (Header) headers.get(i);
246: if (header.getName().equalsIgnoreCase(name)) {
247: return true;
248: }
249: }
250:
251: return false;
252: }
253:
254: /**
255: * Returns an iterator over this group of headers.
256: *
257: * @return iterator over this group of headers.
258: *
259: * @since 4.0
260: */
261: public HeaderIterator iterator() {
262: return new BasicListHeaderIterator(this .headers, null);
263: }
264:
265: /**
266: * Returns an iterator over the headers with a given name in this group.
267: *
268: * @param name the name of the headers over which to iterate, or
269: * <code>null</code> for all headers
270: *
271: * @return iterator over some headers in this group.
272: *
273: * @since 4.0
274: */
275: public HeaderIterator iterator(final String name) {
276: return new BasicListHeaderIterator(this .headers, name);
277: }
278:
279: public Object clone() throws CloneNotSupportedException {
280: HeaderGroup clone = (HeaderGroup) super .clone();
281: clone.headers = new ArrayList(this.headers);
282: return clone;
283: }
284:
285: }
|