You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by se...@apache.org on 2009/09/16 02:38:43 UTC
svn commit: r815579 -
/jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java
Author: sebb
Date: Wed Sep 16 00:38:43 2009
New Revision: 815579
URL: http://svn.apache.org/viewvc?rev=815579&view=rev
Log:
Add findAnnotatedClasses method (part of Bugzilla 47803)
Modified:
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java
Modified: jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java?rev=815579&r1=815578&r2=815579&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java (original)
+++ jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/reflect/ClassFinder.java Wed Sep 16 00:38:43 2009
@@ -21,6 +21,8 @@
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -108,6 +110,40 @@
return false;
}
}
+
+ private static class AnnoFilterTreeSet extends TreeSet<String>{
+ private final boolean inner; // are inner classes OK?
+
+ private final Class<? extends Annotation>[] annotations; // annotation classes to check
+ private final transient ClassLoader contextClassLoader
+ = Thread.currentThread().getContextClassLoader(); // Potentially expensive; do it once
+ AnnoFilterTreeSet(Class<? extends Annotation> []annotations, boolean inner){
+ super();
+ this.annotations = annotations;
+ this.inner=inner;
+ }
+ /**
+ * Override the superclass so we only add classnames that
+ * meet the criteria.
+ *
+ * @param s - classname (must be a String)
+ * @return true if it is a new entry
+ *
+ * @see java.util.TreeSet#add(java.lang.Object)
+ */
+ @Override
+ public boolean add(String s){
+ if (contains(s)) {
+ return false;// No need to check it again
+ }
+ if ((s.indexOf("$") == -1) || inner) { // $NON-NLS-1$
+ if (hasAnnotationOnMethod(annotations,s, contextClassLoader)) {
+ return super.add(s);
+ }
+ }
+ return false;
+ }
+ }
/**
* Convenience method for
@@ -173,10 +209,42 @@
final Class<?>[] superClasses, final boolean innerClasses,
String contains, String notContains)
throws IOException {
-
+ return findClassesThatExtend(strPathsOrJars, superClasses, innerClasses, contains, notContains, false);
+ }
+
+ /**
+ * Find classes in the provided path(s)/jar(s) that extend the class(es).
+ * @param strPathsOrJars - pathnames or jarfiles to search for classes
+ * @param annotations - required annotations
+ * @param innerClasses - should we include inner classes?
+ *
+ * @return List containing discovered classes
+ */
+ public static List<String> findAnnotatedClasses(String[] strPathsOrJars,
+ final Class<? extends Annotation>[] annotations, final boolean innerClasses)
+ throws IOException {
+ return findClassesThatExtend(strPathsOrJars, annotations, innerClasses, null, null, true);
+ }
+
+ /**
+ * Find classes in the provided path(s)/jar(s) that extend the class(es).
+ * @param strPathsOrJars - pathnames or jarfiles to search for classes
+ * @param classNames - required parent class(es) or annotations
+ * @param innerClasses - should we include inner classes?
+ * @param contains - classname should contain this string
+ * @param notContains - classname should not contain this string
+ * @param annotations - true if classnames are annotations
+ *
+ * @return List containing discovered classes
+ */
+ @SuppressWarnings("unchecked")
+ public static List<String> findClassesThatExtend(String[] strPathsOrJars,
+ final Class<?>[] classNames, final boolean innerClasses,
+ String contains, String notContains, boolean annotations)
+ throws IOException {
if (log.isDebugEnabled()) {
- for (int i = 0; i < superClasses.length ; i++){
- log.debug("superclass: "+superClasses[i].getName());
+ for (int i = 0; i < classNames.length ; i++){
+ log.debug("superclass: "+classNames[i].getName());
}
}
@@ -198,7 +266,11 @@
}
}
- Set<String> listClasses = new FilterTreeSet(superClasses, innerClasses, contains, notContains);
+ Set<String> listClasses =
+ annotations ?
+ new AnnoFilterTreeSet((Class<? extends Annotation>[]) classNames, innerClasses)
+ :
+ new FilterTreeSet(classNames, innerClasses, contains, notContains);
// first get all the classes
findClassesInPaths(listPaths, listClasses);
if (log.isDebugEnabled()) {
@@ -384,11 +456,29 @@
}
}
}
- } catch (Throwable ignored) {
+ } catch (ClassNotFoundException ignored) {
log.debug(ignored.getLocalizedMessage());
}
return false;
}
+
+ private static boolean hasAnnotationOnMethod(Class<? extends Annotation>[] annotations, String classInQuestion,
+ ClassLoader contextClassLoader ){
+ try{
+ Class<?> c = Class.forName(classInQuestion, false, contextClassLoader);
+ for(Method method : c.getMethods()) {
+ for(int i = 0;i<annotations.length;i++) {
+ Class<? extends Annotation> annotation = annotations[i];
+ if(method.isAnnotationPresent(annotation)) {
+ return true;
+ }
+ }
+ }
+ } catch (ClassNotFoundException ignored) {
+ log.debug(ignored.getLocalizedMessage());
+ }
+ return false;
+ }
/*
---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org