mbenson 2005/02/10 15:52:00 Modified: src/main/org/apache/tools/ant DirectoryScanner.java Log: Synchronize scanning so that a scan initiated before the end of another scan will block and the two will share results. Likewise for slow scans. Revision Changes Path 1.84 +171 -84 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.83 retrieving revision 1.84 diff -u -r1.83 -r1.84 --- DirectoryScanner.java 10 Feb 2005 23:20:06 -0000 1.83 +++ DirectoryScanner.java 10 Feb 2005 23:51:59 -0000 1.84 @@ -326,6 +326,41 @@ private boolean areNonPatternSetsReady = false; /** + * Scanning flag. + * + * @since Ant 1.7 + */ + private boolean scanning = false; + + /** + * Scanning lock. + * + * @since Ant 1.7 + */ + private Object scanLock = new Object(); + + /** + * Slow scanning flag. + * + * @since Ant 1.7 + */ + private boolean slowScanning = false; + + /** + * Slow scanning lock. + * + * @since Ant 1.7 + */ + private Object slowScanLock = new Object(); + + /** + * Exception thrown during scan. + * + * @since Ant 1.7 + */ + private IllegalStateException illegal = null; + + /** * Sole constructor. */ public DirectoryScanner() { @@ -528,7 +563,7 @@ * @param basedir The base directory for scanning. * Should not be <code>null</code>. */ - public void setBasedir(File basedir) { + public synchronized void setBasedir(File basedir) { this.basedir = basedir; } @@ -538,7 +573,7 @@ * * @return the base directory to be scanned */ - public File getBasedir() { + public synchronized File getBasedir() { return basedir; } @@ -548,9 +583,10 @@ * @return whether or not the scanning is case sensitive. * @since Ant 1.6 */ - public boolean isCaseSensitive() { + public synchronized boolean isCaseSensitive() { return isCaseSensitive; } + /** * Set whether or not include and exclude patterns are matched * in a case sensitive way. @@ -558,7 +594,7 @@ * @param isCaseSensitive whether or not the file system should be * regarded as a case sensitive one. */ - public void setCaseSensitive(boolean isCaseSensitive) { + public synchronized void setCaseSensitive(boolean isCaseSensitive) { this.isCaseSensitive = isCaseSensitive; } @@ -569,7 +605,7 @@ * * @since Ant 1.6 */ - public boolean isFollowSymlinks() { + public synchronized boolean isFollowSymlinks() { return followSymlinks; } @@ -578,7 +614,7 @@ * * @param followSymlinks whether or not symbolic links should be followed. */ - public void setFollowSymlinks(boolean followSymlinks) { + public synchronized void setFollowSymlinks(boolean followSymlinks) { this.followSymlinks = followSymlinks; } @@ -595,7 +631,7 @@ * list is given, all elements must be * non-<code>null</code>. */ - public void setIncludes(String[] includes) { + public synchronized void setIncludes(String[] includes) { if (includes == null) { this.includes = null; } else { @@ -618,7 +654,7 @@ * should be excluded. If a non-<code>null</code> list is * given, all elements must be non-<code>null</code>. */ - public void setExcludes(String[] excludes) { + public synchronized void setExcludes(String[] excludes) { if (excludes == null) { this.excludes = null; } else { @@ -642,9 +678,9 @@ * * @since Ant 1.7 */ - public void addExcludes(String[] excludes) { - if (excludes != null) { - if (this.excludes != null) { + public synchronized void addExcludes(String[] excludes) { + if (excludes != null && excludes.length > 0) { + if (this.excludes != null && this.excludes.length > 0) { String[] tmp = new String[excludes.length + this.excludes.length]; System.arraycopy(this.excludes, 0, tmp, 0, @@ -683,7 +719,7 @@ * * @param selectors specifies the selectors to be invoked on a scan. */ - public void setSelectors(FileSelector[] selectors) { + public synchronized void setSelectors(FileSelector[] selectors) { this.selectors = selectors; } @@ -694,7 +730,7 @@ * @return <code>true</code> if all files and directories which have * been found so far have been included. */ - public boolean isEverythingIncluded() { + public synchronized boolean isEverythingIncluded() { return everythingIncluded; } @@ -708,51 +744,68 @@ * or isn't a directory). */ public void scan() throws IllegalStateException { - if (basedir == null) { - throw new IllegalStateException("No basedir set"); - } - if (!basedir.exists()) { - throw new IllegalStateException("basedir " + basedir - + " does not exist"); - } - if (!basedir.isDirectory()) { - throw new IllegalStateException("basedir " + basedir - + " is not a directory"); - } - - if (includes == null) { - // No includes supplied, so set it to 'matches all' - includes = new String[1]; - includes[0] = "**"; - } - if (excludes == null) { - excludes = new String[0]; + synchronized (scanLock) { + if (scanning) { + while (scanning) { + try { + scanLock.wait(); + } catch (InterruptedException e) { + continue; + } + } + if (illegal != null) { + throw illegal; + } + return; + } + scanning = true; } + try { + synchronized (this) { + illegal = null; + clearResults(); + + // set in/excludes to reasonable defaults if needed: + boolean nullIncludes = (includes == null); + includes = nullIncludes ? new String[] {"**"} : includes; + boolean nullExcludes = (excludes == null); + excludes = nullExcludes ? new String[0] : excludes; - filesIncluded = new Vector(); - filesNotIncluded = new Vector(); - filesExcluded = new Vector(); - filesDeselected = new Vector(); - dirsIncluded = new Vector(); - dirsNotIncluded = new Vector(); - dirsExcluded = new Vector(); - dirsDeselected = new Vector(); - - if (isIncluded("")) { - if (!isExcluded("")) { - if (isSelected("", basedir)) { - dirsIncluded.addElement(""); + if (basedir == null) { + throw new IllegalStateException("No basedir set"); + } + if (!basedir.exists()) { + throw new IllegalStateException("basedir " + basedir + + " does not exist"); + } + if (!basedir.isDirectory()) { + throw new IllegalStateException("basedir " + basedir + + " is not a directory"); + } + if (isIncluded("")) { + if (!isExcluded("")) { + if (isSelected("", basedir)) { + dirsIncluded.addElement(""); + } else { + dirsDeselected.addElement(""); + } + } else { + dirsExcluded.addElement(""); + } } else { - dirsDeselected.addElement(""); + dirsNotIncluded.addElement(""); } - } else { - dirsExcluded.addElement(""); + checkIncludePatterns(); + clearCaches(); + includes = nullIncludes ? null : includes; + excludes = nullExcludes ? null : excludes; + } + } finally { + synchronized (scanLock) { + scanning = false; + scanLock.notifyAll(); } - } else { - dirsNotIncluded.addElement(""); } - checkIncludePatterns(); - clearCaches(); } /** @@ -859,6 +912,21 @@ } /** + * Clear the result caches for a scan. + */ + protected synchronized void clearResults() { + filesIncluded = new Vector(); + filesNotIncluded = new Vector(); + filesExcluded = new Vector(); + filesDeselected = new Vector(); + dirsIncluded = new Vector(); + dirsNotIncluded = new Vector(); + dirsExcluded = new Vector(); + dirsDeselected = new Vector(); + everythingIncluded = (basedir != null); + } + + /** * Top level invocation for a slow scan. A slow scan builds up a full * list of excluded/included files/directories, whereas a fast scan * will only have full results for included files, as it ignores @@ -867,31 +935,50 @@ * Returns immediately if a slow scan has already been completed. */ protected void slowScan() { - if (haveSlowResults) { - return; - } - - String[] excl = new String[dirsExcluded.size()]; - dirsExcluded.copyInto(excl); - - String[] notIncl = new String[dirsNotIncluded.size()]; - dirsNotIncluded.copyInto(notIncl); - - for (int i = 0; i < excl.length; i++) { - if (!couldHoldIncluded(excl[i])) { - scandir(new File(basedir, excl[i]), - excl[i] + File.separator, false); + synchronized (slowScanLock) { + if (haveSlowResults) { + return; } + if (slowScanning) { + while (slowScanning) { + try { + slowScanLock.wait(); + } catch (InterruptedException e) { + } + } + return; + } + slowScanning = true; } + try { + synchronized (this) { - for (int i = 0; i < notIncl.length; i++) { - if (!couldHoldIncluded(notIncl[i])) { - scandir(new File(basedir, notIncl[i]), - notIncl[i] + File.separator, false); + String[] excl = new String[dirsExcluded.size()]; + dirsExcluded.copyInto(excl); + + String[] notIncl = new String[dirsNotIncluded.size()]; + dirsNotIncluded.copyInto(notIncl); + + for (int i = 0; i < excl.length; i++) { + if (!couldHoldIncluded(excl[i])) { + scandir(new File(basedir, excl[i]), + excl[i] + File.separator, false); + } + } + for (int i = 0; i < notIncl.length; i++) { + if (!couldHoldIncluded(notIncl[i])) { + scandir(new File(basedir, notIncl[i]), + notIncl[i] + File.separator, false); + } + } + } + } finally { + synchronized (slowScanLock) { + haveSlowResults = true; + slowScanning = false; + slowScanLock.notifyAll(); } } - - haveSlowResults = true; } /** @@ -1179,7 +1266,7 @@ * @return the names of the files which matched at least one of the * include patterns and none of the exclude patterns. */ - public String[] getIncludedFiles() { + public synchronized String[] getIncludedFiles() { if (filesIncluded == null) { throw new IllegalStateException(); } @@ -1194,7 +1281,7 @@ * @return <code>int</code>. * @since Ant 1.6.3 */ - public int getIncludedFilesCount() { + public synchronized int getIncludedFilesCount() { if (filesIncluded == null) { throw new IllegalStateException(); } @@ -1211,7 +1298,7 @@ * * @see #slowScan */ - public String[] getNotIncludedFiles() { + public synchronized String[] getNotIncludedFiles() { slowScan(); String[] files = new String[filesNotIncluded.size()]; filesNotIncluded.copyInto(files); @@ -1229,7 +1316,7 @@ * * @see #slowScan */ - public String[] getExcludedFiles() { + public synchronized String[] getExcludedFiles() { slowScan(); String[] files = new String[filesExcluded.size()]; filesExcluded.copyInto(files); @@ -1247,7 +1334,7 @@ * * @see #slowScan */ - public String[] getDeselectedFiles() { + public synchronized String[] getDeselectedFiles() { slowScan(); String[] files = new String[filesDeselected.size()]; filesDeselected.copyInto(files); @@ -1262,7 +1349,7 @@ * @return the names of the directories which matched at least one of the * include patterns and none of the exclude patterns. */ - public String[] getIncludedDirectories() { + public synchronized String[] getIncludedDirectories() { if (dirsIncluded == null) { throw new IllegalStateException(); } @@ -1277,7 +1364,7 @@ * @return <code>int</code>. * @since Ant 1.6.3 */ - public int getIncludedDirsCount() { + public synchronized int getIncludedDirsCount() { if (dirsIncluded == null) { throw new IllegalStateException(); } @@ -1294,7 +1381,7 @@ * * @see #slowScan */ - public String[] getNotIncludedDirectories() { + public synchronized String[] getNotIncludedDirectories() { slowScan(); String[] directories = new String[dirsNotIncluded.size()]; dirsNotIncluded.copyInto(directories); @@ -1312,7 +1399,7 @@ * * @see #slowScan */ - public String[] getExcludedDirectories() { + public synchronized String[] getExcludedDirectories() { slowScan(); String[] directories = new String[dirsExcluded.size()]; dirsExcluded.copyInto(directories); @@ -1330,7 +1417,7 @@ * * @see #slowScan */ - public String[] getDeselectedDirectories() { + public synchronized String[] getDeselectedDirectories() { slowScan(); String[] directories = new String[dirsDeselected.size()]; dirsDeselected.copyInto(directories); @@ -1340,7 +1427,7 @@ /** * Add default exclusions to the current exclusions set. */ - public void addDefaultExcludes() { + public synchronized void addDefaultExcludes() { int excludesLength = excludes == null ? 0 : excludes.length; String[] newExcludes; newExcludes = new String[excludesLength + defaultExcludes.size()]; @@ -1363,7 +1450,7 @@ * @return the resource with the given name. * @since Ant 1.5.2 */ - public Resource getResource(String name) { + 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());
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]