1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  package org.apache.commons.httpclient;
32  
33  import java.util.ArrayList;
34  import java.util.Iterator;
35  import java.util.List;
36  
37  /**
38   * A class for combining a set of headers.  This class allows for multiple
39   * headers with the same name and keeps track of the order in which headers were
40   * added.
41   * 
42   * @author Michael Becke
43   * 
44   * @since 2.0beta1
45   */
46  public class HeaderGroup {
47  
48      /** The list of headers for this group, in the order in which they were added */
49      private List headers;
50  
51      /**
52       * Constructor for HeaderGroup.
53       */
54      public HeaderGroup() {
55          this.headers = new ArrayList();
56      }
57      
58      /**
59       * Removes any contained headers.
60       */
61      public void clear() {
62          headers.clear();
63      }
64      
65      /**
66       * Adds the given header to the group.  The order in which this header was
67       * added is preserved.
68       * 
69       * @param header the header to add
70       */
71      public void addHeader(Header header) {
72          headers.add(header);
73      }
74      
75      /**
76       * Removes the given header.
77       *
78       * @param header the header to remove
79       */
80      public void removeHeader(Header header) {
81          headers.remove(header);
82      }
83  
84      /**
85       * Sets all of the headers contained within this group overriding any
86       * existing headers. The headers are added in the order in which they appear
87       * in the array.
88       * 
89       * @param headers the headers to set
90       */
91      public void setHeaders(Header[] headers) {
92          clear();
93          
94          for (int i = 0; i < headers.length; i++) {
95              addHeader(headers[i]);
96          }
97      }
98      
99      /**
100      * Gets a header representing all of the header values with the given name.
101      * If more that one header with the given name exists the values will be
102      * combined with a "," as per RFC 2616.
103      * 
104      * <p>Header name comparison is case insensitive.
105      * 
106      * @param name the name of the header(s) to get
107      * @return a header with a condensed value or <code>null</code> if no
108      * headers by the given name are present
109      */
110     public Header getCondensedHeader(String name) {
111         Header[] headers = getHeaders(name);
112         
113         if (headers.length == 0) {
114             return null;   
115         } else if (headers.length == 1) {
116             return new Header(headers[0].getName(), headers[0].getValue());
117         } else {
118             StringBuffer valueBuffer = new StringBuffer(headers[0].getValue());
119             
120             for (int i = 1; i < headers.length; i++) {
121                 valueBuffer.append(", ");
122                 valueBuffer.append(headers[i].getValue());
123             }
124             
125             return new Header(name.toLowerCase(), valueBuffer.toString());
126         }
127     }
128     
129     /**
130      * Gets all of the headers with the given name.  The returned array
131      * maintains the relative order in which the headers were added.  
132      * 
133      * <p>Header name comparison is case insensitive.
134      * 
135      * @param name the name of the header(s) to get
136      * 
137      * @return an array of length >= 0
138      */
139     public Header[] getHeaders(String name) {
140         ArrayList headersFound = new ArrayList();
141         
142         for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) {
143             Header header = (Header) headerIter.next();
144             if (header.getName().equalsIgnoreCase(name)) {
145                 headersFound.add(header);
146             }
147         }
148         
149         return (Header[]) headersFound.toArray(new Header[headersFound.size()]);
150     }
151     
152     /**
153      * Gets the first header with the given name.
154      * 
155      * <p>Header name comparison is case insensitive.
156      * 
157      * @param name the name of the header to get
158      * @return the first header or <code>null</code>
159      */
160     public Header getFirstHeader(String name) {
161         for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) {
162             Header header = (Header) headerIter.next();
163             if (header.getName().equalsIgnoreCase(name)) {
164                 return header;
165             }
166         }
167         
168         return null;                
169     }
170     
171     /**
172      * Gets the last header with the given name.
173      *
174      * <p>Header name comparison is case insensitive.
175      *
176      * @param name the name of the header to get
177      * @return the last header or <code>null</code>
178      */
179     public Header getLastHeader(String name) {
180         
181         for (int i = headers.size() - 1; i >= 0; i--) {
182             Header header = (Header) headers.get(i);
183             if (header.getName().equalsIgnoreCase(name)) {
184                 return header;
185             }            
186         }
187         
188         return null;        
189     }
190     
191     /**
192      * Gets all of the headers contained within this group.
193      * 
194      * @return an array of length >= 0
195      */
196     public Header[] getAllHeaders() {
197         return (Header[]) headers.toArray(new Header[headers.size()]);
198     }
199     
200     /**
201      * Tests if headers with the given name are contained within this group.
202      * 
203      * <p>Header name comparison is case insensitive.
204      * 
205      * @param name the header name to test for
206      * @return <code>true</code> if at least one header with the name is
207      * contained, <code>false</code> otherwise
208      */
209     public boolean containsHeader(String name) {
210         for (Iterator headerIter = headers.iterator(); headerIter.hasNext();) {
211             Header header = (Header) headerIter.next();
212             if (header.getName().equalsIgnoreCase(name)) {
213                 return true;
214             }
215         }
216         
217         return false;
218     }
219 
220     /**
221      * Returns an iterator over this group of headers.
222      * 
223      * @return iterator over this group of headers.
224      * 
225      * @since 3.0
226      */
227     public Iterator getIterator() {
228         return this.headers.iterator(); 
229     }
230 }