/** * */ package photoSpreadParser.photoSpreadExpression.photoSpreadFunctions; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; /** * @author paepcke * */ public class AllArgEvalResults implements Iterable<ArgEvalResult<? extends Object>> { private ArrayList<ArgEvalResult<? extends Object>> _allArgResults = new ArrayList<ArgEvalResult<? extends Object>>(); private ArgEvalResult<? extends Object> _oneArgResults; protected AllArgEvalResults () { } public Iterator<ArgEvalResult<? extends Object>> iterator () { return _allArgResults.iterator(); } /**************************************************** * Inner-Inner Class FlattenedArgResultsIterator *****************************************************/ /** * Given a AllArgEvalResults, return an iterator * that feeds out a flat list of all results of * evaluating all the arguments of a function. * * @author paepcke * */ public class FlattenedArgsIterator { ArgEvalResult<?> _currResultArray; Iterator<ArgEvalResult<?>> _argResultsArraysIterator; Iterator<?> _argResultArrayIterator; AllArgEvalResults _allResults; Object _mostRecentFedOut = null; public FlattenedArgsIterator (AllArgEvalResults resultsStructure) { _allResults = resultsStructure; _argResultsArraysIterator = resultsStructure.iterator(); switchToNextArgResults (); } /**************************************************** * Methods for FlattenedArgsIterator *****************************************************/ public Object getMostRecentlyFedOut () { return _mostRecentFedOut; } /** * All results of one function argument have been fed out. * Get the results of the next argument and feed it out. * Note that the new result list that is popped off * _argResultsArraysIterator may be empty, signifying * an empty set! So clients of this class, who receive * this empty set later by calling next() on this instance, * cannot simply call .next() on that result. They must * check for null. * * @return True if any results are left to be fed out; * false otherwise. */ protected boolean switchToNextArgResults () { while(_argResultsArraysIterator.hasNext()) { _currResultArray = _argResultsArraysIterator.next(); _argResultArrayIterator = _currResultArray.iterator(); return true; } return false; } /** * Return the next result from the flattened list * of sub-results. A return of null means that we * found a result set that was empty. That's a * legitimate result, and callers must be prepared * to receive it. * @return Object of type <T>, or null. */ public <T> T next() { if (_argResultArrayIterator.hasNext()) { _mostRecentFedOut = _argResultArrayIterator.next(); return (T) _mostRecentFedOut; } else { boolean haveMoreResults = switchToNextArgResults(); if (haveMoreResults) { if (!_argResultArrayIterator.hasNext()) { // Empty-set result. Next call to this // next() method will move on to the next // result set in this 'else' clause. We // return null to communicate this empty set: return null; } _mostRecentFedOut = _argResultArrayIterator.next(); return (T) _mostRecentFedOut; } // We should never get here: throw new NoSuchElementException("No more results available."); } } public boolean hasNext() { return (_argResultArrayIterator.hasNext() || _argResultsArraysIterator.hasNext()); } } /**************************************************** * Methods for ArgEvalResults *****************************************************/ /* public void addOneArgResult (FunctionResultable res) { _oneArgResults.add(res); } */ public void addAllOneArgResults (ArgEvalResult<?> oneArgResults) { _allArgResults.add(oneArgResults); } /* public void addAllOneArgResults (ArrayList<FunctionResultable> oneArgResults) { _oneArgResults.addAll(oneArgResults); } */ public <T> ArgEvalResult<T> newResultSet () { if ((_oneArgResults != null) && !_oneArgResults.isEmpty()) _allArgResults.add(_oneArgResults); _oneArgResults = new ArgEvalResult<T>(); return (ArgEvalResult<T>) _oneArgResults; } /** * Iterator that feeds out one argument result set at * a time. That is, each fed item is a set of FunctionResultable * packaged in an ArgEvalResult * @return Iterator for feeding out one result set at a time. */ //public <T> Iterator<ArgEvalResult<T>> argsResultsIterator() { public <T> Iterator<T> argsResultsIterator() { return (Iterator<T>) _allArgResults.iterator(); } /** * Iterator that feeds out a flat list of all results of * evaluating all the arguments of a function. Use if * all result sets from evaluating each of a function's * arguments are to be lumped into one soup for further * processing. (e.g. Union(arg1, arge2, arg3, ...) * * @return Iterator that feeds out one FunctionResultable * until all results of evaluating all of a function's * arguments have been provided. */ public FlattenedArgsIterator flattenedArgsIterator () { return new FlattenedArgsIterator(this); } }