You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by st...@apache.org on 2012/08/29 19:29:58 UTC

svn commit: r1378655 - in /maven/shared/trunk/maven-shared-utils/src: main/java/org/apache/maven/shared/utils/io/ test/java/org/apache/maven/shared/utils/io/

Author: struberg
Date: Wed Aug 29 17:29:58 2012
New Revision: 1378655

URL: http://svn.apache.org/viewvc?rev=1378655&view=rev
Log:
MSHARED-238 introduce ScanConductor and adopt scandir

Added:
    maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/ScanConductor.java   (with props)
Modified:
    maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/DirectoryScanner.java
    maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/SelectorUtils.java
    maven/shared/trunk/maven-shared-utils/src/test/java/org/apache/maven/shared/utils/io/DirectoryScannerTest.java

Modified: maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/DirectoryScanner.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/DirectoryScanner.java?rev=1378655&r1=1378654&r2=1378655&view=diff
==============================================================================
--- maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/DirectoryScanner.java (original)
+++ maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/DirectoryScanner.java Wed Aug 29 17:29:58 2012
@@ -105,6 +105,8 @@ import java.util.Vector;
  * </pre>
  * This will scan a directory called test for .class files, but excludes all
  * files in all proper subdirectories of a directory called "modules"
+ * <p>
+ * This class must not be used from multiple Threads concurrently!
  *
  * @author Arnout J. Kuiper
  * <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
@@ -232,6 +234,17 @@ public class DirectoryScanner
     protected boolean everythingIncluded = true;
 
     /**
+     * A {@link ScanConductor} an control the scanning process.
+     */
+    protected ScanConductor scanConductor = null;
+
+    /**
+     * The last ScanAction. We need to store this in the instance
+     * as the scan() method doesn't return
+     */
+    private ScanConductor.ScanAction scanAction = null;
+
+    /**
      * Sole constructor.
      */
     public DirectoryScanner()
@@ -491,6 +504,11 @@ public class DirectoryScanner
         }
     }
 
