tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject git commit: Remove some unwanted tail recursion when scanning the classpath
Date Mon, 08 Oct 2012 17:06:01 GMT
Updated Branches:
  refs/heads/5.4-js-rewrite 5d2cbf66a -> c1279a4d6


Remove some unwanted tail recursion when scanning the classpath


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/c1279a4d
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/c1279a4d
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/c1279a4d

Branch: refs/heads/5.4-js-rewrite
Commit: c1279a4d69dbd520a2cae9e332f40b357e2412f4
Parents: 5d2cbf6
Author: Howard M. Lewis Ship <hlship@apache.org>
Authored: Mon Oct 8 10:05:52 2012 -0700
Committer: Howard M. Lewis Ship <hlship@apache.org>
Committed: Mon Oct 8 10:05:52 2012 -0700

----------------------------------------------------------------------
 .../internal/services/ClasspathScannerImpl.java    |   69 ++++++++++-----
 1 files changed, 47 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c1279a4d/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClasspathScannerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClasspathScannerImpl.java
b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClasspathScannerImpl.java
index c006c0f..338f7a1 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClasspathScannerImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClasspathScannerImpl.java
@@ -39,6 +39,7 @@ public class ClasspathScannerImpl implements ClasspathScanner
 
     private final Pattern FOLDER_NAME_PATTERN = Pattern.compile("^\\p{javaJavaIdentifierStart}[\\p{javaJavaIdentifierPart}]*$",
Pattern.CASE_INSENSITIVE);
 
+
     public ClasspathScannerImpl(ClasspathURLConverter converter)
     {
         this.converter = converter;
@@ -125,26 +126,28 @@ public class ClasspathScannerImpl implements ClasspathScanner
         return null;
     }
 
-    static class Queued
+    /**
+     * Variation of {@link Runnable} that throws {@link IOException}.  Still think checked
exceptions are a good idea?
+     */
+    interface IOWork
     {
-        final URL packageURL;
-
-        final String packagePath;
-
-        public Queued(final URL packageURL, final String packagePath)
-        {
-            this.packageURL = packageURL;
-            this.packagePath = packagePath;
-        }
+        void run() throws IOException;
     }
 
+    /**
+     * Encapsulates the data, result, and queue of deferred operations for performing the
scan.
+     */
     class Job
     {
         final ClasspathMatcher matcher;
 
         final Set<String> matches = CollectionFactory.newSet();
 
-        final Stack<Queued> queue = CollectionFactory.newStack();
+        /**
+         * Explicit queue used to avoid deep tail-recursion.
+         */
+        final Stack<IOWork> queue = CollectionFactory.newStack();
+
 
         Job(ClasspathMatcher matcher)
         {
@@ -166,16 +169,16 @@ public class ClasspathScannerImpl implements ClasspathScanner
 
                 while (!queue.isEmpty())
                 {
-                    Queued queued = queue.pop();
+                    IOWork queued = queue.pop();
 
-                    scanDirStream(queued.packagePath, queued.packageURL);
+                    queued.run();
                 }
             }
 
             return matches;
         }
 
-        void scanURL(String packagePath, URL url) throws IOException
+        void scanURL(final String packagePath, final URL url) throws IOException
         {
             URLConnection connection = url.openConnection();
 
@@ -194,7 +197,14 @@ public class ClasspathScannerImpl implements ClasspathScanner
                 scanJarFile(packagePath, jarFile);
             } else if (supportsDirStream(url))
             {
-                queue.push(new Queued(url, packagePath));
+                queue.push(new IOWork()
+                {
+                    @Override
+                    public void run() throws IOException
+                    {
+                        scanDirStream(packagePath, url);
+                    }
+                });
             } else
             {
                 // Try scanning file system.
@@ -216,15 +226,22 @@ public class ClasspathScannerImpl implements ClasspathScanner
         {
             if (packageDir.exists() && packageDir.isDirectory())
             {
-                for (File file : packageDir.listFiles())
+                for (final File file : packageDir.listFiles())
                 {
                     String fileName = file.getName();
 
                     if (file.isDirectory())
                     {
-                        // TODO: A second queue instead of recursion.
+                        final String nestedPackagePath = fileName + "/";
 
-                        scanDir(packagePath + fileName + "/", file);
+                        queue.push(new IOWork()
+                        {
+                            @Override
+                            public void run() throws IOException
+                            {
+                                scanDir(nestedPackagePath, file);
+                            }
+                        });
                     }
 
                     if (matcher.matches(packagePath, fileName))
@@ -273,13 +290,21 @@ public class ClasspathScannerImpl implements ClasspathScanner
 
                         if (FOLDER_NAME_PATTERN.matcher(line).matches())
                         {
-                            URL newURL = new URL(packageURL.toExternalForm() + line + "/");
-                            String newPackagePath = packagePath + line + "/";
-
-                            queue.push(new Queued(newURL, newPackagePath));
+                            final URL newURL = new URL(packageURL.toExternalForm() + line
+ "/");
+                            final String nestedPackagePath = packagePath + line + "/";
+
+                            queue.push(new IOWork()
+                            {
+                                @Override
+                                public void run() throws IOException
+                                {
+                                    scanURL(nestedPackagePath, newURL);
+                                }
+                            });
                         }
                     }
                 }
+
                 lineReader.close();
                 lineReader = null;
             } finally


Mime
View raw message