Home | History | Annotate | Download | only in message
      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      */
     59     public HeaderGroup() {
     60         this.headers = new ArrayList(16);
     61     }
     62 
     63     /**
     64      * Removes any contained headers.
     65      */
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    283     public HeaderGroup copy() {
    284         HeaderGroup clone = new HeaderGroup();
    285         clone.headers.addAll(this.headers);
    286         return clone;
    287     }
    288 
    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