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 32 package org.apache.http.message; 33 34 35 import java.util.NoSuchElementException; 36 37 import org.apache.http.Header; 38 import org.apache.http.HeaderIterator; 39 40 41 /** 42 * Basic implementation of a {@link HeaderIterator}. 43 * 44 * @version $Revision: 581981 $ 45 */ 46 public 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