001: /*
002: * Janino - An embedded Java[TM] compiler
003: *
004: * Copyright (c) 2006, Arno Unkrig
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above
014: * copyright notice, this list of conditions and the following
015: * disclaimer in the documentation and/or other materials
016: * provided with the distribution.
017: * 3. The name of the author may not be used to endorse or promote
018: * products derived from this software without specific prior
019: * written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
022: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
025: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
027: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
029: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
030: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
031: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032: */
033:
034: package org.codehaus.janino.util.iterator;
035:
036: import java.io.File;
037: import java.io.FilenameFilter;
038: import java.util.ArrayList;
039: import java.util.Iterator;
040: import java.util.List;
041:
042: import org.codehaus.janino.util.Producer;
043:
044: /**
045: * An {@link Iterator} that finds the normal {@link File}s who's names are
046: * {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
047: * <code>fileNameFilter</code> and
048: * <ul>
049: * <li>
050: * that exist in the given <code>rootDirectory</code>,
051: * </li>
052: * <li>
053: * and those that exist in all subdirectories of the
054: * <code>rootDirectory</code> who's names are
055: * {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
056: * <code>directoryNameFilter</code>
057: * </li>
058: * </ul>
059: */
060: public class DirectoryIterator extends ProducerIterator {
061: public DirectoryIterator(final File rootDirectory,
062: final FilenameFilter directoryNameFilter,
063: final FilenameFilter fileNameFilter) {
064: super (new Producer() {
065: private final List stateStack = DirectoryIterator
066: .newArrayList(new State(rootDirectory));
067:
068: public Object produce() {
069: while (!this .stateStack.isEmpty()) {
070: State state = (State) this .stateStack
071: .get(this .stateStack.size() - 1);
072: if (state.directories.hasNext()) {
073: this .stateStack.add(new State(
074: (File) state.directories.next()));
075: } else if (state.files.hasNext()) {
076: return (File) state.files.next();
077: } else {
078: this .stateStack
079: .remove(this .stateStack.size() - 1);
080: }
081: }
082: return null;
083: }
084:
085: class State {
086: State(File dir) {
087: File[] entries = dir.listFiles();
088: if (entries == null)
089: throw new RuntimeException("Directory \"" + dir
090: + "\" could not be read");
091: List directoryList = new ArrayList();
092: List fileList = new ArrayList();
093: for (int i = 0; i < entries.length; ++i) {
094: File entry = entries[i];
095: if (entry.isDirectory()) {
096: if (directoryNameFilter.accept(dir, entry
097: .getName()))
098: directoryList.add(entry);
099: } else if (entry.isFile()) {
100: if (fileNameFilter.accept(dir, entry
101: .getName()))
102: fileList.add(entry);
103: }
104: }
105: this .directories = directoryList.iterator();
106: this .files = fileList.iterator();
107: }
108:
109: final Iterator directories; // File
110: final Iterator files; // File
111: }
112: });
113: }
114:
115: /**
116: * Create an {@link Iterator} that return all matching
117: * {@link File}s locatable in a <i>set</i> of root directories.
118: *
119: * @see #DirectoryIterator(File, FilenameFilter, FilenameFilter)
120: */
121: public static Iterator traverseDirectories(File[] rootDirectories,
122: FilenameFilter directoryNameFilter,
123: FilenameFilter fileNameFilter) {
124: List result = new ArrayList();
125: for (int i = 0; i < rootDirectories.length; ++i) {
126: result.add(new DirectoryIterator(rootDirectories[i],
127: directoryNameFilter, fileNameFilter));
128: }
129: return new MultiDimensionalIterator(result.iterator(), 2);
130: }
131:
132: private static ArrayList newArrayList(Object initialElement) {
133: ArrayList result = new ArrayList();
134: result.add(initialElement);
135: return result;
136: }
137: }
|