Browse Source

allow absolute include paths & no basedir for Directory scanning

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278334 13f79535-47bb-0310-9956-ffa450edef68
master
Matthew Jason Benson 20 years ago
parent
commit
b92e6b644f
4 changed files with 171 additions and 49 deletions
  1. +9
    -2
      src/etc/testcases/core/directoryscanner.xml
  2. +71
    -35
      src/main/org/apache/tools/ant/DirectoryScanner.java
  3. +22
    -12
      src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
  4. +69
    -0
      src/testcases/org/apache/tools/ant/DirectoryScannerTest.java

+ 9
- 2
src/etc/testcases/core/directoryscanner.xml View File

@@ -1,14 +1,20 @@
<project name="directoryscanner-test" basedir=".">

<property name="tmp.dir" location="tmp"/>

<target name="setup">
<mkdir dir="${tmp.dir}/alpha/beta/gamma"/>
<touch file="${tmp.dir}/alpha/beta/gamma/gamma.xml"/>
<touch file="${tmp.dir}/alpha/beta/beta.xml"/>
</target>
<target name="children-of-excluded-dir-setup" depends="setup">

<target name="extended-setup" depends="setup">
<mkdir dir="${tmp.dir}/delta"/>
<touch file="${tmp.dir}/delta/delta.xml"/>
</target>

<target name="children-of-excluded-dir-setup" depends="extended-setup" />

<target name="cleanup">
<delete dir="${tmp.dir}" quiet="true"/>
</target>
@@ -19,4 +25,5 @@
<symlink link="${tmp.dir}/alpha/beta" resource="${tmp.dir}/epsilon"/>
<touch file="${tmp.dir}/alpha/beta/gamma/gamma.xml"/>
</target>
</project>

</project>

+ 71
- 35
src/main/org/apache/tools/ant/DirectoryScanner.java View File

@@ -35,6 +35,7 @@ import org.apache.tools.ant.types.ResourceFactory;
import org.apache.tools.ant.types.selectors.FileSelector;
import org.apache.tools.ant.types.selectors.SelectorUtils;
import org.apache.tools.ant.types.selectors.SelectorScanner;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.util.FileUtils;

/**
@@ -555,11 +556,11 @@ public class DirectoryScanner
* <code>File.separatorChar</code>.
*
* @param basedir The base directory to scan.
* Must not be <code>null</code>.
*/
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 <code>null</code>.
*/
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 <code>null</code>, 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++) {


+ 22
- 12
src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java View File

@@ -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;

/**
* <p>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));


+ 69
- 0
src/testcases/org/apache/tools/ant/DirectoryScannerTest.java View File

@@ -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();


Loading…
Cancel
Save