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