private void process(File dir, String fileName, List<Pattern> matchingIncludes) { // Increment patterns that need to move to the next token. boolean isFinalMatch = false; List<Pattern> incrementedPatterns = new ArrayList(); for (Iterator iter = matchingIncludes.iterator(); iter.hasNext(); ) { Pattern include = (Pattern) iter.next(); if (include.incr(fileName)) { incrementedPatterns.add(include); if (include.isExhausted()) iter.remove(); } if (include.wasFinalMatch()) isFinalMatch = true; } File file = new File(dir, fileName); if (isFinalMatch) { int length = rootDir.getPath().length(); if (!rootDir.getPath().endsWith(File.separator)) length++; // Lose starting slash. matches.add(file.getPath().substring(length)); } if (!matchingIncludes.isEmpty() && file.isDirectory()) scanDir(file, matchingIncludes); // Decrement patterns. for (Pattern include : incrementedPatterns) include.decr(); }
public GlobScanner( File rootDir, List<String> includes, List<String> excludes, boolean ignoreCase) { if (rootDir == null) throw new IllegalArgumentException("rootDir cannot be null."); if (!rootDir.exists()) throw new IllegalArgumentException("Directory does not exist: " + rootDir); if (!rootDir.isDirectory()) throw new IllegalArgumentException("File must be a directory: " + rootDir); try { rootDir = rootDir.getCanonicalFile(); } catch (IOException ex) { throw new RuntimeException("OS error determining canonical path: " + rootDir, ex); } this.rootDir = rootDir; if (includes == null) throw new IllegalArgumentException("includes cannot be null."); if (excludes == null) throw new IllegalArgumentException("excludes cannot be null."); if (includes.isEmpty()) includes.add("**"); List<Pattern> includePatterns = new ArrayList(includes.size()); for (String include : includes) includePatterns.add(new Pattern(include, ignoreCase)); List<Pattern> allExcludePatterns = new ArrayList(excludes.size()); for (String exclude : excludes) allExcludePatterns.add(new Pattern(exclude, ignoreCase)); scanDir(rootDir, includePatterns); if (!allExcludePatterns.isEmpty()) { // For each file, see if any exclude patterns match. outerLoop: // for (Iterator matchIter = matches.iterator(); matchIter.hasNext(); ) { String filePath = (String) matchIter.next(); List<Pattern> excludePatterns = new ArrayList(allExcludePatterns); try { // Shortcut for excludes that are "**/XXX", just check file name. for (Iterator excludeIter = excludePatterns.iterator(); excludeIter.hasNext(); ) { Pattern exclude = (Pattern) excludeIter.next(); if (exclude.values.length == 2 && exclude.values[0].equals("**")) { exclude.incr(); String fileName = filePath.substring(filePath.lastIndexOf(File.separatorChar) + 1); if (exclude.matches(fileName)) { matchIter.remove(); continue outerLoop; } excludeIter.remove(); } } // Get the file names after the root dir. String[] fileNames = filePath.split("\\" + File.separator); for (String fileName : fileNames) { for (Iterator excludeIter = excludePatterns.iterator(); excludeIter.hasNext(); ) { Pattern exclude = (Pattern) excludeIter.next(); if (!exclude.matches(fileName)) { excludeIter.remove(); continue; } exclude.incr(fileName); if (exclude.wasFinalMatch()) { // Exclude pattern matched. matchIter.remove(); continue outerLoop; } } // Stop processing the file if none of the exclude patterns matched. if (excludePatterns.isEmpty()) continue outerLoop; } } finally { for (Pattern exclude : allExcludePatterns) exclude.reset(); } } } }