You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2016/11/28 16:07:54 UTC
[09/14] zest-java git commit: classscanner: prever Streams over
Iterables
classscanner: prever Streams over Iterables
Project: http://git-wip-us.apache.org/repos/asf/zest-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-java/commit/3acd801d
Tree: http://git-wip-us.apache.org/repos/asf/zest-java/tree/3acd801d
Diff: http://git-wip-us.apache.org/repos/asf/zest-java/diff/3acd801d
Branch: refs/heads/develop
Commit: 3acd801d4a51ca16a0db4b91531842db81261633
Parents: 611ef1b
Author: Paul Merlin <pa...@apache.org>
Authored: Mon Nov 28 11:12:55 2016 +0100
Committer: Paul Merlin <pa...@apache.org>
Committed: Mon Nov 28 11:28:41 2016 +0100
----------------------------------------------------------------------
.../org/apache/zest/bootstrap/ClassScanner.java | 160 +++++++------------
.../apache/zest/bootstrap/ClassScannerTest.java | 14 +-
.../builder/ApplicationBuilderTest.java | 12 +-
.../runtime/query/IterableQuerySourceTest.java | 8 +-
.../library/rest/common/ValueAssembler.java | 12 +-
.../server/assembler/RestServerAssembler.java | 32 ++--
6 files changed, 98 insertions(+), 140 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zest-java/blob/3acd801d/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ClassScanner.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ClassScanner.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ClassScanner.java
index 7b8cd6b..c792048 100644
--- a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ClassScanner.java
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ClassScanner.java
@@ -25,47 +25,46 @@ import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
+import java.util.Collections;
+import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
-import org.apache.zest.functional.Iterables;
-
-import static org.apache.zest.functional.Iterables.filter;
-import static org.apache.zest.functional.Iterables.flatten;
-import static org.apache.zest.functional.Iterables.flattenIterables;
-import static org.apache.zest.functional.Iterables.iterable;
-import static org.apache.zest.functional.Iterables.map;
+import java.util.stream.Stream;
/**
* Scan classpath for classes that matches given criteria. Useful for automated assemblies with lots of similar classes.
*/
public class ClassScanner
{
+ private static final ValidClass VALID_CLASS_PREDICATE = new ValidClass();
+
/**
* Get all classes from the same package of the given class, and recursively in all subpackages.
* <p>
* This only works if the seed class is loaded from a file: URL. Jar files are possible as well. Abstract classes
- * are not included in the results. For further filtering use e.g. Iterables.filter.
+ * are not included in the results. For further filtering use e.g. Stream.filter.
* </p>
* @param seedClass starting point for classpath scanning
*
- * @return iterable of all concrete classes in the same package as the seedclass, and also all classes in subpackages.
+ * @return Stream of all concrete classes in the same package as the seedclass, and also all classes in subpackages.
*/
- public static Iterable<Class<?>> findClasses( final Class<?> seedClass )
+ public static Stream<? extends Class<?>> findClasses( final Class<?> seedClass )
{
CodeSource codeSource = seedClass.getProtectionDomain().getCodeSource();
if( codeSource == null )
{
- return Iterables.empty();
+ return Stream.of();
}
URL location = codeSource.getLocation();
if( !location.getProtocol().equals( "file" ) )
{
- throw new IllegalArgumentException( "Can only enumerate classes from file system locations. URL is:" + location );
+ throw new IllegalArgumentException(
+ "Can only enumerate classes from file system locations. URL is:" + location );
}
final File file;
@@ -75,7 +74,8 @@ public class ClassScanner
}
catch( URISyntaxException e )
{
- throw new IllegalArgumentException( "The file location of codebase is invalid. Can not convert to URI. URL is:" + location );
+ throw new IllegalArgumentException(
+ "The file location of codebase is invalid. Can not convert to URI. URL is:" + location );
}
if( file.getName().endsWith( ".jar" ) )
@@ -85,38 +85,27 @@ public class ClassScanner
final String packageName = seedClass.getPackage().getName().replace( '.', '/' );
JarFile jarFile = new JarFile( file );
- Iterable<JarEntry> entries = Iterables.iterable( jarFile.entries() );
+ List<JarEntry> entries = Collections.list( jarFile.entries() );
try
{
- return Iterables.toList( filter( new ValidClass(),
- map( new Function<JarEntry, Class<?>>()
- {
- @Override
- public Class apply( JarEntry jarEntry )
- {
- String name = jarEntry.getName();
- name = name.substring( 0, name.length() - 6 );
- name = name.replace( '/', '.' );
- try
- {
- return seedClass.getClassLoader().loadClass( name );
- }
- catch( ClassNotFoundException e )
- {
- return null;
- }
- }
- }
- , filter( new Predicate<JarEntry>()
- {
- @Override
- public boolean test( JarEntry jarEntry )
- {
- return jarEntry.getName()
- .startsWith( packageName ) && jarEntry.getName()
- .endsWith( ".class" );
- }
- }, entries ) ) ) );
+ return entries.stream()
+ .filter( jarEntry -> jarEntry.getName().startsWith( packageName )
+ && jarEntry.getName().endsWith( ".class" ) )
+ .map( jarEntry ->
+ {
+ String name = jarEntry.getName();
+ name = name.substring( 0, name.length() - 6 );
+ name = name.replace( '/', '.' );
+ try
+ {
+ return seedClass.getClassLoader().loadClass( name );
+ }
+ catch( ClassNotFoundException e )
+ {
+ return null;
+ }
+ } )
+ .filter( VALID_CLASS_PREDICATE );
}
finally
{
@@ -131,34 +120,22 @@ public class ClassScanner
else
{
final File path = new File( file, seedClass.getPackage().getName().replace( '.', File.separatorChar ) );
- Iterable<File> files = findFiles( path, new Predicate<File>()
- {
- @Override
- public boolean test( File file )
- {
- return file.getName().endsWith( ".class" );
- }
- } );
-
- return filter( new ValidClass(),
- map( new Function<File, Class<?>>()
- {
- @Override
- public Class<?> apply( File f )
- {
- String fileName = f.getAbsolutePath().substring( file.toString().length() + 1 );
- fileName = fileName.replace( File.separatorChar, '.' )
- .substring( 0, fileName.length() - 6 );
- try
- {
- return seedClass.getClassLoader().loadClass( fileName );
- }
- catch( ClassNotFoundException e )
- {
- return null;
- }
- }
- }, files ) );
+ Stream<File> classFiles = findFiles( path, candidate -> candidate.getName().endsWith( ".class" ) );
+ return classFiles
+ .map( classFile ->
+ {
+ String fileName = classFile.getAbsolutePath().substring( file.toString().length() + 1 );
+ fileName = fileName.replace( File.separatorChar, '.' ).substring( 0, fileName.length() - 6 );
+ try
+ {
+ return seedClass.getClassLoader().loadClass( fileName );
+ }
+ catch( ClassNotFoundException e )
+ {
+ return null;
+ }
+ } )
+ .filter( VALID_CLASS_PREDICATE );
}
}
@@ -175,35 +152,21 @@ public class ClassScanner
public static Predicate<Class<?>> matches( String regex )
{
final Pattern pattern = Pattern.compile( regex );
-
- return new Predicate<Class<?>>()
- {
- @Override
- public boolean test( Class<?> aClass )
- {
- return pattern.matcher( aClass.getName() ).matches();
- }
- };
+ return aClass -> pattern.matcher( aClass.getName() ).matches();
}
- private static Iterable<File> findFiles( File directory, final Predicate<File> filter )
+ private static Stream<File> findFiles( File directory, final Predicate<File> filter )
{
- return flatten( filter( filter, iterable( directory.listFiles() ) ),
- flattenIterables( map( new Function<File, Iterable<File>>()
- {
- @Override
- public Iterable<File> apply( File file )
- {
- return findFiles( file, filter );
- }
- }, filter( new Predicate<File>()
- {
- @Override
- public boolean test( File file )
- {
- return file.isDirectory();
- }
- }, iterable( directory.listFiles() ) ) ) ) );
+ File[] listedFiles = directory.listFiles();
+ if( listedFiles == null )
+ {
+ return Stream.of();
+ }
+ return Stream.concat( Stream.of( listedFiles ).filter( filter ),
+ Stream.of( listedFiles )
+ .filter( File::isDirectory )
+ .map( dir -> findFiles( dir, filter ) )
+ .flatMap( Function.identity() ) );
}
private static class ValidClass
@@ -212,7 +175,8 @@ public class ClassScanner
@Override
public boolean test( Class<?> item )
{
- return ( item.isInterface() || !Modifier.isAbstract( item.getModifiers() ) ) && ( !item.isEnum() && !item.isAnonymousClass() );
+ return ( item.isInterface() || !Modifier.isAbstract( item.getModifiers() ) )
+ && ( !item.isEnum() && !item.isAnonymousClass() );
}
}
}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/3acd801d/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java
index 0a9932b..bb38ff5 100644
--- a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java
+++ b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java
@@ -19,16 +19,14 @@
*/
package org.apache.zest.bootstrap;
+import org.apache.zest.api.activation.ActivationException;
+import org.apache.zest.bootstrap.somepackage.Test2Value;
import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
import org.junit.Assert;
import org.junit.Test;
-import org.apache.zest.api.activation.ActivationException;
-import org.apache.zest.bootstrap.somepackage.Test2Value;
-import org.apache.zest.functional.Iterables;
import static org.apache.zest.bootstrap.ClassScanner.findClasses;
import static org.apache.zest.bootstrap.ClassScanner.matches;
-import static org.apache.zest.functional.Iterables.filter;
/**
* Test and showcase of the ClassScanner assembly utility.
@@ -48,10 +46,8 @@ public class ClassScannerTest
new DefaultUnitOfWorkAssembler().assemble( module );
// Find all classes starting from TestValue, but include only the ones that are named *Value
- for( Class aClass : filter( matches( ".*Value" ), findClasses( TestValue.class ) ) )
- {
- module.values( aClass );
- }
+ findClasses( TestValue.class ).filter( matches( ".*Value" ) )
+ .forEach( module::values );
}
};
@@ -62,6 +58,6 @@ public class ClassScannerTest
@Test
public void testClassScannerJar()
{
- Assert.assertEquals( 185, Iterables.count( findClasses( Test.class ) ) );
+ Assert.assertEquals( 185, findClasses( Test.class ).count() );
}
}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/3acd801d/core/bootstrap/src/test/java/org/apache/zest/bootstrap/builder/ApplicationBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/builder/ApplicationBuilderTest.java b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/builder/ApplicationBuilderTest.java
index fea47d4..a07d92a 100644
--- a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/builder/ApplicationBuilderTest.java
+++ b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/builder/ApplicationBuilderTest.java
@@ -22,8 +22,6 @@ package org.apache.zest.bootstrap.builder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import org.json.JSONException;
-import org.junit.Test;
import org.apache.zest.api.activation.ActivationException;
import org.apache.zest.api.mixin.Mixins;
import org.apache.zest.api.structure.Application;
@@ -31,12 +29,15 @@ import org.apache.zest.api.structure.Module;
import org.apache.zest.bootstrap.Assembler;
import org.apache.zest.bootstrap.AssemblyException;
import org.apache.zest.bootstrap.ModuleAssembly;
+import org.json.JSONException;
+import org.junit.Test;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertThat;
+import static java.util.stream.Collectors.toList;
import static org.apache.zest.bootstrap.ClassScanner.findClasses;
import static org.apache.zest.bootstrap.ClassScanner.matches;
import static org.apache.zest.functional.Iterables.filter;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
public class ApplicationBuilderTest
{
@@ -48,7 +49,8 @@ public class ApplicationBuilderTest
builder.withLayer( "layer1" ).using( "layer2" ).using( "layer3" );
builder.withLayer( "layer2" );
builder.withLayer( "layer3" ).withModule( "test module" ).
- withAssemblers( filter( matches( ".*ServiceAssembler" ), findClasses( getClass() ) ) );
+ withAssemblers( filter( matches( ".*ServiceAssembler" ),
+ findClasses( getClass() ).collect( toList() ) ) );
Application application = builder.newApplication();
Module module = application.findModule( "layer3", "test module" );
TestService service = module.findService( TestService.class ).get();
http://git-wip-us.apache.org/repos/asf/zest-java/blob/3acd801d/core/runtime/src/test/java/org/apache/zest/runtime/query/IterableQuerySourceTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/zest/runtime/query/IterableQuerySourceTest.java b/core/runtime/src/test/java/org/apache/zest/runtime/query/IterableQuerySourceTest.java
index 2b35c48..d36e659 100644
--- a/core/runtime/src/test/java/org/apache/zest/runtime/query/IterableQuerySourceTest.java
+++ b/core/runtime/src/test/java/org/apache/zest/runtime/query/IterableQuerySourceTest.java
@@ -81,15 +81,11 @@ public class IterableQuerySourceTest
{
SingletonAssembler assembler = new SingletonAssembler()
{
+ @Override
public void assemble( ModuleAssembly module )
throws AssemblyException
{
- Iterable<Class<?>> entities = ClassScanner.findClasses( DomainEntity.class );
-
- for( Class entity : entities )
- {
- module.entities( entity );
- }
+ ClassScanner.findClasses( DomainEntity.class ).forEach( module::entities );
module.values( ContactsValue.class, ContactValue.class );
new EntityTestAssembler().assemble( module );
http://git-wip-us.apache.org/repos/asf/zest-java/blob/3acd801d/libraries/rest-common/src/main/java/org/apache/zest/library/rest/common/ValueAssembler.java
----------------------------------------------------------------------
diff --git a/libraries/rest-common/src/main/java/org/apache/zest/library/rest/common/ValueAssembler.java b/libraries/rest-common/src/main/java/org/apache/zest/library/rest/common/ValueAssembler.java
index f8a301e..8cebeba 100644
--- a/libraries/rest-common/src/main/java/org/apache/zest/library/rest/common/ValueAssembler.java
+++ b/libraries/rest-common/src/main/java/org/apache/zest/library/rest/common/ValueAssembler.java
@@ -26,9 +26,8 @@ import org.apache.zest.bootstrap.Assembler;
import org.apache.zest.bootstrap.AssemblyException;
import org.apache.zest.bootstrap.ModuleAssembly;
-import static org.apache.zest.api.util.Classes.*;
-import static org.apache.zest.bootstrap.ClassScanner.*;
-import static org.apache.zest.functional.Iterables.*;
+import static org.apache.zest.api.util.Classes.isAssignableFrom;
+import static org.apache.zest.bootstrap.ClassScanner.findClasses;
/**
* Assembler for all REST values.
@@ -40,9 +39,8 @@ public class ValueAssembler
public void assemble( ModuleAssembly module )
throws AssemblyException
{
- for( Class<?> aClass : filter( isAssignableFrom( ValueComposite.class ), findClasses( Resource.class ) ))
- {
- module.values( aClass ).visibleIn( Visibility.application );
- }
+ findClasses( Resource.class ).filter( isAssignableFrom( ValueComposite.class ) )
+ .forEach( resourceType -> module.values( resourceType )
+ .visibleIn( Visibility.application ) );
}
}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/3acd801d/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/assembler/RestServerAssembler.java
----------------------------------------------------------------------
diff --git a/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/assembler/RestServerAssembler.java b/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/assembler/RestServerAssembler.java
index a9ee8ac..d51c8d5 100644
--- a/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/assembler/RestServerAssembler.java
+++ b/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/assembler/RestServerAssembler.java
@@ -23,6 +23,7 @@ package org.apache.zest.library.rest.server.assembler;
import freemarker.template.Configuration;
import freemarker.template.Version;
import java.lang.reflect.Modifier;
+import java.util.List;
import java.util.Properties;
import java.util.function.Predicate;
import org.apache.velocity.app.VelocityEngine;
@@ -42,11 +43,11 @@ import org.apache.zest.library.rest.server.restlet.responsewriter.DefaultRespons
import org.apache.zest.library.rest.server.spi.ResponseWriter;
import org.restlet.service.MetadataService;
+import static java.util.stream.Collectors.toList;
import static org.apache.zest.api.util.Classes.hasModifier;
import static org.apache.zest.api.util.Classes.isAssignableFrom;
import static org.apache.zest.bootstrap.ImportedServiceDeclaration.INSTANCE;
import static org.apache.zest.bootstrap.ImportedServiceDeclaration.NEW_OBJECT;
-import static org.apache.zest.functional.Iterables.filter;
/**
* JAVADOC
@@ -66,7 +67,7 @@ public class RestServerAssembler
VelocityEngine velocity = new VelocityEngine( props );
module.importedServices( VelocityEngine.class )
- .importedBy( INSTANCE ).setMetaInfo( velocity );
+ .importedBy( INSTANCE ).setMetaInfo( velocity );
}
catch( Exception e )
{
@@ -83,28 +84,29 @@ public class RestServerAssembler
module.importedServices( MetadataService.class );
module.importedServices( ResponseWriterDelegator.class )
- .identifiedBy( "responsewriterdelegator" )
- .importedBy( NEW_OBJECT )
- .visibleIn( Visibility.layer );
+ .identifiedBy( "responsewriterdelegator" )
+ .importedBy( NEW_OBJECT )
+ .visibleIn( Visibility.layer );
module.objects( ResponseWriterDelegator.class );
module.importedServices( RequestReaderDelegator.class )
- .identifiedBy( "requestreaderdelegator" )
- .importedBy( NEW_OBJECT )
- .visibleIn( Visibility.layer );
+ .identifiedBy( "requestreaderdelegator" )
+ .importedBy( NEW_OBJECT )
+ .visibleIn( Visibility.layer );
module.objects( RequestReaderDelegator.class );
- module.importedServices( InteractionConstraintsService.class ).
- importedBy( NewObjectImporter.class ).
- visibleIn( Visibility.application );
+ module.importedServices( InteractionConstraintsService.class )
+ .importedBy( NewObjectImporter.class )
+ .visibleIn( Visibility.application );
module.objects( InteractionConstraintsService.class );
// Standard response writers
- Iterable<Class<?>> writers = ClassScanner.findClasses( DefaultResponseWriter.class );
- Predicate<Class<?>> responseWriterClass = isAssignableFrom( ResponseWriter.class );
+ Predicate<Class<?>> isResponseWriterClass = isAssignableFrom( ResponseWriter.class );
Predicate<Class<?>> isNotAnAbstract = hasModifier( Modifier.ABSTRACT ).negate();
- Iterable<Class<?>> candidates = filter( isNotAnAbstract.and( responseWriterClass ), writers );
- for( Class<?> responseWriter : candidates )
+ List<? extends Class<?>> responseWriters = ClassScanner.findClasses( DefaultResponseWriter.class )
+ .filter( isNotAnAbstract.and( isResponseWriterClass ) )
+ .collect( toList() );
+ for( Class<?> responseWriter : responseWriters )
{
module.objects( responseWriter );
}