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/BasicListHeaderIterator.java $
      3  * $Revision: 584542 $
      4  * $Date: 2007-10-14 06:29:34 -0700 (Sun, 14 Oct 2007) $
      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 
     35 import java.util.List;
     36 import java.util.NoSuchElementException;
     37 
     38 import org.apache.http.Header;
     39 import org.apache.http.HeaderIterator;
     40 
     41 
     42 /**
     43  * Implementation of a {@link HeaderIterator} based on a {@link List}.
     44  * For use by {@link HeaderGroup}.
     45  *
     46  * @version $Revision: 584542 $
     47  */
     48 public class BasicListHeaderIterator implements HeaderIterator {
     49 
     50     /**
     51      * A list of headers to iterate over.
     52      * Not all elements of this array are necessarily part of the iteration.
     53      */
     54     protected final List allHeaders;
     55 
     56 
     57     /**
     58      * The position of the next header in {@link #allHeaders allHeaders}.
     59      * Negative if the iteration is over.
     60      */
     61     protected int currentIndex;
     62 
     63 
     64     /**
     65      * The position of the last returned header.
     66      * Negative if none has been returned so far.
     67      */
     68     protected int lastIndex;
     69 
     70 
     71     /**
     72      * The header name to filter by.
     73      * <code>null</code> to iterate over all headers in the array.
     74      */
     75     protected String headerName;
     76 
     77 
     78 
     79     /**
     80      * Creates a new header iterator.
     81      *
     82      * @param headers   a list of headers over which to iterate
     83      * @param name      the name of the headers over which to iterate, or
     84      *                  <code>null</code> for any
     85      */
     86     public BasicListHeaderIterator(List headers, String name) {
     87         if (headers == null) {
     88             throw new IllegalArgumentException
     89                 ("Header list must not be null.");
     90         }
     91 
     92         this.allHeaders = headers;
     93         this.headerName = name;
     94         this.currentIndex = findNext(-1);
     95         this.lastIndex = -1;
     96     }
     97 
     98 
     99     /**
    100      * Determines the index of the next header.
    101      *
    102      * @param from      one less than the index to consider first,
    103      *                  -1 to search for the first header
    104      *
    105      * @return  the index of the next header that matches the filter name,
    106      *          or negative if there are no more headers
    107      */
    108     protected int findNext(int from) {
    109         if (from < -1)
    110             return -1;
    111 
    112         final int to = this.allHeaders.size()-1;
    113         boolean found = false;
    114         while (!found && (from < to)) {
    115             from++;
    116             found = filterHeader(from);
    117         }
    118         return found ? from : -1;
    119     }
    120 
    121 
    122     /**
    123      * Checks whether a header is part of the iteration.
    124      *
    125      * @param index     the index of the header to check
    126      *
    127      * @return  <code>true</code> if the header should be part of the
    128      *          iteration, <code>false</code> to skip
    129      */
    130     protected boolean filterHeader(int index) {
    131         if (this.headerName == null)
    132             return true;
    133 
    134         // non-header elements, including null, will trigger exceptions
    135         final String name = ((Header)this.allHeaders.get(index)).getName();
    136 
    137         return this.headerName.equalsIgnoreCase(name);
    138     }
    139 
    140 
    141     // non-javadoc, see interface HeaderIterator
    142     public boolean hasNext() {
    143         return (this.currentIndex >= 0);
    144     }
    145 
    146 
    147     /**
    148      * Obtains the next header from this iteration.
    149      *
    150      * @return  the next header in this iteration
    151      *
    152      * @throws NoSuchElementException   if there are no more headers
    153      */
    154     public Header nextHeader()
    155         throws NoSuchElementException {
    156 
    157         final int current = this.currentIndex;
    158         if (current < 0) {
    159             throw new NoSuchElementException("Iteration already finished.");
    160         }
    161 
    162         this.lastIndex    = current;
    163         this.currentIndex = findNext(current);
    164 
    165         return (Header) this.allHeaders.get(current);
    166     }
    167 
    168 
    169     /**
    170      * Returns the next header.
    171      * Same as {@link #nextHeader nextHeader}, but not type-safe.
    172      *
    173      * @return  the next header in this iteration
    174      *
    175      * @throws NoSuchElementException   if there are no more headers
    176      */
    177     public final Object next()
    178         throws NoSuchElementException {
    179         return nextHeader();
    180     }
    181 
    182 
    183     /**
    184      * Removes the header that was returned last.
    185      */
    186     public void remove()
    187         throws UnsupportedOperationException {
    188 
    189         if (this.lastIndex < 0) {
    190             throw new IllegalStateException("No header to remove.");
    191         }
    192         this.allHeaders.remove(this.lastIndex);
    193         this.lastIndex = -1;
    194         this.currentIndex--; // adjust for the removed element
    195     }
    196 }
    197