public class ResolverUtil
extends java.lang.Object
ResolverUtil is used to locate classes that are available in the/a class path and meet arbitrary conditions. The two
most common conditions are that a class implements/extends another class, or that is it annotated with a specific
annotation. However, through the use of the ResolverUtil.Test
class it is possible to search using arbitrary conditions.
A ClassLoader is used to locate all locations (directories and jar files) in the class path that contain classes
within certain packages, and then to load those classes and check them. By default the ClassLoader returned by
Thread.currentThread().getContextClassLoader()
is used, but this can be overridden by calling
setClassLoader(ClassLoader)
prior to invoking any of the find()
methods.
General searches are initiated by calling the find(ResolverUtil.Test, String...)
method and supplying a
package name and a Test instance. This will cause the named package and all sub-packages to be scanned for
classes that meet the test. There are also utility methods for the common use cases of scanning multiple packages for
extensions of particular classes, or classes annotated with a specific annotation.
The standard usage pattern for the ResolverUtil class is as follows:
ResolverUtil resolver = new ResolverUtil(); resolver.findInPackage(new CustomTest(), pkg1); resolver.find(new CustomTest(), pkg1); resolver.find(new CustomTest(), pkg1, pkg2); Set<Class<?>> beans = resolver.getClasses();
This class was copied and modified from Stripes - http://stripes.mc4j.org/confluence/display/stripes/Home
Modifier and Type | Class and Description |
---|---|
static interface |
ResolverUtil.Test
A simple interface that specifies how to test classes to determine if they are to be included in the results
produced by the ResolverUtil.
|
Modifier and Type | Field and Description |
---|---|
private static java.lang.String |
BUNDLE_RESOURCE |
private java.lang.ClassLoader |
classloader
The ClassLoader to use when looking for classes.
|
private java.util.Set<java.lang.Class<?>> |
classMatches
The set of matches being accumulated.
|
private static java.lang.String |
JAR |
private static Logger |
LOGGER
An instance of Log to use for logging in this class.
|
private java.util.Set<java.net.URI> |
resourceMatches
The set of matches being accumulated.
|
private static java.lang.String |
VFS |
private static java.lang.String |
VFSZIP |
Constructor and Description |
---|
ResolverUtil() |
Modifier and Type | Method and Description |
---|---|
protected void |
addIfMatching(ResolverUtil.Test test,
java.lang.String fqn)
Add the class designated by the fully qualified class name provided to the set of resolved classes if and only if
it is approved by the Test supplied.
|
private void |
close(java.util.jar.JarInputStream jarStream,
java.lang.Object source) |
(package private) java.lang.String |
extractPath(java.net.URL url) |
void |
find(ResolverUtil.Test test,
java.lang.String... packageNames)
Attempts to discover classes that pass the test.
|
void |
findInPackage(ResolverUtil.Test test,
java.lang.String packageName)
Scans for classes starting at the package provided and descending into subpackages.
|
java.util.Set<java.lang.Class<?>> |
getClasses()
Provides access to the classes discovered so far.
|
java.lang.ClassLoader |
getClassLoader()
Returns the ClassLoader that will be used for scanning for classes.
|
java.util.Set<java.net.URI> |
getResources()
Returns the matching resources.
|
private boolean |
isTestApplicable(ResolverUtil.Test test,
java.lang.String path) |
private void |
loadImplementationsInBundle(ResolverUtil.Test test,
java.lang.String packageName) |
private void |
loadImplementationsInDirectory(ResolverUtil.Test test,
java.lang.String parent,
java.io.File location)
Finds matches in a physical directory on a file system.
|
private void |
loadImplementationsInJar(ResolverUtil.Test test,
java.lang.String parent,
java.io.File jarFile)
Finds matching classes within a jar files that contains a folder structure matching the package structure.
|
private void |
loadImplementationsInJar(ResolverUtil.Test test,
java.lang.String parent,
java.lang.String path,
java.util.jar.JarInputStream stream)
Finds matching classes within a jar files that contains a folder structure matching the package structure.
|
private void |
loadImplementationsInJar(ResolverUtil.Test test,
java.lang.String parent,
java.net.URL url)
Finds matching classes within a jar files that contains a folder structure matching the package structure.
|
void |
setClassLoader(java.lang.ClassLoader aClassloader)
Sets an explicit ClassLoader that should be used when scanning for classes.
|
private static final Logger LOGGER
private static final java.lang.String VFSZIP
private static final java.lang.String VFS
private static final java.lang.String JAR
private static final java.lang.String BUNDLE_RESOURCE
private final java.util.Set<java.lang.Class<?>> classMatches
private final java.util.Set<java.net.URI> resourceMatches
private java.lang.ClassLoader classloader
public java.util.Set<java.lang.Class<?>> getClasses()
find()
methods, this set will be empty.public java.util.Set<java.net.URI> getResources()
public java.lang.ClassLoader getClassLoader()
public void setClassLoader(java.lang.ClassLoader aClassloader)
aClassloader
- a ClassLoader to use when scanning for classespublic void find(ResolverUtil.Test test, java.lang.String... packageNames)
getClasses()
.test
- the test to determine matching classespackageNames
- one or more package names to scan (including subpackages) for classespublic void findInPackage(ResolverUtil.Test test, java.lang.String packageName)
getClasses()
.test
- an instance of ResolverUtil.Test
that will be used to filter classespackageName
- the name of the package from which to start scanning for classes, e.g. net.sourceforge.stripes
java.lang.String extractPath(java.net.URL url) throws java.io.UnsupportedEncodingException, java.net.URISyntaxException
java.io.UnsupportedEncodingException
java.net.URISyntaxException
private void loadImplementationsInBundle(ResolverUtil.Test test, java.lang.String packageName)
private void loadImplementationsInDirectory(ResolverUtil.Test test, java.lang.String parent, java.io.File location)
test
- a Test used to filter the classes that are discoveredparent
- the package name up to this directory in the package hierarchy. E.g. if /classes is in the classpath and
we wish to examine files in /classes/org/apache then the values of parent would be
org/apachelocation
- a File object representing a directoryprivate boolean isTestApplicable(ResolverUtil.Test test, java.lang.String path)
private void loadImplementationsInJar(ResolverUtil.Test test, java.lang.String parent, java.net.URL url)
test
- a Test used to filter the classes that are discoveredparent
- the parent package under which classes must be in order to be consideredurl
- the url that identifies the jar containing the resource.private void loadImplementationsInJar(ResolverUtil.Test test, java.lang.String parent, java.io.File jarFile)
test
- a Test used to filter the classes that are discoveredparent
- the parent package under which classes must be in order to be consideredjarFile
- the jar file to be examined for classesprivate void close(java.util.jar.JarInputStream jarStream, java.lang.Object source)
jarStream
- source
- private void loadImplementationsInJar(ResolverUtil.Test test, java.lang.String parent, java.lang.String path, java.util.jar.JarInputStream stream)
test
- a Test used to filter the classes that are discoveredparent
- the parent package under which classes must be in order to be consideredstream
- The jar InputStreamprotected void addIfMatching(ResolverUtil.Test test, java.lang.String fqn)
test
- the test used to determine if the class matchesfqn
- the fully qualified name of a class