+    public void setScanConductor( ScanConductor scanConductor )
+    {
+        this.scanConductor = scanConductor;
+    }
+
     /**
      * Returns whether or not the scanner has included all the files or
      * directories it has come across so far.
@@ -548,6 +566,7 @@ public class DirectoryScanner
         dirsNotIncluded = new Vector();
         dirsExcluded = new Vector();
         dirsDeselected = new Vector();
+        scanAction = ScanConductor.ScanAction.CONTINUE;
 
         if ( isIncluded( "" ) )
         {
@@ -555,6 +574,19 @@ public class DirectoryScanner
             {
                 if ( isSelected( "", basedir ) )
                 {
+                    if ( scanConductor != null )
+                    {
+                        scanAction = scanConductor.visitDirectory( "", basedir );
+
+                        if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) ||
+                             ScanConductor.ScanAction.ABORT_DIRECTORY.equals( scanAction ) ||
+                             ScanConductor.ScanAction.NO_RECURSE.equals( scanAction ) )
+                        {
+                            return;
+                        }
+                    }
+
+
                     dirsIncluded.addElement( "" );
                 }
                 else
@@ -715,11 +747,31 @@ public class DirectoryScanner
                     {
                         if ( isSelected( name, file ) )
                         {
-                            dirsIncluded.addElement( name );
-                            if ( fast )
+                            if ( scanConductor != null )
                             {
-                                scandir( file, name + File.separator, fast );
+                                scanAction = scanConductor.visitDirectory( name, file );
+
+                                if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) ||
+                                     ScanConductor.ScanAction.ABORT_DIRECTORY.equals( scanAction ) )
+                                {
+                                    return;
+                                }
+                            }
+
+                            if ( !ScanConductor.ScanAction.NO_RECURSE.equals( scanAction ) )
+                            {
+                                dirsIncluded.addElement( name );
+                                if ( fast )
+                                {
+                                    scandir( file, name + File.separator, fast );
+
+                                    if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) )
+                                    {
+                                        return;
+                                    }
+                                }
                             }
+                            scanAction = null;
                         }
                         else
                         {
@@ -728,6 +780,11 @@ public class DirectoryScanner
                             if ( fast && couldHoldIncluded( name ) )
                             {
                                 scandir( file, name + File.separator, fast );
+                                if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) )
+                                {
+                                    return;
+                                }
+                                scanAction = null;
                             }
                         }
 
@@ -739,21 +796,50 @@ public class DirectoryScanner
                         if ( fast && couldHoldIncluded( name ) )
                         {
                             scandir( file, name + File.separator, fast );
+                            if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) )
+                            {
+                                return;
+                            }
+                            scanAction = null;
                         }
                     }
                 }
                 else
                 {
                     everythingIncluded = false;
-                    dirsNotIncluded.addElement( name );
                     if ( fast && couldHoldIncluded( name ) )
                     {
-                        scandir( file, name + File.separator, fast );
+                        if ( scanConductor != null )
+                        {
+                            scanAction = scanConductor.visitDirectory( name, file );
+
+                            if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) ||
+                                    ScanConductor.ScanAction.ABORT_DIRECTORY.equals( scanAction ) )
+                            {
+                                return;
+                            }
+                        }
+                        if ( !ScanConductor.ScanAction.NO_RECURSE.equals( scanAction ) )
+                        {
+                            dirsNotIncluded.addElement( name );
+
+                            scandir( file, name + File.separator, fast );
+                            if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) )
+                            {
+                                return;
+                            }
+                        }
+                        scanAction = null;
                     }
                 }
                 if ( !fast )
                 {
                     scandir( file, name + File.separator, fast );
+                    if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) )
+                    {
+                        return;
+                    }
+                    scanAction = null;
                 }
             }
             else if ( file.isFile() )
@@ -764,6 +850,17 @@ public class DirectoryScanner
                     {
                         if ( isSelected( name, file ) )
                         {
+                            if ( scanConductor != null )
+                            {
+                                scanAction = scanConductor.visitFile( name, file );
+                            }
+
+                            if ( ScanConductor.ScanAction.ABORT.equals( scanAction ) ||
+                                 ScanConductor.ScanAction.ABORT_DIRECTORY.equals( scanAction ) )
+                            {
+                                return;
+                            }
+
                             filesIncluded.addElement( name );
                         }
                         else

Added: maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/ScanConductor.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/ScanConductor.java?rev=1378655&view=auto
==============================================================================
--- maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/ScanConductor.java (added)
+++ maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/ScanConductor.java Wed Aug 29 17:29:58 2012
@@ -0,0 +1,65 @@
+package org.apache.maven.shared.utils.io;
+
+import java.io.File;
+
+/**
+ * <p>Visitor pattern for the DirectoryScanner. A ScanConductor controls the scanning process.</p>
+ *
+ * <p>Create an instance and pass it to
+ * {@link org.apache.maven.shared.utils.io.DirectoryScanner#setScanConductor(ScanConductor)}.
+ * You will get notified about every visited directory and file. You can use the {@link ScanAction}
+ * to control what should happen next.</p>
+ *
+ * <p>A ScanConductor might also store own information but users must make sure that the state gets
+ * cleaned between two scan() invocations.</p>
+ *
+ * @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
+ */
+public interface ScanConductor
+{
+    public enum ScanAction
+    {
+        /**
+         * Abort the whole scanning process. The current file will not
+         * be added anymore.
+         */
+        ABORT,
+
+        /**
+         * Continue the scanning with the next item in the list.
+         */
+        CONTINUE,
+
+        /**
+         * This response is only valid for {@link ScanConductor#visitDirectory(String, java.io.File)}.
+         * Do not recurse into the current directory. The current directory will not be added
+         * and the processing will be continued with the next item in the list.
+         */
+        NO_RECURSE,
+
+        /**
+         * Abort processing the current directory.
+         * The current file will not be added.
+         * The processing will continue it's scan in the parent directory if any.
+         */
+        ABORT_DIRECTORY
+    }
+
+    /**
+     * This method will get invoked for every detected directory.
+     *
+     * @param name the directory name (contains parent folders up to the pwd)
+     * @param directory
+     * @return the ScanAction to control how to proceed with the scanning
+     */
+    ScanAction visitDirectory( String name, File directory );
+
+    /**
+     * This method will get invoked for every detected file.
+     *
+     * @param name the file name (contains parent folders up to the pwd)
+     * @param file
+     * @return the ScanAction to control how to proceed with the scanning
+     */
+    ScanAction visitFile( String name, File file );
+}

