BasicHeaderIterator.java revision 417f3b92ba4549b2f22340e3107d869d2b9c5bb8
1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderIterator.java $
3 * $Revision: 581981 $
4 * $Date: 2007-10-04 11:26:26 -0700 (Thu, 04 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
32package org.apache.http.message;
33
34
35import java.util.NoSuchElementException;
36
37import org.apache.http.Header;
38import org.apache.http.HeaderIterator;
39
40
41/**
42 * Basic implementation of a {@link HeaderIterator}.
43 *
44 * @version $Revision: 581981 $
45 */
46public class BasicHeaderIterator implements HeaderIterator {
47
48    /**
49     * An array of headers to iterate over.
50     * Not all elements of this array are necessarily part of the iteration.
51     * This array will never be modified by the iterator.
52     * Derived implementations are expected to adhere to this restriction.
53     */
54    protected final Header[] 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 header name to filter by.
66     * <code>null</code> to iterate over all headers in the array.
67     */
68    protected String headerName;
69
70
71
72    /**
73     * Creates a new header iterator.
74     *
75     * @param headers   an array of headers over which to iterate
76     * @param name      the name of the headers over which to iterate, or
77     *                  <code>null</code> for any
78     */
79    public BasicHeaderIterator(Header[] headers, String name) {
80        if (headers == null) {
81            throw new IllegalArgumentException
82                ("Header array must not be null.");
83        }
84
85        this.allHeaders = headers;
86        this.headerName = name;
87        this.currentIndex = findNext(-1);
88    }
89
90
91    /**
92     * Determines the index of the next header.
93     *
94     * @param from      one less than the index to consider first,
95     *                  -1 to search for the first header
96     *
97     * @return  the index of the next header that matches the filter name,
98     *          or negative if there are no more headers
99     */
100    protected int findNext(int from) {
101        if (from < -1)
102            return -1;
103
104        final int to = this.allHeaders.length-1;
105        boolean found = false;
106        while (!found && (from < to)) {
107            from++;
108            found = filterHeader(from);
109        }
110        return found ? from : -1;
111    }
112
113
114    /**
115     * Checks whether a header is part of the iteration.
116     *
117     * @param index     the index of the header to check
118     *
119     * @return  <code>true</code> if the header should be part of the
120     *          iteration, <code>false</code> to skip
121     */
122    protected boolean filterHeader(int index) {
123        return (this.headerName == null) ||
124            this.headerName.equalsIgnoreCase(this.allHeaders[index].getName());
125    }
126
127
128    // non-javadoc, see interface HeaderIterator
129    public boolean hasNext() {
130        return (this.currentIndex >= 0);
131    }
132
133
134    /**
135     * Obtains the next header from this iteration.
136     *
137     * @return  the next header in this iteration
138     *
139     * @throws NoSuchElementException   if there are no more headers
140     */
141    public Header nextHeader()
142        throws NoSuchElementException {
143
144        final int current = this.currentIndex;
145        if (current < 0) {
146            throw new NoSuchElementException("Iteration already finished.");
147        }
148
149        this.currentIndex = findNext(current);
150
151        return this.allHeaders[current];
152    }
153
154
155    /**
156     * Returns the next header.
157     * Same as {@link #nextHeader nextHeader}, but not type-safe.
158     *
159     * @return  the next header in this iteration
160     *
161     * @throws NoSuchElementException   if there are no more headers
162     */
163    public final Object next()
164        throws NoSuchElementException {
165        return nextHeader();
166    }
167
168
169    /**
170     * Removing headers is not supported.
171     *
172     * @throws UnsupportedOperationException    always
173     */
174    public void remove()
175        throws UnsupportedOperationException {
176
177        throw new UnsupportedOperationException
178            ("Removing headers is not supported.");
179    }
180}
181