/******************************************************************************* * Copyright (C) 2009-2011 Amir Hassan <amir@viel-zu.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ package org.wooden.io; import java.io.File; import java.util.Stack; import javax.swing.filechooser.FileFilter; public class FileTreeLoader extends BoundedObjectBuffer { private class Loader extends Thread { private Stack currentNodes; private FileFilter filters[]; private File root; public Loader(File root) { this(root, null); } public Loader(File root, FileFilter filters[]) { super(); this.currentNodes = new Stack(); this.filters = null; this.root = null; this.root = root; this.filters = filters; } public boolean acceptFile(File f) { if (this.filters == null) return true; for (FileFilter filter : this.filters) if (filter.accept(f)) return true; return false; } public void clear() { this.currentNodes.clear(); } @Override public void run() { try { this.currentNodes.push(this.root); while (FileTreeLoader.this.isRunning() && !this.currentNodes.isEmpty()) { File currentFiles[] = ((File) this.currentNodes.pop()).listFiles(); for (File currentFile : currentFiles) { if (currentFile.isDirectory()) this.currentNodes.push(currentFile); if (this.acceptFile(currentFile)) FileTreeLoader.this.queueFile(currentFile); } } FileTreeLoader.this.terminate(this); } catch (Exception ex) { throw new RuntimeException(ex); } } } public static void main(String args[]) { try { File files[] = { new File(""), new File(""), new File("") }; FileTreeLoader ftl = new FileTreeLoader(files); ftl.load(new ExtensionFileFilter[] { new ExtensionFileFilter("", false) }); Thread.sleep(3000L); int cnt = 0; for (; ftl.isRunning(); System.out.println(ftl.nextFile() .getAbsolutePath())) cnt++; System.out.println(cnt); } catch (InterruptedException e) { e.printStackTrace(); } } private File rootDirs[]; private Loader loaders[]; public FileTreeLoader(File rootDirs[]) { this(rootDirs, 200); } public FileTreeLoader(File rootDir) { this(rootDir, 200); } public FileTreeLoader(File rootDirs[], int buffersize) { super(buffersize, "FTL"); this.rootDirs = null; this.loaders = null; for (File rootDir : rootDirs) if (rootDir.isFile()) throw new IllegalArgumentException((new StringBuilder( "The root file not a directory: ")).append( rootDir.getAbsolutePath()).toString()); this.rootDirs = rootDirs; } public FileTreeLoader(File rootDir, int buffersize) { this(new File[] { rootDir }, buffersize); } public boolean isRunning() { if (this.loaders == null) return false; for (Loader loader : this.loaders) if (loader != null && loader.isAlive()) return true; return false; } public synchronized void load() { this.load(null); } public synchronized void load(FileFilter filters[]) { if (this.isRunning()) throw new IllegalStateException("Already loading file stack"); this.loaders = new Loader[this.rootDirs.length]; for (int i = 0; i < this.rootDirs.length; i++) { this.loaders[i] = new Loader(this.rootDirs[i], filters); this.loaders[i].start(); } } public File nextFile() { if (!this.isRunning() && this.empty()) return null; else return (File) this.get(); } private void queueFile(File f) { this.put(f); } public synchronized void terminate(Loader l) { l.clear(); for (int i = 0; i < this.loaders.length; i++) if (this.loaders[i] != null && this.loaders[i].equals(l)) this.loaders[i] = null; } public synchronized void terminateAll() { for (int i = 0; i < this.loaders.length; i++) if (this.loaders[i] != null) { this.loaders[i].clear(); this.loaders[i] = null; } this.put(null); } public void waitFor() { if (!this.isRunning()) throw new IllegalStateException("File stack is currently not loading"); try { for (Loader loader : this.loaders) loader.join(); } catch (InterruptedException interruptedexception) {} } }