Propchange: maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/ScanConductor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/SelectorUtils.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/SelectorUtils.java?rev=1378655&r1=1378654&r2=1378655&view=diff
==============================================================================
--- maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/SelectorUtils.java (original)
+++ maven/shared/trunk/maven-shared-utils/src/main/java/org/apache/maven/shared/utils/io/SelectorUtils.java Wed Aug 29 17:29:58 2012
@@ -20,6 +20,8 @@ package org.apache.maven.shared.utils.io
  */
 
 
+import org.apache.maven.shared.utils.StringUtils;
+
 import java.io.File;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -643,7 +645,7 @@ public final class SelectorUtils
      *
      * @param src the original file
      * @param target the file being compared against
-     * @param granularity the amount in seconds of slack we will give in
+     * @param granularity the amount in milliseconds of slack we will give in
      *        determining out of dateness
      * @return whether the target is out of date
      */

Modified: maven/shared/trunk/maven-shared-utils/src/test/java/org/apache/maven/shared/utils/io/DirectoryScannerTest.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-shared-utils/src/test/java/org/apache/maven/shared/utils/io/DirectoryScannerTest.java?rev=1378655&r1=1378654&r2=1378655&view=diff
==============================================================================
--- maven/shared/trunk/maven-shared-utils/src/test/java/org/apache/maven/shared/utils/io/DirectoryScannerTest.java (original)
+++ maven/shared/trunk/maven-shared-utils/src/test/java/org/apache/maven/shared/utils/io/DirectoryScannerTest.java Wed Aug 29 17:29:58 2012
@@ -28,7 +28,9 @@ import org.junit.rules.TemporaryFolder;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 public class DirectoryScannerTest
 {
@@ -51,6 +53,11 @@ public class DirectoryScannerTest
 
         FileTestHelper.generateTestFile( new File( folder1, "file4.txt" ), 14 );
         FileTestHelper.generateTestFile( new File( folder1, "file5.dat" ), 15 );
+
+        File folder2 = new File( folder1, "ignorefolder" );
+        folder2.mkdirs();
+        FileTestHelper.generateTestFile( new File( folder2, "file7.txt" ), 17 );
+
     }
 
     @Test
@@ -169,6 +176,10 @@ public class DirectoryScannerTest
             ds.setExcludes( excludes );
         }
 
+        TestScanConductor scanConductor =  new TestScanConductor();
+
+        ds.setScanConductor( scanConductor );
+
         ds.scan();
 
         checkFiles( "expectedIncludedFiles", expectedIncludedFiles, ds.getIncludedFiles() );
@@ -177,6 +188,8 @@ public class DirectoryScannerTest
         checkFiles( "expectedNotIncludedDirectories", expectedNotIncludedDirectories, ds.getNotIncludedDirectories() );
         checkFiles( "expectedExcludedFiles", expectedExcludedFiles, ds.getExcludedFiles() );
         checkFiles( "expectedExcludedDirectories", expectedExcludedDirectories, ds.getExcludedDirectories() );
+
+        checkFiles( "visitedFiles", expectedIncludedFiles, scanConductor.visitedFiles.toArray( new String[ 0 ] ) );
     }
 
     /**
@@ -201,4 +214,28 @@ public class DirectoryScannerTest
             }
         }
     }
+
+    private static class TestScanConductor implements ScanConductor
+    {
+        List<String> visitedFiles = new ArrayList<String>();
+
+        public ScanConductor.ScanAction visitDirectory( String name, File directory )
+        {
+            Assert.assertTrue( directory.isDirectory() );
+
+            if ( directory.getName().equals( "ignorefolder" ) )
+            {
+                return ScanAction.NO_RECURSE;
+            }
+
+            return ScanAction.CONTINUE;
+        }
+
+        public ScanConductor.ScanAction visitFile( String name, File file )
+        {
+            Assert.assertTrue( file.isFile() );
+            visitedFiles.add( name );
+            return ScanAction.CONTINUE;
+        }
+    }
 }