mbenson 2005/05/23 12:31:14 Modified: src/main/org/apache/tools/ant DirectoryScanner.java src/main/org/apache/tools/ant/types/selectors SelectorUtils.java src/testcases/org/apache/tools/ant DirectoryScannerTest.java src/etc/testcases/core directoryscanner.xml Log: allow absolute include paths & no basedir for Directory scanning Revision Changes Path 1.101 +71 -35 ant/src/main/org/apache/tools/ant/DirectoryScanner.java Index: DirectoryScanner.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/DirectoryScanner.java,v retrieving revision 1.100 retrieving revision 1.101 diff -u -r1.100 -r1.101 --- DirectoryScanner.java 10 May 2005 07:37:04 -0000 1.100 +++ DirectoryScanner.java 23 May 2005 19:31:13 -0000 1.101 @@ -35,6 +35,7 @@ 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 @@ * <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 @@ * 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 @@ * 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 @@ } /** - * 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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ * @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 @@ * @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 @@ 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 @@ 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++) { 1.21 +22 -12 ant/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java Index: SelectorUtils.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- SelectorUtils.java 9 Mar 2004 16:48:47 -0000 1.20 +++ SelectorUtils.java 23 May 2005 19:31:14 -0000 1.21 @@ -22,6 +22,7 @@ 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 @@ 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 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 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 @@ * Same as [EMAIL PROTECTED] #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 @@ 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 @@ 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)); 1.35 +69 -0 ant/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java Index: DirectoryScannerTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- DirectoryScannerTest.java 7 Mar 2005 23:25:51 -0000 1.34 +++ DirectoryScannerTest.java 23 May 2005 19:31:14 -0000 1.35 @@ -415,6 +415,75 @@ 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(); 1.4 +9 -2 ant/src/etc/testcases/core/directoryscanner.xml Index: directoryscanner.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/core/directoryscanner.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- directoryscanner.xml 28 Jul 2003 22:07:47 -0000 1.3 +++ directoryscanner.xml 23 May 2005 19:31:14 -0000 1.4 @@ -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> \ No newline at end of file + +</project>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]