001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.http.header; 018 019import java.util.*; 020 021import org.apache.http.*; 022import org.apache.juneau.common.utils.*; 023 024/** 025 * Basic implementation of a {@link HeaderIterator}. 026 * 027 * <h5 class='section'>Notes:</h5><ul> 028 * <li class='warn'>This class is not thread safe. 029 * </ul> 030 * 031 * <h5 class='section'>See Also:</h5><ul> 032 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a> 033 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 034 * </ul> 035 */ 036public class BasicHeaderIterator implements HeaderIterator { 037 038 private final Header[] entries; 039 private final String name; 040 private final boolean caseSensitive; 041 042 private int currentIndex; 043 044 /** 045 * Creates a new header iterator. 046 * 047 * @param headers An array of headers over which to iterate. 048 * @param name The name of the headers over which to iterate, or <jk>null</jk> for all. 049 * @param caseSensitive Use case-sensitive matching for part name. 050 */ 051 public BasicHeaderIterator(Header[] headers, String name, boolean caseSensitive) { 052 this.entries = Utils.assertArgNotNull("headers", headers); 053 this.name = name; 054 this.caseSensitive = caseSensitive; 055 this.currentIndex = findNext(-1); 056 } 057 058 private int findNext(int pos) { 059 060 int from = pos; 061 062 int to = entries.length - 1; 063 boolean found = false; 064 while (!found && (from < to)) { 065 from++; 066 found = filter(from); 067 } 068 069 return found ? from : -1; 070 } 071 072 private boolean filter(int index) { 073 return (name == null) || eq(name, entries[index].getName()); 074 } 075 076 @Override /* HeaderIterator */ 077 public boolean hasNext() { 078 return (currentIndex >= 0); 079 } 080 081 @Override /* HeaderIterator */ 082 public Header nextHeader() throws NoSuchElementException { 083 084 int current = currentIndex; 085 086 if (current < 0) 087 throw new NoSuchElementException("Iteration already finished."); 088 089 currentIndex = findNext(current); 090 091 return entries[current]; 092 } 093 094 @Override /* HeaderIterator */ 095 public final Object next() throws NoSuchElementException { 096 return nextHeader(); 097 } 098 099 /** 100 * Not supported. 101 */ 102 @Override /* HeaderIterator */ 103 public void remove() { 104 throw new UnsupportedOperationException("Not supported."); 105 } 106 107 private boolean eq(String s1, String s2) { 108 return Utils.eq(!caseSensitive, s1, s2); 109 } 110}