You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by si...@apache.org on 2011/11/20 21:53:29 UTC

svn commit: r1204251 - in /commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath: ErrorHandlerBuilder.java PathAnalyzer.java

Author: simonetripodi
Date: Sun Nov 20 20:53:28 2011
New Revision: 1204251

URL: http://svn.apache.org/viewvc?rev=1204251&view=rev
Log:
use concurrent APIs to speedup the classpath scanning - thanks to Daniel Manzke

Added:
    commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java   (with props)
Modified:
    commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/ErrorHandlerBuilder.java

Modified: commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/ErrorHandlerBuilder.java
URL: http://svn.apache.org/viewvc/commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/ErrorHandlerBuilder.java?rev=1204251&r1=1204250&r2=1204251&view=diff
==============================================================================
--- commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/ErrorHandlerBuilder.java (original)
+++ commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/ErrorHandlerBuilder.java Sun Nov 20 20:53:28 2011
@@ -19,15 +19,14 @@ package org.apache.commons.meiyo.classpa
  * under the License.
  */
 
-import static java.util.regex.Pattern.compile;
+import static java.lang.Runtime.getRuntime;
+import static java.util.concurrent.Executors.newFixedThreadPool;
 
-import java.io.File;
-import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.regex.Pattern;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 
 /**
  * Builder to perform a scan, recording eventual errors inside a proper handler.
@@ -35,18 +34,12 @@ import java.util.regex.Pattern;
 public final class ErrorHandlerBuilder
 {
 
-    private static final Pattern JAR_FILE = compile( ".+\\.(jar|zip)", Pattern.CASE_INSENSITIVE );
-
-    private static final String CLASS_EXTENSION = ".class";
-
     private final String[] paths;
 
     private final Collection<ClassPathHandler> handlers;
 
     private final ClassLoader classLoader;
 
-    private ErrorHandler errorHandler;
-
     ErrorHandlerBuilder( String[] paths, Collection<ClassPathHandler> handlers, ClassLoader classLoader )
     {
         this.paths = paths;
@@ -74,91 +67,26 @@ public final class ErrorHandlerBuilder
             throw new IllegalArgumentException( "Parameter 'errorHandler' must not be null" );
         }
 
-        this.errorHandler = errorHandler;
+        ExecutorService executor = newFixedThreadPool( getRuntime().availableProcessors() );
+        List<Future<?>> futures = new ArrayList<Future<?>>();
 
         for ( String path : paths )
         {
-            File file = new File( path );
-            if ( JAR_FILE.matcher( path ).matches() )
-            {
-                try
-                {
-                    JarFile jarFile = new JarFile( path );
-                    Enumeration<JarEntry> enumeration = jarFile.entries();
-                    while ( enumeration.hasMoreElements() )
-                    {
-                        JarEntry entry = enumeration.nextElement();
-                        if ( !entry.isDirectory() )
-                        {
-                            handleEntry( entry.getName(), path );
-                        }
-                    }
-                }
-                catch ( IOException e )
-                {
-                    errorHandler.onJARReadingError( file, e );
-                }
-            }
-            else
-            {
-                traverse( file, path );
-            }
-            // else ignore it
+            futures.add( executor.submit( new PathAnalyzer( path, handlers, classLoader, errorHandler ) ) );
         }
-    }
 
-    /**
-     * Traverses recursively a directory and handle children with the input handlers.
-     *
-     * @param file the directory has to be traversed
-     * @param path the path where the input directory has been found
-     */
-    private void traverse( final File file, final String path )
-    {
-        if ( file.isDirectory() )
+        for ( Future<?> future : futures )
         {
-
-            for ( File child : file.listFiles() )
+            try
             {
-                traverse( child, path );
+                future.get();
             }
-
-            return;
-        }
-
-        handleEntry( file.getAbsolutePath().substring( path.length() + 1 ), path );
-    }
-
-    /**
-     * Handles an entry found in the ClassPath.
-     *
-     * @param entry the ClassPath entry name found.
-     * @param path the path where the ClassPath entry name is found.
-     * @param handlers ClassPath entry handlers have to be invoked when {@link Matcher} pattern matches.
-     * @param classLoader the {@code ClassLoader} used to resolve/load classes
-     * @param errorHandler the {@link ErrorHandler} used to catch any scanning error
-     */
-    private void handleEntry( String entry, String path )
-    {
-        if ( !entry.endsWith( CLASS_EXTENSION ) )
-        {
-            return;
-        }
-
-        entry = entry.substring( 0, entry.lastIndexOf( '.' ) ).replace( '/', '.' );
-        try
-        {
-            Class<?> clazz = classLoader.loadClass( entry );
-
-            for ( ClassPathHandler classPathHandler : handlers )
+            catch ( Exception e )
             {
-                classPathHandler.doHandle( path, clazz );
+                throw new RuntimeException( e );
             }
         }
-        catch ( Throwable t )
-        {
-            errorHandler.onClassNotFound( entry, t );
-        }
+        executor.shutdown();
     }
 
 }

