package org.jboss.jsfunit.analysis.el; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.regex.Pattern; import org.apache.commons.collections.collection.CompositeCollection; import org.apache.commons.io.filefilter.IOFileFilter; /** * * @author Jason * @since 1.0 */ public class MultiFileELExpressionIterator implements Iterator<ELBundle> { private final Iterator<File> fileIter; private Iterator<ELBundle> currIter = ELIterFactory.EMPTY_ITER; private final Collection<Pattern> alwaysSkipPatterns; private final Map<IOFileFilter, Pattern> sometimesSkipPatterns; private final ArrayList<Pattern> skipBuffer; @SuppressWarnings("unchecked") private static <T> Collection<T> unmodifiableComposite(final Collection<T> coll1, final Collection<T> coll2) { final CompositeCollection compColl = new CompositeCollection(); compColl.addComposited(coll1, coll2); return Collections.unmodifiableCollection(compColl); } public MultiFileELExpressionIterator(final Iterator<File> fileIter, final Collection<Pattern> alwaysSkipPatterns, final Map<IOFileFilter, Pattern> sometimesSkipPatterns) { this.fileIter = fileIter; this.alwaysSkipPatterns = alwaysSkipPatterns; this.sometimesSkipPatterns = sometimesSkipPatterns; final int buffersz = sometimesSkipPatterns.size(); skipBuffer = new ArrayList<Pattern>(buffersz); } private Collection<Pattern> getSkipPatterns(final File file) { skipBuffer.clear(); for(final Map.Entry<IOFileFilter, Pattern> e: sometimesSkipPatterns.entrySet()) { final IOFileFilter filter = e.getKey(); if(filter.accept(file.getParentFile(), file.getName())) { skipBuffer.add(e.getValue()); } } return unmodifiableComposite(alwaysSkipPatterns, skipBuffer); } public boolean hasNext() { while(!currIter.hasNext() && fileIter.hasNext()) { try { final File file = fileIter.next(); currIter = new ELExpressionIterator(file, getSkipPatterns(file)); } catch(final IOException ioe) { //TODO: should we just go on to the next file instead? throw new RuntimeException(ioe); } } return currIter.hasNext(); } public ELBundle next() { hasNext(); //iter may need to cycle to next file. return currIter.next(); } public void remove() { throw new UnsupportedOperationException(); } }