Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 700849CD0 for ; Sun, 20 Nov 2011 20:53:51 +0000 (UTC) Received: (qmail 28850 invoked by uid 500); 20 Nov 2011 20:53:51 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 28791 invoked by uid 500); 20 Nov 2011 20:53:51 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 28784 invoked by uid 99); 20 Nov 2011 20:53:51 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 20 Nov 2011 20:53:51 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 20 Nov 2011 20:53:49 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 7039823889DA for ; Sun, 20 Nov 2011 20:53:29 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1204251 - in /commons/sandbox/meiyo/trunk/src/main/java/org/apache/commons/meiyo/classpath: ErrorHandlerBuilder.java PathAnalyzer.java Date: Sun, 20 Nov 2011 20:53:29 -0000 To: commits@commons.apache.org From: simonetripodi@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111120205329.7039823889DA@eris.apache.org> 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 handlers; private final ClassLoader classLoader; - private ErrorHandler errorHandler; - ErrorHandlerBuilder( String[] paths, Collection 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> futures = new ArrayList>(); for ( String path : paths ) { - File file = new File( path ); - if ( JAR_FILE.matcher( path ).matches() ) - { - try - { - JarFile jarFile = new JarFile( path ); - Enumeration 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 handlers; + + private final ClassLoader classLoader; + + private final ErrorHandler errorHandler; + + PathAnalyzer( String path, Collection 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 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