Added: commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java?rev=1204251&view=auto
==============================================================================
--- commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java (added)
+++ commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java Sun Nov 20 20:53:28 2011
@@ -0,0 +1,143 @@
+package org.apache.commons.meiyo.classpath;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static java.util.regex.Pattern.compile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Pattern;
+
+final class PathAnalyzer
+    implements Runnable
+{
+
+    private static final Pattern JAR_FILE = compile( ".+\\.(jar|zip)", Pattern.CASE_INSENSITIVE );
+
+    private static final String CLASS_EXTENSION = ".class";
+
+    private final String path;
+
+    private final Collection<ClassPathHandler> handlers;
+
+    private final ClassLoader classLoader;
+
+    private final ErrorHandler errorHandler;
+
+    PathAnalyzer( String path, Collection<ClassPathHandler> handlers, ClassLoader classLoader, ErrorHandler errorHandler )
+    {
+        this.path = path;
+        this.handlers = handlers;
+        this.classLoader = classLoader;
+        this.errorHandler = errorHandler;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void run()
+    {
+        File file = new File( path );
+        if ( JAR_FILE.matcher( path ).matches() )
+        {
+            try
+            {
+                JarFile jarFile = new JarFile( path );
+                Enumeration<JarEntry> enumeration = jarFile.entries();
+                while ( enumeration.hasMoreElements() )
+                {
+                    JarEntry entry = enumeration.nextElement();
+                    if ( !entry.isDirectory() )
+                    {
+                        handleEntry( entry.getName(), path );
+                    }
+                }
+            }
+            catch ( IOException e )
+            {
+                errorHandler.onJARReadingError( file, e );
+            }
+        }
+        else
+        {
+            traverse( file, path );
+        }
+        // else ignore it
+    }
+
+    /**
+     * Traverses recursively a directory and handle children with the input handlers.
+     *
+     * @param file the directory has to be traversed
+     * @param path the path where the input directory has been found
+     */
+    private void traverse( final File file, final String path )
+    {
+        if ( file.isDirectory() )
+        {
+
+            for ( File child : file.listFiles() )
+            {
+                traverse( child, path );
+            }
+
+            return;
+        }
+
+        handleEntry( file.getAbsolutePath().substring( path.length() + 1 ), path );
+    }
+
+    /**
+     * Handles an entry found in the ClassPath.
+     *
+     * @param entry the ClassPath entry name found.
+     * @param path the path where the ClassPath entry name is found.
+     * @param handlers ClassPath entry handlers have to be invoked when {@link Matcher} pattern matches.
+     * @param classLoader the {@code ClassLoader} used to resolve/load classes
+     * @param errorHandler the {@link ErrorHandler} used to catch any scanning error
+     */
+    private void handleEntry( String entry, String path )
+    {
+        if ( !entry.endsWith( CLASS_EXTENSION ) )
+        {
+            return;
+        }
+
+        entry = entry.substring( 0, entry.lastIndexOf( '.' ) ).replace( '/', '.' );
+        try
+        {
+            Class<?> clazz = classLoader.loadClass( entry );
+
+            for ( ClassPathHandler classPathHandler : handlers )
+            {
+                classPathHandler.doHandle( path, clazz );
+            }
+        }
+        catch ( Throwable t )
+        {
+            errorHandler.onClassNotFound( entry, t );
+        }
+    }
+
+}

Propchange: commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath/PathAnalyzer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain