/* * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.flex.compiler.problems.collections; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import org.apache.flex.compiler.clients.problems.IProblemFilter; import org.apache.flex.compiler.problems.ICompilerProblem; /** * A FilteredIterator applies a IProblemFilter to an * Iterator>ICompilerProblem< and generates a * subsequence of the orginal Iterator's results, * namely those elements that satisfy the filter. */ public class FilteredIterator implements Iterator<ICompilerProblem> { /** * Construct a FilteredIterator. * @param problems - the underlying problem sequence. * @param filter - the filter to apply to the problems. */ public FilteredIterator(Iterator<ICompilerProblem> problems, IProblemFilter filter) { this.filter = filter; this.underlyingProblems = problems; this.currentProblem = null; } /** The caller's problem filter.*/ IProblemFilter filter; /** The underlying sequence of problems. */ Iterator<ICompilerProblem> underlyingProblems; /** * Holding area for a matching problem that was * found by hasNext() but has not yet been * consumed by a call to next(). */ ICompilerProblem currentProblem = null; /** * Find the next element of the underlying sequence * that the filter accepts. * @return true if a matching element was found. * @post currentProblem is not null if hasNext() returns true. */ @Override public boolean hasNext() { return findNext(); } /** * Find and fetch the next element of the underlying sequence * that the filter accepts. * @return the next filtered element. * @throws NoSuchElementException if no more elements found. * @post currentProblem is null. */ @Override public ICompilerProblem next() { if ( ! findNext() ) throw new NoSuchElementException(); // Return the current problem, which uses it up. ICompilerProblem result = currentProblem; currentProblem = null; return result; } /** * This iterator cannot remove elements. * @throws UnsupportedOperationException in all cases. */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * Position to the next problem that matches the filter. * @post currentProblem is not null if findNext() returns true. */ private boolean findNext() { while (this.currentProblem == null && this.underlyingProblems.hasNext() ) { ICompilerProblem candidate = this.underlyingProblems.next(); if ( filter.accept(candidate) ) this.currentProblem = candidate; } return this.currentProblem != null; } /** * Convenience method extends the FilteredIterator concept to an Iterable. * @param problems - an Iterable (collection) of problems. * @param filter - the filter to apply to the problems. * @return an Iterable wrapper around a FilteredIterator. */ public static Iterable<ICompilerProblem> getFilteredIterable(final Collection<ICompilerProblem> problems, final IProblemFilter filter) { return new Iterable<ICompilerProblem>() { @Override public Iterator<ICompilerProblem> iterator() { return new FilteredIterator(problems.iterator(), filter); } }; } }