From dd7d6b246e7e90f86c2ee86875b866eb228b12eb Mon Sep 17 00:00:00 2001 From: Matthew Jason Benson Date: Fri, 4 Mar 2005 23:41:21 +0000 Subject: [PATCH] By popular demand: Do not scan directories if their contents are excluded. Changed scannedDirs from a cache to a result and added a gettor method with a warning in the Javadoc that it was a testing method only. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277795 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tools/ant/DirectoryScanner.java | 29 +++++++++++++++++-- .../tools/ant/DirectoryScannerTest.java | 14 +++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/main/org/apache/tools/ant/DirectoryScanner.java b/src/main/org/apache/tools/ant/DirectoryScanner.java index e68859492..10f9e62c5 100644 --- a/src/main/org/apache/tools/ant/DirectoryScanner.java +++ b/src/main/org/apache/tools/ant/DirectoryScanner.java @@ -920,6 +920,7 @@ public class DirectoryScanner dirsExcluded = new Vector(); dirsDeselected = new Vector(); everythingIncluded = (basedir != null); + scannedDirs.clear(); } /** @@ -1118,7 +1119,7 @@ public class DirectoryScanner dirsDeselected.addElement(name); } everythingIncluded &= included; - if (fast && couldHoldIncluded(name)) { + if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) { scandir(file, name + File.separator, fast); } } @@ -1206,6 +1207,22 @@ public class DirectoryScanner return true; } + /** + * Test whether all contents of the specified directory must be excluded. + * @param name the directory name to check. + */ + private boolean contentsExcluded(String name) { + name = (name.endsWith(File.separator)) ? name : name + File.separator; + for (int i = 0; i < excludes.length; i++) { + String e = excludes[i]; + if (e.endsWith(File.separator + "**") && SelectorUtils.matchPath( + e.substring(0, e.length() - 2), name, isCaseSensitive())) { + return true; + } + } + return false; + } + /** * Test whether or not a name matches against at least one exclude * pattern. @@ -1565,6 +1582,15 @@ public class DirectoryScanner return !scannedDirs.add(vpath); } + /** + * This method is of interest for testing purposes. The returned + * Set is live and should not be modified. + * @return the Set of relative directory names that have been scanned. + */ + public Set getScannedDirs() { + return scannedDirs; + } + /** * Clear internal caches. * @@ -1572,7 +1598,6 @@ public class DirectoryScanner */ private synchronized void clearCaches() { fileListMap.clear(); - scannedDirs.clear(); includeNonPatterns.clear(); excludeNonPatterns.clear(); includePatterns = null; diff --git a/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java b/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java index 205d528ce..8a29be779 100644 --- a/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java +++ b/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java @@ -26,6 +26,7 @@ import junit.framework.TestCase; import junit.framework.AssertionFailedError; import java.io.File; import java.io.IOException; +import java.util.Set; import java.util.TreeSet; import java.util.Iterator; @@ -397,6 +398,19 @@ public class DirectoryScannerTest extends BuildFileTest { } + public void testIsExcludedDirectoryScanned() { + getProject().executeTarget("children-of-excluded-dir-setup"); + DirectoryScanner ds = new DirectoryScanner(); + ds.setBasedir(new File(getProject().getBaseDir(), "tmp")); + ds.setExcludes(new String[] {"**/gamma/**"}); + ds.setFollowSymlinks(false); + ds.scan(); + Set set = ds.getScannedDirs(); + assertFalse("empty set", set.isEmpty()); + String s = "alpha/beta/gamma/".replace('/', File.separatorChar); + assertFalse("scanned " + s, set.contains(s)); + } + private void compareFiles(DirectoryScanner ds, String[] expectedFiles, String[] expectedDirectories) { String includedFiles[] = ds.getIncludedFiles();