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.classic.header; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import java.util.*; 022 023import org.apache.http.*; 024import org.apache.juneau.commons.utils.*; 025 026/** 027 * Basic implementation of a {@link HeaderIterator}. 028 * 029 * <h5 class='section'>Notes:</h5><ul> 030 * <li class='warn'>This class is not thread safe. 031 * </ul> 032 * 033 * <h5 class='section'>See Also:</h5><ul> 034 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommon">juneau-rest-common</a> 035 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 036 * </ul> 037 */ 038@SuppressWarnings({ 039 "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants 040}) 041public class BasicHeaderIterator implements HeaderIterator { 042 043 private final Header[] entries; 044 private final String name; 045 private final boolean caseSensitive; 046 047 private int currentIndex; 048 049 /** 050 * Creates a new header iterator. 051 * 052 * @param headers An array of headers over which to iterate. Must not be <jk>null</jk>. 053 * @param name The name of the headers over which to iterate, or <jk>null</jk> for all. 054 * @param caseSensitive Use case-sensitive matching for part name. 055 */ 056 public BasicHeaderIterator(Header[] headers, String name, boolean caseSensitive) { 057 this.entries = reqnn("headers", headers); 058 this.name = name; 059 this.caseSensitive = caseSensitive; 060 this.currentIndex = findNext(-1); 061 } 062 063 @Override /* Overridden from HeaderIterator */ 064 public boolean hasNext() { 065 return (currentIndex >= 0); 066 } 067 068 @Override /* Overridden from HeaderIterator */ 069 public final Object next() throws NoSuchElementException { 070 return nextHeader(); 071 } 072 073 @Override /* Overridden from HeaderIterator */ 074 public Header nextHeader() throws NoSuchElementException { 075 076 int current = currentIndex; 077 078 if (current < 0) 079 throw new NoSuchElementException("Iteration already finished."); 080 081 currentIndex = findNext(current); 082 083 return entries[current]; 084 } 085 086 /** 087 * Not supported. 088 */ 089 @Override /* Overridden from HeaderIterator */ 090 public void remove() { 091 throw uoex(); 092 } 093 094 private boolean eq(String s1, String s2) { 095 return Shorts.eq(! caseSensitive, s1, s2); // NOAI 096 } 097 098 private boolean filter(int index) { 099 return (name == null) || eq(name, entries[index].getName()); 100 } 101 102 private int findNext(int pos) { 103 104 int from = pos; 105 106 int to = entries.length - 1; 107 boolean found = false; 108 while (! found && (from < to)) { 109 from++; 110 found = filter(from); 111 } 112 113 return found ? from : -1; 114 } 115}