001/* 002 * #%L 003 * Netarchivesuite - common 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023 024package dk.netarkivet.common.utils; 025 026import java.util.Iterator; 027import java.util.NoSuchElementException; 028 029/** 030 * An iterator that filters out and converts items from another iterator. Java 1.5 type: FilterIterator<T>,<S>> <S> 031 * filter(<T> o); 032 * 033 * @param <T> Type of Iterator 034 * @param <S> Type of objects returned by the iterator. 035 */ 036public abstract class FilterIterator<T, S> implements Iterator<S> { 037 038 private S objectcache; 039 040 private final Iterator<T> iter; 041 042 /** 043 * Create a new iterator based on an old one. The old one must not contain any null entries. 044 * 045 * @param i An iterator 046 */ 047 public FilterIterator(Iterator<T> i) { 048 iter = i; 049 } 050 051 /** 052 * Returns the object corresponding to the given object, or null if that object is to be skipped. 053 * 054 * @param o An object in the source iterator domain 055 * @return An object in this iterators domain, or null 056 */ 057 protected abstract S filter(T o); 058 059 /** 060 * Returns <tt>true</tt> if the iteration has more elements. (In other words, returns <tt>true</tt> if <tt>next</tt> 061 * would return an element rather than throwing an exception.) 062 * 063 * @return <tt>true</tt> if the iterator has more elements. 064 */ 065 public boolean hasNext() { 066 while (iter.hasNext() && objectcache == null) { 067 objectcache = filter(iter.next()); 068 } 069 return objectcache != null; 070 } 071 072 /** 073 * Returns the next element in the iteration. Calling this method repeatedly until the {@link #hasNext()} method 074 * returns false will return each element in the underlying collection exactly once. 075 * 076 * @return the next element in the iteration. 077 * @throws NoSuchElementException iteration has no more elements. 078 */ 079 public S next() { 080 if (hasNext()) { 081 S o = objectcache; 082 objectcache = null; 083 return o; 084 } 085 086 throw new NoSuchElementException("No more accepted elements"); 087 } 088 089 /** 090 * Removes from the underlying collection the last element returned by the iterator (optional operation). This 091 * method can be called only once per call to <tt>next</tt>. The behavior of an iterator is unspecified if the 092 * underlying collection is modified while the iteration is in progress in any way other than by calling this 093 * method. 094 * 095 * @throws UnsupportedOperationException if the <tt>remove</tt> operation is not supported by this Iterator. 096 * @throws IllegalStateException if the <tt>next</tt> method has not yet been called, or the <tt>remove</tt> method 097 * has already been called after the last call to the <tt>next</tt> method. 098 */ 099 public void remove() { 100 throw new UnsupportedOperationException("Cannot remove from this iterator"); 101 } 102 103}