ClassFinder searches the classpath of the specified ClassLoaderInterface for
packages, classes, constructors, methods, or fields with specific annotations.
For security reasons ASM is used to find the annotations. Classes are not
loaded unless they match the requirements of a called findAnnotated* method.
Once loaded, these classes are cached.
The getClassesNotLoaded() method can be used immediately after any find*
method to get a list of classes which matched the find requirements (i.e.
contained the annotation), but were unable to be loaded.
| Constructor: |
public ClassFinder(ClassLoaderInterface classLoader) throws Exception {
this(classLoader, true);
}
Creates a ClassFinder that will search the urls in the specified ClassLoaderInterface
excluding the urls in the ClassLoaderInterface's parent.
To include the parent ClassLoaderInterface, use:
new ClassFinder(ClassLoaderInterface, false);
To exclude the parent's parent, use:
new ClassFinder(ClassLoaderInterface, ClassLoaderInterface.getParent().getParent()); Parameters:
classLoader - source of classes to scan
Throws:
Exception - if something goes wrong
|
public ClassFinder(Class classes) {
this(Arrays.asList(classes));
}
|
public ClassFinder(List<Class> classes) {
this.classLoaderInterface = null;
List< Info > infos = new ArrayList< Info >();
List< Package > packages = new ArrayList< Package >();
for (Class clazz : classes) {
Package aPackage = clazz.getPackage();
if (aPackage != null && !packages.contains(aPackage)){
infos.add(new PackageInfo(aPackage));
packages.add(aPackage);
}
ClassInfo classInfo = new ClassInfo(clazz);
infos.add(classInfo);
classInfos.put(classInfo.getName(), classInfo);
for (Method method : clazz.getDeclaredMethods()) {
infos.add(new MethodInfo(classInfo, method));
}
for (Constructor constructor : clazz.getConstructors()) {
infos.add(new MethodInfo(classInfo, constructor));
}
for (Field field : clazz.getDeclaredFields()) {
infos.add(new FieldInfo(classInfo, field));
}
}
for (Info info : infos) {
for (AnnotationInfo annotation : info.getAnnotations()) {
List< Info > annotationInfos = getAnnotationInfos(annotation.getName());
annotationInfos.add(info);
}
}
}
|
public ClassFinder(ClassLoaderInterface classLoader,
boolean excludeParent) throws Exception {
this(classLoader, getUrls(classLoader, excludeParent));
}
Creates a ClassFinder that will search the urls in the specified ClassLoaderInterface. Parameters:
classLoader - source of classes to scan
excludeParent - Allegedly excludes classes from parent ClassLoaderInterface, whatever that might mean
Throws:
Exception - if something goes wrong.
|
public ClassFinder(ClassLoaderInterface classLoader,
ClassLoaderInterface exclude) throws Exception {
this(classLoader, getUrls(classLoader, exclude));
}
Creates a ClassFinder that will search the urls in the specified classloader excluding
the urls in the 'exclude' ClassLoaderInterface. Parameters:
classLoader - source of classes to scan
exclude - source of classes to exclude from scanning
Throws:
Exception - if something goes wrong
|
public ClassFinder(ClassLoaderInterface classLoader,
URL url) {
this(classLoader, Arrays.asList(url));
}
|
public ClassFinder(ClassLoaderInterface classLoader,
String dirNames) {
this(classLoader, getURLs(classLoader, dirNames));
}
|
public ClassFinder(ClassLoaderInterface classLoaderInterface,
Collection<URL> urls) {
this(classLoaderInterface, urls, false);
}
|
public ClassFinder(ClassLoaderInterface classLoaderInterface,
Collection<URL> urls,
boolean extractBaseInterfaces) {
this(classLoaderInterface, urls, extractBaseInterfaces, new HashSet(){
{
add("jar");
}
});
}
|
public ClassFinder(ClassLoaderInterface classLoaderInterface,
Collection<URL> urls,
boolean extractBaseInterfaces,
Set<String> protocols) {
this.classLoaderInterface = classLoaderInterface;
this.extractBaseInterfaces = extractBaseInterfaces;
List< String > classNames = new ArrayList< String >();
for (URL location : urls) {
try {
if (protocols.contains(location.getProtocol())) {
classNames.addAll(jar(location));
} else if ("file".equals(location.getProtocol())) {
try {
// See if it's actually a jar
URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/");
JarURLConnection juc = (JarURLConnection) jarUrl.openConnection();
juc.getJarFile();
classNames.addAll(jar(jarUrl));
} catch (IOException e) {
classNames.addAll(file(location));
}
}
} catch (Exception e) {
if (LOG.isErrorEnabled())
LOG.error("Unable to read URL [#0]", e, location.toExternalForm());
}
}
for (String className : classNames) {
try {
readClassDef(className);
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Unable to read class [#0]", e, className);
}
}
}
|
| Method from com.opensymphony.xwork2.util.finder.ClassFinder Detail: |
public List<Class> findAnnotatedClasses(Class<Annotation> annotation) {
classesNotLoaded.clear();
List< Class > classes = new ArrayList< Class >();
List< Info > infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof ClassInfo) {
ClassInfo classInfo = (ClassInfo) info;
try {
Class clazz = classInfo.get();
// double check via proper reflection
if (clazz.isAnnotationPresent(annotation)) {
classes.add(clazz);
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return classes;
}
|
public List<Constructor> findAnnotatedConstructors(Class<Annotation> annotation) {
classesNotLoaded.clear();
List< ClassInfo > seen = new ArrayList< ClassInfo >();
List< Constructor > constructors = new ArrayList< Constructor >();
List< Info > infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof MethodInfo && "< init >".equals(info.getName())) {
MethodInfo methodInfo = (MethodInfo) info;
ClassInfo classInfo = methodInfo.getDeclaringClass();
if (seen.contains(classInfo)) continue;
seen.add(classInfo);
try {
Class clazz = classInfo.get();
for (Constructor constructor : clazz.getConstructors()) {
if (constructor.isAnnotationPresent(annotation)) {
constructors.add(constructor);
}
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return constructors;
}
|
public List<Field> findAnnotatedFields(Class<Annotation> annotation) {
classesNotLoaded.clear();
List< ClassInfo > seen = new ArrayList< ClassInfo >();
List< Field > fields = new ArrayList< Field >();
List< Info > infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof FieldInfo) {
FieldInfo fieldInfo = (FieldInfo) info;
ClassInfo classInfo = fieldInfo.getDeclaringClass();
if (seen.contains(classInfo)) continue;
seen.add(classInfo);
try {
Class clazz = classInfo.get();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(annotation)) {
fields.add(field);
}
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return fields;
}
|
public List<Method> findAnnotatedMethods(Class<Annotation> annotation) {
classesNotLoaded.clear();
List< ClassInfo > seen = new ArrayList< ClassInfo >();
List< Method > methods = new ArrayList< Method >();
List< Info > infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof MethodInfo && !"< init >".equals(info.getName())) {
MethodInfo methodInfo = (MethodInfo) info;
ClassInfo classInfo = methodInfo.getDeclaringClass();
if (seen.contains(classInfo)) continue;
seen.add(classInfo);
try {
Class clazz = classInfo.get();
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(annotation)) {
methods.add(method);
}
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return methods;
}
|
public List<Package> findAnnotatedPackages(Class<Annotation> annotation) {
classesNotLoaded.clear();
List< Package > packages = new ArrayList< Package >();
List< Info > infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof PackageInfo) {
PackageInfo packageInfo = (PackageInfo) info;
try {
Package pkg = packageInfo.get();
// double check via proper reflection
if (pkg.isAnnotationPresent(annotation)) {
packages.add(pkg);
}
} catch (ClassNotFoundException e) {
classesNotLoaded.add(packageInfo.getName());
}
}
}
return packages;
}
|
public List<Class> findClasses() {
classesNotLoaded.clear();
List< Class > classes = new ArrayList< Class >();
for (ClassInfo classInfo : classInfos.values()) {
try {
classes.add(classInfo.get());
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
return classes;
}
|
public List<Class> findClasses(Test<ClassInfo> test) {
classesNotLoaded.clear();
List< Class > classes = new ArrayList< Class >();
for (ClassInfo classInfo : classInfos.values()) {
try {
if (test.test(classInfo)) {
classes.add(classInfo.get());
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
return classes;
}
|
public List<Class> findClassesInPackage(String packageName,
boolean recursive) {
classesNotLoaded.clear();
List< Class > classes = new ArrayList< Class >();
for (ClassInfo classInfo : classInfos.values()) {
try {
if (recursive && classInfo.getPackageName().startsWith(packageName)){
classes.add(classInfo.get());
} else if (classInfo.getPackageName().equals(packageName)){
classes.add(classInfo.get());
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
return classes;
}
|
public List<String> getClassesNotLoaded() {
return Collections.unmodifiableList(classesNotLoaded);
}
Returns a list of classes that could not be loaded in last invoked findAnnotated* method.
The list will only contain entries of classes whose byte code matched the requirements
of last invoked find* method, but were unable to be loaded and included in the results.
The list returned is unmodifiable. Once obtained, the returned list will be a live view of the
results from the last findAnnotated* method call.
This method is not thread safe. |
public boolean isAnnotationPresent(Class<Annotation> annotation) {
List< Info > infos = annotated.get(annotation.getName());
return infos != null && !infos.isEmpty();
}
|