001    /**
002     * This class is based on the Iterators.FilterIterator class from
003     * araSpect (araspect.sourceforge.net).  The original copyright follows ...
004     *
005     * =================================================================
006     * Copyright (c) 2001,2002 aragost ag, Z???rich, Switzerland.
007     * All rights reserved.
008     *
009     * This software is provided 'as-is', without any express or implied
010     * warranty. In no event will the authors be held liable for any
011     * damages arising from the use of this software.
012     *
013     * Permission is granted to anyone to use this software for any
014     * purpose, including commercial applications, and to alter it and
015     * redistribute it freely, subject to the following restrictions:
016     *
017     * 1. The origin of this software must not be misrepresented; you
018     *    must not claim that you wrote the original software. If you
019     *    use this software in a product, an acknowledgment in the
020     *    product documentation would be appreciated but is not required.
021     *
022     * 2. Altered source versions must be plainly marked as such, and
023     *    must not be misrepresented as being the original software.
024     *
025     * 3. This notice may not be removed or altered from any source
026     *    distribution.
027     *
028     * ==================================================================
029     *
030     * Changes (c) 2003 University Health Network include the following:
031     * - move to non-nested class
032     * - collapse inherited method remove()
033     * - accept iterator instead of object in constructor
034     * - moved to HAPI package
035     * - Predicate added as an inner class; also changed to an interface
036     *
037     * These changes are distributed under the same terms as the original (above). 
038     */
039    package ca.uhn.hl7v2.util;
040    
041    import java.util.*;
042    
043    public class FilterIterator<T> implements Iterator<T> {
044        
045        private Predicate<T> predicate;
046        private Iterator<T> iter;
047        private T nextObject;
048        private boolean nextObjectSet = false;
049        
050        public FilterIterator(Iterator<T> iter, Predicate<T> predicate) {
051            this.iter = iter;
052            this.predicate = predicate;
053        }
054        
055        public boolean hasNext() {
056            if (nextObjectSet) {
057                return true;
058            } else {
059                return setNextObject();
060            }
061        }
062        
063        public T next() {
064            if (!nextObjectSet) {
065                if (!setNextObject()) {
066                    throw new NoSuchElementException();
067                }
068            }
069            nextObjectSet = false;
070            return nextObject;
071        }
072        
073        /**
074         * Set nextObject to the next object. If there are no more
075         * objects then return false. Otherwise, return true.
076         */
077        private boolean setNextObject() {
078            while (iter.hasNext()) {
079                T object = iter.next();
080                if (predicate.evaluate(object)) {
081                    nextObject = object;
082                    nextObjectSet = true;
083                    return true;
084                }
085            }
086            return false;
087        }
088        
089        /** Throws UnsupportedOperationException */
090        public void remove() {
091            throw new UnsupportedOperationException();
092        }
093        
094        /**
095         * Interface for evaluating whether an object should be returned by the iterator
096         */
097        public interface Predicate<T> {
098            public boolean evaluate(T obj);
099        }
100        
101    }