package org.jetbrains.ether; import java.io.File; import java.io.FileFilter; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by IntelliJ IDEA. * User: db * Date: 19.11.10 * Time: 2:01 * To change this template use File | Settings | File Templates. */ public class DirectoryScanner { public static class Result { final Set<ProjectWrapper.FileWrapper> myFiles; long myLatest; long myEarliest; public Result () { myFiles = new HashSet<ProjectWrapper.FileWrapper> (); myLatest = 0; myEarliest = Long.MAX_VALUE; } public void update (final ProjectWrapper.FileWrapper w) { final long t = w.getStamp (); if (t > myLatest) myLatest = t; if (t< myEarliest) myEarliest = t; myFiles.add(w); } public long getEarliest () { return myEarliest; } public long getLatest () { return myLatest; } public Set<ProjectWrapper.FileWrapper> getFiles () { return myFiles; } } private static class Crawler { final Result myResult; final FileFilter myFilter; final ProjectWrapper myProjectWrapper; public Crawler (final FileFilter ff, final ProjectWrapper pw) { myResult = new Result(); myFilter = ff; myProjectWrapper = pw; } public Result getResult () { return myResult; } public void run(File root) { if (root.exists()) { final File[] files = root.listFiles(myFilter); for (int i = 0; i < files.length; i++) { myResult.update (myProjectWrapper.new FileWrapper(files[i])); } final File[] subdirs = root.listFiles(myDirectoryFilter); for (int i = 0; i < subdirs.length; i++) { run(subdirs[i]); } } } } private static FileFilter myDirectoryFilter = new FileFilter() { public boolean accept(File f) { final String name = f.getName(); return f.isDirectory() && !name.equals(".") && !name.equals(".."); } }; private static FileFilter myTrueFilter = new FileFilter() { public boolean accept(File s) { return s.isFile(); } }; private static FileFilter createFilter(final Collection<String> excludes) { if (excludes == null) { return myTrueFilter; } StringBuilder buf = new StringBuilder(); for (String exclude : excludes) { StringBuilder alternative = new StringBuilder(); if (exclude != null) { for (int i = 0; i < exclude.length(); i++) { final char c = exclude.charAt(i); switch (c) { case '.': case '\\': case '*': case '^': case '$': case '[': case '(': case '|': alternative.append("\\"); alternative.append(c); break; case '?': alternative.append("."); break; default: alternative.append(c); } } } if (alternative.length() > 0) { alternative.append(".*"); if (buf.length() > 0) buf.append("|"); buf.append("("); buf.append(alternative); buf.append(')'); } } if (buf.length() > 0) { final Pattern patt = Pattern.compile(buf.toString()); return new FileFilter() { public boolean accept(File f) { final Matcher m = patt.matcher(f.getAbsolutePath()); final boolean ok = !m.matches(); return ok && f.isFile(); } }; } return myTrueFilter; } public static Result getFiles(final Set<String> roots, final Set<String> excludes, final ProjectWrapper pw) { final Crawler cw = new Crawler(createFilter(excludes), pw); for (String root : roots) cw.run(new File(pw.getAbsolutePath(root))); return cw.getResult(); } }