Class ResolverUtil
- java.lang.Object
-
- org.apache.logging.log4j.core.config.plugins.util.ResolverUtil
-
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 callingsetClassLoader(ClassLoader)
prior to invoking any of thefind()
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
-
-
Nested Class Summary
Nested Classes Modifier and Type Class 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.
-
Field Summary
Fields Modifier and Type Field 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 Summary
Constructors Constructor Description ResolverUtil()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method 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.
-
-
-
Field Detail
-
LOGGER
private static final Logger LOGGER
An instance of Log to use for logging in this class.
-
VFSZIP
private static final java.lang.String VFSZIP
- See Also:
- Constant Field Values
-
VFS
private static final java.lang.String VFS
- See Also:
- Constant Field Values
-
JAR
private static final java.lang.String JAR
- See Also:
- Constant Field Values
-
BUNDLE_RESOURCE
private static final java.lang.String BUNDLE_RESOURCE
- See Also:
- Constant Field Values
-
classMatches
private final java.util.Set<java.lang.Class<?>> classMatches
The set of matches being accumulated.
-
resourceMatches
private final java.util.Set<java.net.URI> resourceMatches
The set of matches being accumulated.
-
classloader
private java.lang.ClassLoader classloader
The ClassLoader to use when looking for classes. If null then the ClassLoader returned by Thread.currentThread().getContextClassLoader() will be used.
-
-
Method Detail
-
getClasses
public java.util.Set<java.lang.Class<?>> getClasses()
Provides access to the classes discovered so far. If no calls have been made to any of thefind()
methods, this set will be empty.- Returns:
- the set of classes that have been discovered.
-
getResources
public java.util.Set<java.net.URI> getResources()
Returns the matching resources.- Returns:
- A Set of URIs that match the criteria.
-
getClassLoader
public java.lang.ClassLoader getClassLoader()
Returns the ClassLoader that will be used for scanning for classes. If no explicit ClassLoader has been set by the calling, the context class loader will be used.- Returns:
- the ClassLoader that will be used to scan for classes
-
setClassLoader
public void setClassLoader(java.lang.ClassLoader aClassloader)
Sets an explicit ClassLoader that should be used when scanning for classes. If none is set then the context ClassLoader will be used.- Parameters:
aClassloader
- a ClassLoader to use when scanning for classes
-
find
public void find(ResolverUtil.Test test, java.lang.String... packageNames)
Attempts to discover classes that pass the test. Accumulated classes can be accessed by callinggetClasses()
.- Parameters:
test
- the test to determine matching classespackageNames
- one or more package names to scan (including subpackages) for classes
-
findInPackage
public void findInPackage(ResolverUtil.Test test, java.lang.String packageName)
Scans for classes starting at the package provided and descending into subpackages. Each class is offered up to the Test as it is discovered, and if the Test returns true the class is retained. Accumulated classes can be fetched by callinggetClasses()
.- Parameters:
test
- an instance ofResolverUtil.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
-
extractPath
java.lang.String extractPath(java.net.URL url) throws java.io.UnsupportedEncodingException, java.net.URISyntaxException
- Throws:
java.io.UnsupportedEncodingException
java.net.URISyntaxException
-
loadImplementationsInBundle
private void loadImplementationsInBundle(ResolverUtil.Test test, java.lang.String packageName)
-
loadImplementationsInDirectory
private void loadImplementationsInDirectory(ResolverUtil.Test test, java.lang.String parent, java.io.File location)
Finds matches in a physical directory on a file system. Examines all files within a directory - if the File object is not a directory, and ends with .class the file is loaded and tested to see if it is acceptable according to the Test. Operates recursively to find classes within a folder structure matching the package structure.- Parameters:
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 directory
-
isTestApplicable
private boolean isTestApplicable(ResolverUtil.Test test, java.lang.String path)
-
loadImplementationsInJar
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. If the File is not a JarFile or does not exist a warning will be logged, but no error will be raised.- Parameters:
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.
-
loadImplementationsInJar
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. If the File is not a JarFile or does not exist a warning will be logged, but no error will be raised.- Parameters:
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 classes
-
close
private void close(java.util.jar.JarInputStream jarStream, java.lang.Object source)
- Parameters:
jarStream
-source
-
-
loadImplementationsInJar
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. If the File is not a JarFile or does not exist a warning will be logged, but no error will be raised.- Parameters:
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 InputStream
-
addIfMatching
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.- Parameters:
test
- the test used to determine if the class matchesfqn
- the fully qualified name of a class
-
-