You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xbean-scm@geronimo.apache.org by rm...@apache.org on 2013/10/28 10:33:45 UTC
svn commit: r1536292 - in /geronimo/xbean/trunk/xbean-finder/src:
main/java/org/apache/xbean/finder/AnnotationFinder.java
main/java/org/apache/xbean/finder/MultiThreadedAnnotationFinder.java
test/java/org/apache/xbean/finder/ClassFinderDepthTest.java
Author: rmannibucau
Date: Mon Oct 28 09:33:44 2013
New Revision: 1536292
URL: http://svn.apache.org/r1536292
Log:
XBEAN-253 adding MultiThreadedAnnotationFinder
Added:
geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MultiThreadedAnnotationFinder.java
Modified:
geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotationFinder.java
geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/ClassFinderDepthTest.java
Modified: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotationFinder.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotationFinder.java?rev=1536292&r1=1536291&r2=1536292&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotationFinder.java (original)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotationFinder.java Mon Oct 28 09:33:44 2013
@@ -50,6 +50,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -68,11 +69,11 @@ public class AnnotationFinder implements
private final Set<Class<? extends Annotation>> metaroots = new HashSet<Class<? extends Annotation>>();
- private final Map<String, List<Info>> annotated = new HashMap<String, List<Info>>();
+ protected final Map<String, List<Info>> annotated = newAnnotatedMap();
- protected final Map<String, ClassInfo> classInfos = new HashMap<String, ClassInfo>();
- protected final Map<String, ClassInfo> originalInfos = new HashMap<String, ClassInfo>();
- private final List<String> classesNotLoaded = new ArrayList<String>();
+ protected final Map<String, ClassInfo> classInfos = newClassInfoMap();
+ protected final Map<String, ClassInfo> originalInfos = newClassInfoMap();
+ private final List<String> classesNotLoaded = new LinkedList<String>();
private final int ASM_FLAGS = ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES;
private final Archive archive;
private final boolean checkRuntimeAnnotation;
@@ -81,6 +82,7 @@ public class AnnotationFinder implements
this.archive = new SubArchive(classNames);
this.checkRuntimeAnnotation = parent.checkRuntimeAnnotation;
this.metaroots.addAll(parent.metaroots);
+
for (Class<? extends Annotation> metaroot : metaroots) {
final ClassInfo info = parent.classInfos.get(metaroot.getName());
if (info == null) continue;
@@ -92,7 +94,7 @@ public class AnnotationFinder implements
readClassDef(info);
}
- resolveAnnotations(parent, new ArrayList<String>());
+ resolveAnnotations(parent, new LinkedList<String>());
for (ClassInfo classInfo : classInfos.values()) {
if (isMetaRoot(classInfo)) {
try {
@@ -114,6 +116,14 @@ public class AnnotationFinder implements
}
}
+ protected Map<String, List<Info>> newAnnotatedMap() {
+ return new HashMap<String, List<Info>>();
+ }
+
+ protected Map<String, ClassInfo> newClassInfoMap() {
+ return new HashMap<String, ClassInfo>();
+ }
+
/**
*
* @param archive
@@ -217,7 +227,7 @@ public class AnnotationFinder implements
public AnnotationFinder enableMetaAnnotations() {
// diff new and old lists
- resolveAnnotations(new ArrayList<String>());
+ resolveAnnotations(new LinkedList<String>());
linkMetaAnnotations();
@@ -335,7 +345,7 @@ public class AnnotationFinder implements
return className.equals(simpleName) || className.endsWith("." + simpleName) || className.endsWith("$" + simpleName);
}
- private void linkParent(ClassInfo classInfo) {
+ protected void linkParent(ClassInfo classInfo) {
if (classInfo.superType == null) return;
if (classInfo.superType.equals("java.lang.Object")) return;
@@ -363,13 +373,15 @@ public class AnnotationFinder implements
classInfo.superclassInfo = parentInfo;
}
- if (!parentInfo.subclassInfos.contains(classInfo)) {
- parentInfo.subclassInfos.add(classInfo);
+ synchronized (parentInfo.subclassInfos) {
+ if (!parentInfo.subclassInfos.contains(classInfo)) {
+ parentInfo.subclassInfos.add(classInfo);
+ }
}
}
- private void linkInterfaces(ClassInfo classInfo) {
- final List<ClassInfo> infos = new ArrayList<ClassInfo>();
+ protected void linkInterfaces(ClassInfo classInfo) {
+ final List<ClassInfo> infos = new LinkedList<ClassInfo>();
if (classInfo.clazz != null) {
final Class<?>[] interfaces = classInfo.clazz.getInterfaces();
@@ -388,17 +400,19 @@ public class AnnotationFinder implements
}
}
} else {
- for (String className : classInfo.interfaces) {
- ClassInfo interfaceInfo = classInfos.get(className);
+ synchronized (classInfo.interfaces) {
+ for (String className : classInfo.interfaces) {
+ ClassInfo interfaceInfo = classInfos.get(className);
- if (interfaceInfo == null) {
- readClassDef(className);
- }
+ if (interfaceInfo == null) {
+ readClassDef(className);
+ }
- interfaceInfo = classInfos.get(className);
+ interfaceInfo = classInfos.get(className);
- if (interfaceInfo != null) {
- infos.add(interfaceInfo);
+ if (interfaceInfo != null) {
+ infos.add(interfaceInfo);
+ }
}
}
}
@@ -432,7 +446,7 @@ public class AnnotationFinder implements
public List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
- List<Package> packages = new ArrayList<Package>();
+ List<Package> packages = new LinkedList<Package>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof PackageInfo) {
@@ -453,7 +467,7 @@ public class AnnotationFinder implements
public List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
- List<Class<?>> classes = new ArrayList<Class<?>>();
+ List<Class<?>> classes = new LinkedList<Class<?>>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof ClassInfo) {
@@ -476,7 +490,7 @@ public class AnnotationFinder implements
classesNotLoaded.clear();
Set<Class<?>> classes = findMetaAnnotatedClasses(annotation, new HashSet<Class<?>>());
- List<Annotated<Class<?>>> list = new ArrayList<Annotated<Class<?>>>();
+ List<Annotated<Class<?>>> list = new LinkedList<Annotated<Class<?>>>();
for (Class<?> clazz : classes) {
if (Annotation.class.isAssignableFrom(clazz) && isMetaAnnotation((Class<? extends Annotation>) clazz)) continue;
@@ -554,7 +568,7 @@ public class AnnotationFinder implements
*/
public List<Class<?>> findInheritedAnnotatedClasses(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
- List<Class<?>> classes = new ArrayList<Class<?>>();
+ List<Class<?>> classes = new LinkedList<Class<?>>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
try {
@@ -606,8 +620,8 @@ public class AnnotationFinder implements
public List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
- List<ClassInfo> seen = new ArrayList<ClassInfo>();
- List<Method> methods = new ArrayList<Method>();
+ List<ClassInfo> seen = new LinkedList<ClassInfo>();
+ List<Method> methods = new LinkedList<Method>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof MethodInfo && !info.getName().equals("<init>")) {
@@ -649,7 +663,7 @@ public class AnnotationFinder implements
classesNotLoaded.clear();
final Set<ClassInfo> seen = checkRuntimeAnnotation ? new HashSet<ClassInfo>() : null;
- final List<Parameter<Method>> result = new ArrayList<Parameter<Method>>();
+ final List<Parameter<Method>> result = new LinkedList<Parameter<Method>>();
for (Info info : getAnnotationInfos(annotation.getName())) {
if (!(info instanceof ParameterInfo)) {
continue;
@@ -696,7 +710,7 @@ public class AnnotationFinder implements
Set<Method> methods = findMetaAnnotatedMethods(annotation, new HashSet<Method>(), new HashSet<String>());
- List<Annotated<Method>> targets = new ArrayList<Annotated<Method>>();
+ List<Annotated<Method>> targets = new LinkedList<Annotated<Method>>();
for (Method method : methods) {
targets.add(new MetaAnnotatedMethod(method));
@@ -757,7 +771,7 @@ public class AnnotationFinder implements
Set<Field> fields = findMetaAnnotatedFields(annotation, new HashSet<Field>(), new HashSet<String>());
- List<Annotated<Field>> targets = new ArrayList<Annotated<Field>>();
+ List<Annotated<Field>> targets = new LinkedList<Annotated<Field>>();
for (Field field : fields) {
targets.add(new MetaAnnotatedField(field));
@@ -815,8 +829,8 @@ public class AnnotationFinder implements
public List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
- List<ClassInfo> seen = new ArrayList<ClassInfo>();
- List<Constructor> constructors = new ArrayList<Constructor>();
+ List<ClassInfo> seen = new LinkedList<ClassInfo>();
+ List<Constructor> constructors = new LinkedList<Constructor>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof MethodInfo && info.getName().equals("<init>")) {
@@ -857,7 +871,7 @@ public class AnnotationFinder implements
classesNotLoaded.clear();
final Set<ClassInfo> seen = checkRuntimeAnnotation ? new HashSet<ClassInfo>() : null;
- final List<Parameter<Constructor<?>>> result = new ArrayList<Parameter<Constructor<?>>>();
+ final List<Parameter<Constructor<?>>> result = new LinkedList<Parameter<Constructor<?>>>();
for (Info info : getAnnotationInfos(annotation.getName())) {
if (!(info instanceof ParameterInfo)) {
continue;
@@ -903,8 +917,8 @@ public class AnnotationFinder implements
public List<Field> findAnnotatedFields(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
- List<ClassInfo> seen = new ArrayList<ClassInfo>();
- List<Field> fields = new ArrayList<Field>();
+ List<ClassInfo> seen = new LinkedList<ClassInfo>();
+ List<Field> fields = new LinkedList<Field>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof FieldInfo) {
@@ -943,7 +957,7 @@ public class AnnotationFinder implements
public List<Class<?>> findClassesInPackage(String packageName, boolean recursive) {
classesNotLoaded.clear();
- List<Class<?>> classes = new ArrayList<Class<?>>();
+ List<Class<?>> classes = new LinkedList<Class<?>>();
for (ClassInfo classInfo : classInfos.values()) {
try {
if (recursive && classInfo.getPackageName().startsWith(packageName)) {
@@ -965,7 +979,7 @@ public class AnnotationFinder implements
final ClassInfo classInfo = classInfos.get(clazz.getName());
- List<Class<? extends T>> found = new ArrayList<Class<? extends T>>();
+ List<Class<? extends T>> found = new LinkedList<Class<? extends T>>();
if (classInfo == null) return found;
@@ -991,7 +1005,7 @@ public class AnnotationFinder implements
private <T> List<Class<? extends T>> _findSubclasses(Class<T> clazz) {
if (clazz == null) throw new NullPointerException("class cannot be null");
- List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
+ List<Class<? extends T>> classes = new LinkedList<Class<? extends T>>();
for (ClassInfo classInfo : classInfos.values()) {
@@ -1030,7 +1044,7 @@ public class AnnotationFinder implements
List<ClassInfo> infos = collectImplementations(interfaceName);
// Collect all subclasses of implementations
- List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
+ List<Class<? extends T>> classes = new LinkedList<Class<? extends T>>();
for (ClassInfo info : infos) {
try {
final Class<? extends T> impl = (Class<? extends T>) info.get();
@@ -1052,26 +1066,28 @@ public class AnnotationFinder implements
}
private List<ClassInfo> collectImplementations(String interfaceName) {
- final List<ClassInfo> infos = new ArrayList<ClassInfo>();
+ final List<ClassInfo> infos = new LinkedList<ClassInfo>();
for (ClassInfo classInfo : classInfos.values()) {
- if (classInfo.interfaces.contains(interfaceName)) {
+ synchronized (classInfo.interfaces) {
+ if (classInfo.interfaces.contains(interfaceName)) {
- infos.add(classInfo);
+ infos.add(classInfo);
- try {
+ try {
- final Class clazz = classInfo.get();
+ final Class clazz = classInfo.get();
- if (clazz.isInterface() && !clazz.isAnnotation()) {
+ if (clazz.isInterface() && !clazz.isAnnotation()) {
- infos.addAll(collectImplementations(classInfo.name));
+ infos.addAll(collectImplementations(classInfo.name));
- }
+ }
- } catch (ClassNotFoundException ignore) {
- // we'll deal with this later
+ } catch (ClassNotFoundException ignore) {
+ // we'll deal with this later
+ }
}
}
}
@@ -1113,7 +1129,7 @@ public class AnnotationFinder implements
}
protected void readClassDef(Class clazz) {
- List<Info> infos = new ArrayList<Info>();
+ List<Info> infos = new LinkedList<Info>();
Package aPackage = clazz.getPackage();
if (aPackage != null) {
@@ -1180,7 +1196,7 @@ public class AnnotationFinder implements
}
public class SubArchive implements Archive {
- private List<Entry> classes = new ArrayList<Entry>();
+ private List<Entry> classes = new LinkedList<Entry>();
public SubArchive(String... classes) {
for (String name : classes) {
@@ -1224,7 +1240,7 @@ public class AnnotationFinder implements
}
public class Annotatable {
- private final List<AnnotationInfo> annotations = new ArrayList<AnnotationInfo>();
+ private final List<AnnotationInfo> annotations = new LinkedList<AnnotationInfo>();
public Annotatable(AnnotatedElement element) {
for (Annotation annotation : getAnnotations(element)) {
@@ -1428,7 +1444,7 @@ public class AnnotationFinder implements
private final ClassInfo declaringClass;
private final String descriptor;
private final String name;
- private final List<List<AnnotationInfo>> parameterAnnotations = new ArrayList<List<AnnotationInfo>>();
+ private final List<List<AnnotationInfo>> parameterAnnotations = new LinkedList<List<AnnotationInfo>>();
private final List<ParameterInfo> parameters = new SingleLinkedList<ParameterInfo>();
private Member method;
@@ -1479,7 +1495,7 @@ public class AnnotationFinder implements
public List<AnnotationInfo> getParameterAnnotations(int index) {
if (index >= parameterAnnotations.size()) {
for (int i = parameterAnnotations.size(); i <= index; i++) {
- List<AnnotationInfo> annotationInfos = new ArrayList<AnnotationInfo>();
+ List<AnnotationInfo> annotationInfos = new LinkedList<AnnotationInfo>();
parameterAnnotations.add(i, annotationInfos);
}
}
@@ -1514,7 +1530,7 @@ public class AnnotationFinder implements
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, descriptor);
Class<?> clazz = this.declaringClass.get();
- List<Class> parameterTypes = new ArrayList<Class>();
+ List<Class> parameterTypes = new LinkedList<Class>();
for (Type type : method.getArgumentTypes()) {
String paramType = type.getClassName();
@@ -1551,7 +1567,7 @@ public class AnnotationFinder implements
public class ParameterInfo extends Annotatable implements Info {
private final MethodInfo declaringMethod;
private final int index;
- private final List<AnnotationInfo> annotations = new ArrayList<AnnotationInfo>();
+ private final List<AnnotationInfo> annotations = new LinkedList<AnnotationInfo>();
private Parameter<?> parameter;
public ParameterInfo(MethodInfo parent, int index) {
Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MultiThreadedAnnotationFinder.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MultiThreadedAnnotationFinder.java?rev=1536292&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MultiThreadedAnnotationFinder.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MultiThreadedAnnotationFinder.java Mon Oct 28 09:33:44 2013
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+package org.apache.xbean.finder;
+
+import org.apache.xbean.finder.archive.Archive;
+import org.apache.xbean.finder.util.SingleLinkedList;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MultiThreadedAnnotationFinder extends AnnotationFinder {
+ private ExecutorService executor = null;
+ private CountDownLatch subclassesLatch = null;
+ private CountDownLatch implementationsLatch = null;
+ private final int threads;
+
+ public MultiThreadedAnnotationFinder(final Archive archive, final boolean checkRuntimeAnnotation, final int threads) {
+ super(archive, checkRuntimeAnnotation);
+ this.threads = threads;
+ }
+
+ public MultiThreadedAnnotationFinder(final Archive archive, final int threads) {
+ super(archive);
+ this.threads = threads;
+ }
+
+ @Override
+ public AnnotationFinder enableFindImplementations() {
+ if (implementationsLatch == null) {
+ implementationsLatch = scan(new FindImplementationsFactory());
+ }
+ return this;
+ }
+
+ @Override
+ public AnnotationFinder enableFindSubclasses() {
+ if (subclassesLatch == null) {
+ subclassesLatch = scan(new FindSubclassesFactory());
+ }
+ return this;
+ }
+
+ private ExecutorService executor() {
+ if (executor == null) {
+ executor = Executors.newFixedThreadPool(threads, new DaemonThreadFactory());
+ }
+ return executor;
+ }
+
+ @Override
+ public <T> List<Class<? extends T>> findSubclasses(final Class<T> clazz) {
+ if (subclassesLatch == null) {
+ enableFindSubclasses();
+ }
+ join(subclassesLatch);
+
+ return super.findSubclasses(clazz);
+ }
+
+ @Override
+ public <T> List<Class<? extends T>> findImplementations(final Class<T> clazz) {
+ if (implementationsLatch == null) {
+ enableFindImplementations();
+ }
+ join(implementationsLatch);
+ return super.findImplementations(clazz);
+ }
+
+ private CountDownLatch scan(final ScanTaskFactory factory) {
+ final ClassInfo[] classes = classInfos.values().toArray(new ClassInfo[classInfos.size()]);
+ final ExecutorService es = executor();
+ final CountDownLatch latch = new CountDownLatch(classes.length);
+ for (final ClassInfo classInfo : classes) {
+ es.submit(factory.next(classInfo, latch));
+ }
+ return latch;
+ }
+
+ private void join(final CountDownLatch latch) {
+ try {
+ latch.await(1, TimeUnit.HOURS);
+ } catch (final InterruptedException e) {
+ // no-op
+ }
+ }
+
+ @Override
+ protected Map<String, ClassInfo> newClassInfoMap() {
+ return new ConcurrentHashMap<String, ClassInfo>();
+ }
+
+ @Override
+ protected Map<String, List<Info>> newAnnotatedMap() {
+ return new ConcurrentHashMap<String, List<Info>>();
+ }
+
+ @Override
+ protected List<Info> initAnnotationInfos(String name) {
+ List<Info> infos = annotated.get(name);
+ if (infos == null) {
+ infos = new SingleLinkedList<Info>();
+
+ final List<Info> old = ((ConcurrentMap<String, List<Info>>) annotated).putIfAbsent(name, infos);
+ if (old != null) {
+ infos = old;
+ }
+ }
+ return infos;
+ }
+
+ protected static class DaemonThreadFactory implements ThreadFactory {
+ private final String name = "xbean-finder-" + hashCode();
+ private final ThreadGroup group;
+ private final AtomicInteger ids = new AtomicInteger(0);
+
+ protected DaemonThreadFactory() {
+ final SecurityManager securityManager = System.getSecurityManager();
+ if (securityManager != null) {
+ group = securityManager.getThreadGroup();
+ } else {
+ group = Thread.currentThread().getThreadGroup();
+ }
+ }
+
+ // @Override
+ public Thread newThread(final Runnable runnable) {
+ final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(AnnotationFinder.class.getClassLoader());
+ try {
+ final Thread thread = new Thread(group, runnable, name + " - " + ids.incrementAndGet());
+ if (!thread.isDaemon()) {
+ thread.setDaemon(true);
+ }
+ if (thread.getPriority() != Thread.NORM_PRIORITY) {
+ thread.setPriority(Thread.NORM_PRIORITY);
+ }
+ return thread;
+ } finally {
+ Thread.currentThread().setContextClassLoader(loader);
+ }
+ }
+ }
+
+ protected static abstract class ScanTask implements Runnable {
+ private final ClassInfo info;
+ private final CountDownLatch latch;
+
+ protected ScanTask(final ClassInfo info, final CountDownLatch latch) {
+ this.info = info;
+ this.latch = latch;
+ }
+
+ // @Override
+ public void run() {
+ try {
+ doRun(info);
+ } finally {
+ latch.countDown();
+ }
+ }
+
+ public abstract void doRun(final ClassInfo info);
+ }
+
+ protected static interface ScanTaskFactory {
+ ScanTask next(final ClassInfo info, CountDownLatch latch);
+ }
+
+ protected class FindImplementationsFactory implements ScanTaskFactory {
+ // @Override
+ public ScanTask next(final ClassInfo info, final CountDownLatch latch) {
+ return new FindImplementations(info, latch);
+ }
+ }
+
+ protected class FindSubclassesFactory implements ScanTaskFactory {
+ // @Override
+ public ScanTask next(final ClassInfo info, final CountDownLatch latch) {
+ return new FindSubclasses(info, latch);
+ }
+ }
+
+ protected class FindImplementations extends ScanTask {
+ public FindImplementations(final ClassInfo info, final CountDownLatch latch) {
+ super(info, latch);
+ }
+
+ @Override
+ public void doRun(final ClassInfo info) {
+ linkInterfaces(info);
+ }
+ }
+
+ protected class FindSubclasses extends ScanTask {
+ public FindSubclasses(final ClassInfo info, final CountDownLatch latch) {
+ super(info, latch);
+ }
+
+ @Override
+ public void doRun(final ClassInfo info) {
+ linkParent(info);
+ }
+ }
+}
Modified: geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/ClassFinderDepthTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/ClassFinderDepthTest.java?rev=1536292&r1=1536291&r2=1536292&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/ClassFinderDepthTest.java (original)
+++ geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/ClassFinderDepthTest.java Mon Oct 28 09:33:44 2013
@@ -61,24 +61,36 @@ public class ClassFinderDepthTest extend
}
public void testFindSubclassesIncomplete() throws Exception {
- final AnnotationFinder finder = new AnnotationFinder(new ClassesArchive(Crimson.class, Square.class)).link();
+ for (final AnnotationFinder finder : new AnnotationFinder[] {
+ new AnnotationFinder(new ClassesArchive(Crimson.class, Square.class)).link(),
+ new MultiThreadedAnnotationFinder(new ClassesArchive(Crimson.class, Square.class), maxThreads()).link()
+ }) {
+
+ assertSubclasses(finder, Color.class, Red.class, Crimson.class);
+ assertSubclasses(finder, Red.class, Crimson.class);
+ assertSubclasses(finder, Crimson.class);
- assertSubclasses(finder, Color.class, Red.class, Crimson.class);
- assertSubclasses(finder, Red.class, Crimson.class);
- assertSubclasses(finder, Crimson.class);
-
- assertSubclasses(finder, Shape.class, Square.class);
- assertSubclasses(finder, Square.class);
+ assertSubclasses(finder, Shape.class, Square.class);
+ assertSubclasses(finder, Square.class);
+ }
}
public void testFindImplementations() throws Exception {
- final AnnotationFinder finder = new AnnotationFinder(new ClassesArchive(Crimson.class, Square.class)).link();
+ for (final AnnotationFinder finder : new AnnotationFinder[] {
+ new AnnotationFinder(new ClassesArchive(Crimson.class, Square.class)).link(),
+ new MultiThreadedAnnotationFinder(new ClassesArchive(Crimson.class, Square.class), maxThreads()).link()
+ }) {
+
+ assertImplementations(finder, HSB.class, Color.class, Red.class, Crimson.class);
+ assertImplementations(finder, Hue.class, HSB.class, Color.class, Red.class, Crimson.class);
+ assertImplementations(finder, Saturation.class, HSB.class, Color.class, Red.class, Crimson.class);
+ }
+ }
- assertImplementations(finder, HSB.class, Color.class, Red.class, Crimson.class);
- assertImplementations(finder, Hue.class, HSB.class, Color.class, Red.class, Crimson.class);
- assertImplementations(finder, Saturation.class, HSB.class, Color.class, Red.class, Crimson.class);
+ private static int maxThreads() {
+ return 2 * Runtime.getRuntime().availableProcessors();
}
-
+
private void assertSubclasses(AnnotationFinder finder, Class<?> clazz, Class... subclasses) {
final List<Class<?>> classes = new ArrayList(finder.findSubclasses(clazz));