package hudson.util; import hudson.Util; import hudson.model.TaskListener; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.types.FileSet; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.InterruptedIOException; import java.io.Serializable; import static hudson.Util.fixEmpty; /** * Visits a directory and its contents and pass them to the {@link FileVisitor}. * * A {@link DirScanner} encapsulates the logic of how it filters files in the directory. It is also remotable. * * @since 1.343 * @see FileVisitor */ public abstract class DirScanner implements Serializable { /** * Scans the given directory and pass files onto the given visitor. */ public abstract void scan(File dir, FileVisitor visitor) throws IOException; /** * Scans everything recursively. */ public static class Full extends DirScanner { private void scan(File f, String path, FileVisitor visitor) throws IOException { if (f.canRead()) { if (visitor.understandsSymlink()) { try { String target = Util.resolveSymlink(f, TaskListener.NULL); if (target!=null) { visitor.visitSymlink(f,target,path+f.getName()); return; } } catch (InterruptedException e) { throw (IOException)new InterruptedIOException().initCause(e); } } visitor.visit(f,path+f.getName()); if(f.isDirectory()) { for( File child : f.listFiles() ) scan(child,path+f.getName()+'/',visitor); } } } public void scan(File dir, FileVisitor visitor) throws IOException { scan(dir,"",visitor); } private static final long serialVersionUID = 1L; } /** * Scans by filtering things out from {@link FileFilter} */ public static class Filter extends Full { private final FileFilter filter; public Filter(FileFilter filter) { this.filter = filter; } @Override public void scan(File dir, FileVisitor visitor) throws IOException { super.scan(dir,visitor.with(filter)); } private static final long serialVersionUID = 1L; } /** * Scans by using Ant GLOB syntax. */ public static class Glob extends DirScanner { private final String includes, excludes; public Glob(String includes, String excludes) { this.includes = includes; this.excludes = excludes; } public void scan(File dir, FileVisitor visitor) throws IOException { if(fixEmpty(includes)==null && excludes==null) { // optimization new Full().scan(dir,visitor); return; } FileSet fs = Util.createFileSet(dir,includes,excludes); if(dir.exists()) { DirectoryScanner ds = fs.getDirectoryScanner(new org.apache.tools.ant.Project()); for( String f : ds.getIncludedFiles()) { File file = new File(dir, f); visitor.visit(file,f); } } } private static final long serialVersionUID = 1L; } private static final long serialVersionUID = 1L; }