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]

Reply via email to