/* Copyright (C) 2001, 2007 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.util; import java.io.File; import java.io.FileFilter; import java.util.*; /** * @author dcollins * @version $Id: FileTree.java 4565 2008-02-28 17:53:41Z dcollins $ */ public class FileTree implements Iterable<File> { private File root; private int mode = FILES_AND_DIRECTORIES; public static final int FILES_ONLY = 1; public static final int DIRECTORIES_ONLY = 2; public static final int FILES_AND_DIRECTORIES = 3; public FileTree() { this(null); } public FileTree(File root) { this.root = root; } public File getRoot() { return this.root; } public void setRoot(File root) { this.root = root; } public int getMode() { return this.mode; } public void setMode(int mode) { if (!validate(mode)) throw new IllegalArgumentException("mode:" + mode); this.mode = mode; } public List<File> asList() { return asList(null); } public List<File> asList(FileFilter fileFilter) { return makeList(this.root, fileFilter, this.mode); } public Iterator<File> iterator() { return iterator(null); } public Iterator<File> iterator(FileFilter fileFilter) { return new FileTreeIterator(this.root, fileFilter, this.mode); } private static List<File> makeList(File root, FileFilter fileFilter, int mode) { Queue<File> dirs = new LinkedList<File>(); if (isDirectory(root)) dirs.offer(root); LinkedList<File> result = new LinkedList<File>(); while (dirs.peek() != null) expand(dirs.poll(), fileFilter, mode, result, dirs); return result; } private static class FileTreeIterator implements Iterator<File> { private final Queue<File> dirs = new LinkedList<File>(); private final Queue<File> files = new LinkedList<File>(); private final FileFilter fileFilter; private final int mode; private FileTreeIterator(File root, FileFilter fileFilter, int mode) { if (isDirectory(root)) this.dirs.offer(root); this.fileFilter = fileFilter; this.mode = mode; } public boolean hasNext() { if (this.files.peek() == null) expandUntilFilesFound(); return this.files.peek() != null; } public File next() { if (this.files.peek() == null) { expandUntilFilesFound(); if (this.files.peek() == null) throw new NoSuchElementException(); } return this.files.poll(); } public void remove() { throw new UnsupportedOperationException(); } private void expandUntilFilesFound() { while (this.dirs.peek() != null && this.files.peek() == null) expand(this.dirs.poll()); } private void expand(File directory) { if (directory != null) { FileTree.expand(directory, this.fileFilter, this.mode, this.files, this.dirs); } } } private static void expand(File file, FileFilter fileFilter, int mode, Queue<File> outFiles, Queue<File> outDirs) { if (file != null) { File[] list = file.listFiles(); if (list != null) { for (File child : list) { if (child != null) { boolean isDir = child.isDirectory(); if (isDir) { outDirs.offer(child); } if ((!isDir && isDisplayFiles(mode)) || (isDir && isDisplayDirectories(mode))) { if (fileFilter == null || fileFilter.accept(child)) { outFiles.offer(child); } } } } } } } private static boolean isDirectory(File file) { return file != null && file.exists() && file.isDirectory(); } private static boolean isDisplayFiles(int mode) { return mode == FILES_ONLY || mode == FILES_AND_DIRECTORIES; } private static boolean isDisplayDirectories(int mode) { return mode == DIRECTORIES_ONLY || mode == FILES_AND_DIRECTORIES; } private static boolean validate(int mode) { return mode == FILES_ONLY || mode == DIRECTORIES_ONLY || mode == FILES_AND_DIRECTORIES; } }