diff --git a/src/etc/testcases/core/directoryscanner.xml b/src/etc/testcases/core/directoryscanner.xml
index 31a5fc884..5417a4ee9 100644
--- a/src/etc/testcases/core/directoryscanner.xml
+++ b/src/etc/testcases/core/directoryscanner.xml
@@ -1,14 +1,20 @@
File.separatorChar
.
*
* @param basedir The base directory to scan.
- * Must not be null
.
*/
public void setBasedir(String basedir) {
- setBasedir(new File(basedir.replace('/', File.separatorChar).replace(
- '\\', File.separatorChar)));
+ setBasedir(basedir == null ? (File) null
+ : new File(basedir.replace('/', File.separatorChar).replace(
+ '\\', File.separatorChar)));
}
/**
@@ -567,7 +568,6 @@ public class DirectoryScanner
* scanned recursively.
*
* @param basedir The base directory for scanning.
- * Should not be null
.
*/
public synchronized void setBasedir(File basedir) {
this.basedir = basedir;
@@ -577,7 +577,7 @@ public class DirectoryScanner
* Return the base directory to be scanned.
* This is the directory which is scanned recursively.
*
- * @return the base directory to be scanned
+ * @return the base directory to be scanned.
*/
public synchronized File getBasedir() {
return basedir;
@@ -741,13 +741,14 @@ public class DirectoryScanner
}
/**
- * Scan the base directory for files which match at least one include
- * pattern and don't match any exclude patterns. If there are selectors
- * then the files must pass muster there, as well.
+ * Scan for files which match at least one include pattern and don't match
+ * any exclude patterns. If there are selectors then the files must pass
+ * muster there, as well. Scans under basedir, if set; otherwise the
+ * include patterns without leading wildcards specify the absolute paths of
+ * the files that may be included.
*
* @exception IllegalStateException if the base directory was set
- * incorrectly (i.e. if it is null
, doesn't exist,
- * or isn't a directory).
+ * incorrectly (i.e. if it doesn't exist or isn't a directory).
*/
public void scan() throws IllegalStateException {
synchronized (scanLock) {
@@ -778,19 +779,22 @@ public class DirectoryScanner
excludes = nullExcludes ? new String[0] : excludes;
if (basedir == null) {
- illegal = new IllegalStateException("No basedir set");
+ // if no basedir and no includes, nothing to do:
+ if (nullIncludes) {
+ return;
+ }
} else {
if (!basedir.exists()) {
illegal = new IllegalStateException("basedir " + basedir
- + " does not exist");
+ + " does not exist");
}
if (!basedir.isDirectory()) {
illegal = new IllegalStateException("basedir " + basedir
- + " is not a directory");
+ + " is not a directory");
+ }
+ if (illegal != null) {
+ throw illegal;
}
- }
- if (illegal != null) {
- throw illegal;
}
if (isIncluded("")) {
if (!isExcluded("")) {
@@ -828,10 +832,21 @@ public class DirectoryScanner
// put in the newroots vector the include patterns without
// wildcard tokens
for (int icounter = 0; icounter < includes.length; icounter++) {
+ if (FileUtils.isAbsolutePath(includes[icounter])) {
+ //skip abs. paths not under basedir, if set:
+ if (basedir != null
+ && !SelectorUtils.matchPatternStart(includes[icounter],
+ basedir.getAbsolutePath(), isCaseSensitive())) {
+ continue;
+ }
+ } else if (basedir == null) {
+ //skip non-abs. paths if basedir == null:
+ continue;
+ }
newroots.put(SelectorUtils.rtrimWildcardTokens(
includes[icounter]), includes[icounter]);
}
- if (newroots.containsKey("")) {
+ if (newroots.containsKey("") && basedir != null) {
// we are going to scan everything anyway
scandir(basedir, "", true);
} else {
@@ -840,13 +855,18 @@ public class DirectoryScanner
Enumeration enum2 = newroots.keys();
File canonBase = null;
- try {
- canonBase = basedir.getCanonicalFile();
- } catch (IOException ex) {
- throw new BuildException(ex);
+ if (basedir != null) {
+ try {
+ canonBase = basedir.getCanonicalFile();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
}
while (enum2.hasMoreElements()) {
String currentelement = (String) enum2.nextElement();
+ if (basedir == null && !FileUtils.isAbsolutePath(currentelement)) {
+ continue;
+ }
String originalpattern = (String) newroots.get(currentelement);
File myfile = new File(basedir, currentelement);
@@ -855,15 +875,15 @@ public class DirectoryScanner
// the results to show what's really on the disk, so
// we need to double check.
try {
- File canonFile = myfile.getCanonicalFile();
- String path = FILE_UTILS.removeLeadingPath(canonBase,
- canonFile);
+ String path = (basedir == null)
+ ? myfile.getCanonicalPath()
+ : FILE_UTILS.removeLeadingPath(canonBase,
+ myfile.getCanonicalFile());
if (!path.equals(currentelement) || ON_VMS) {
myfile = findFile(basedir, currentelement, true);
- if (myfile != null) {
- currentelement =
- FILE_UTILS.removeLeadingPath(basedir,
- myfile);
+ if (myfile != null && basedir != null) {
+ currentelement = FILE_UTILS.removeLeadingPath(
+ basedir, myfile);
}
}
} catch (IOException ex) {
@@ -875,8 +895,9 @@ public class DirectoryScanner
if (f != null && f.exists()) {
// adapt currentelement to the case we've
// actually found
- currentelement = FILE_UTILS.removeLeadingPath(basedir,
- f);
+ currentelement = (basedir == null)
+ ? f.getAbsolutePath()
+ : FILE_UTILS.removeLeadingPath(basedir, f);
myfile = f;
}
}
@@ -1475,9 +1496,7 @@ public class DirectoryScanner
* @since Ant 1.5.2
*/
public synchronized Resource getResource(String name) {
- File f = FILE_UTILS.resolveFile(basedir, name);
- return new Resource(name, f.exists(), f.lastModified(),
- f.isDirectory(), f.length());
+ return new FileResource(basedir, name);
}
/**
@@ -1510,6 +1529,21 @@ public class DirectoryScanner
* @since Ant 1.6.3
*/
private File findFile(File base, String path, boolean cs) {
+ if (FileUtils.isAbsolutePath(path)) {
+ if (base == null) {
+ String[] s = FILE_UTILS.dissect(path);
+ base = new File(s[0]);
+ path = s[1];
+ } else {
+ File f = FILE_UTILS.normalize(path);
+ String s = FILE_UTILS.removeLeadingPath(base, f);
+ if (s.equals(f.getAbsolutePath())) {
+ //removing base from path yields no change; path not child of base
+ return null;
+ }
+ path = s;
+ }
+ }
return findFile(base, SelectorUtils.tokenizePath(path), cs);
}
@@ -1528,6 +1562,10 @@ public class DirectoryScanner
if (pathElements.size() == 0) {
return base;
}
+ String current = (String) pathElements.remove(0);
+ if (base == null) {
+ return findFile(new File(current), pathElements, cs);
+ }
if (!base.isDirectory()) {
return null;
}
@@ -1536,8 +1574,6 @@ public class DirectoryScanner
throw new BuildException("IO error scanning directory "
+ base.getAbsolutePath());
}
- String current = (String) pathElements.remove(0);
-
boolean[] matchCase = cs ? CS_SCAN_ONLY : CS_THEN_NON_CS;
for (int i = 0; i < matchCase.length; i++) {
for (int j = 0; j < files.length; j++) {
diff --git a/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java b/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
index 7483d8bbd..5c022a023 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
@@ -22,6 +22,7 @@ import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
/**
*
This is a utility class used by selectors and DirectoryScanner. The @@ -36,6 +37,7 @@ import org.apache.tools.ant.types.Resource; public final class SelectorUtils { private static SelectorUtils instance = new SelectorUtils(); + private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); /** * Private Constructor @@ -164,15 +166,6 @@ public final class SelectorUtils { */ public static boolean matchPath(String pattern, String str, boolean isCaseSensitive) { - // When str starts with a File.separator, pattern has to start with a - // File.separator. - // When pattern starts with a File.separator, str has to start with a - // File.separator. - if (str.startsWith(File.separator) - != pattern.startsWith(File.separator)) { - return false; - } - String[] patDirs = tokenizePathAsArray(pattern); String[] strDirs = tokenizePathAsArray(str); @@ -502,6 +495,11 @@ public final class SelectorUtils { */ public static Vector tokenizePath (String path, String separator) { Vector ret = new Vector(); + if (FileUtils.isAbsolutePath(path)) { + String[] s = FILE_UTILS.dissect(path); + ret.add(s[0]); + path = s[1]; + } StringTokenizer st = new StringTokenizer(path, separator); while (st.hasMoreTokens()) { ret.addElement(st.nextToken()); @@ -513,6 +511,12 @@ public final class SelectorUtils { * Same as {@link #tokenizePath tokenizePath} but hopefully faster. */ private static String[] tokenizePathAsArray(String path) { + String root = null; + if (FileUtils.isAbsolutePath(path)) { + String[] s = FILE_UTILS.dissect(path); + root = s[0]; + path = s[1]; + } char sep = File.separatorChar; int start = 0; int len = path.length(); @@ -528,8 +532,14 @@ public final class SelectorUtils { if (len != start) { count++; } - String[] l = new String[count]; - count = 0; + String[] l = new String[count + ((root == null) ? 0 : 1)]; + + if (root != null) { + l[0] = root; + count = 1; + } else { + count = 0; + } start = 0; for (int pos = 0; pos < len; pos++) { if (path.charAt(pos) == sep) { @@ -643,7 +653,7 @@ public final class SelectorUtils { if (hasWildcards((String) v.elementAt(counter))) { break; } - if (counter > 0) { + if (counter > 0 && sb.charAt(sb.length() - 1) != File.separatorChar) { sb.append(File.separator); } sb.append((String) v.elementAt(counter)); diff --git a/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java b/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java index aefd92927..7d0600e64 100644 --- a/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java +++ b/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java @@ -415,6 +415,75 @@ public class DirectoryScannerTest extends BuildFileTest { assertFalse("scanned " + s, set.contains(s)); } + public void testAbsolute1() { + getProject().executeTarget("extended-setup"); + DirectoryScanner ds = new DirectoryScanner(); + String tmpdir = getProject().getBaseDir().getAbsolutePath().replace( + File.separatorChar, '/') + "/tmp"; + ds.setIncludes(new String[] {tmpdir + "/**/*"}); + ds.scan(); + compareFiles(ds, new String[] {tmpdir + "/alpha/beta/beta.xml", + tmpdir + "/alpha/beta/gamma/gamma.xml", + tmpdir + "/delta/delta.xml"}, + new String[] {tmpdir + "/alpha", + tmpdir + "/alpha/beta", + tmpdir + "/alpha/beta/gamma", + tmpdir + "/delta"}); + } + + public void testAbsolute2() { + getProject().executeTarget("setup"); + DirectoryScanner ds = new DirectoryScanner(); + ds.setIncludes(new String[] {"alpha/**", "alpha/beta/gamma/**"}); + ds.scan(); + String[] mt = new String[0]; + compareFiles(ds, mt, mt); + } + + public void testAbsolute3() { + getProject().executeTarget("extended-setup"); + DirectoryScanner ds = new DirectoryScanner(); + String tmpdir = getProject().getBaseDir().getAbsolutePath().replace( + File.separatorChar, '/') + "/tmp"; + ds.setIncludes(new String[] {tmpdir + "/**/*"}); + ds.setExcludes(new String[] {"**/alpha", + "**/delta/*"}); + ds.scan(); + compareFiles(ds, new String[] {tmpdir + "/alpha/beta/beta.xml", + tmpdir + "/alpha/beta/gamma/gamma.xml"}, + new String[] {tmpdir + "/alpha/beta", + tmpdir + "/alpha/beta/gamma", + tmpdir + "/delta"}); + } + + public void testAbsolute4() { + getProject().executeTarget("extended-setup"); + DirectoryScanner ds = new DirectoryScanner(); + String tmpdir = getProject().getBaseDir().getAbsolutePath().replace( + File.separatorChar, '/') + "/tmp"; + ds.setIncludes(new String[] {tmpdir + "/alpha/beta/**/*", + tmpdir + "/delta/*"}); + ds.setExcludes(new String[] {"**/beta.xml"}); + ds.scan(); + compareFiles(ds, new String[] {tmpdir + "/alpha/beta/gamma/gamma.xml", + tmpdir + "/delta/delta.xml"}, + new String[] {tmpdir + "/alpha/beta/gamma"}); + } + + public void testAbsolute5() { + //testing drive letter search from root: + if (!(Os.isFamily("dos") || Os.isFamily("netware"))) { + return; + } + DirectoryScanner ds = new DirectoryScanner(); + String pattern = new File(File.separator).getAbsolutePath().toUpperCase() + "*"; + ds.setIncludes(new String[] {pattern}); + ds.scan(); + //if this is our context we assume there must be something here: + assertTrue("should have at least one resident file", + ds.getIncludedFilesCount() + ds.getIncludedDirsCount() > 0); + } + private void compareFiles(DirectoryScanner ds, String[] expectedFiles, String[] expectedDirectories) { String includedFiles[] = ds.getIncludedFiles();