- The latest version (1.0.0) is now available at the Maven Central Repository.
This project provides the Java class org.cornutum.annotation.Finder. A Finder offers an
interface to search Java class files for class elements with specific annotations. A Finder can
search for class files in class path elements like directories and JAR files. At runtime, these
class path elements might already be accessible via a ClassLoader, but that isn't required. For
example, you can use the Finder to locate class path elements to be loaded later.
The result of Finder.find() is a Stream of Annotated objects. Each Annotated instance
identifies the Annotation class found, the class element that was annotated (class, method, or field),
the class containing the annotated element, and the location of the corresponding *.class file.
But which Annotation references does the Finder find? That depends on where you look and
what you look for.
The "where" is defined by the Finder.inClasses() method, which defines the class path elements
(directories, JAR files, or *.class files) to be searched.
The "what" is determined by the AnnotationFilter specified by the Finder.filter() method. An
AnnotationFilter specifies which Annotation classes to look for and which classes to include in
the search. By default, Finder uses a filter that returns all Annotation references in all
classes searched. But the PackageFilter provides more control by allowing you to specify exactly
which Annotation classes to look for and which Java packages will be included in the search.
You're free to use your own AnnotationFilter implementation to tailor the search more precisely.
import org.cornutum.annotation.Annotated;
import org.cornutum.annotation.Finder;
import static org.cornutum.annotation.Files.classPathFor;
@Test
public void findAllInClasspath()
{
// When...
Stream<Annotated> stream =
new Finder()
// ...searching in: currently loaded resources in the "org.cornutum.annotation" package
.inClasses( classPathFor( "org.cornutum.annotation"))
// ...looking for: all annotations in all classes (the default)
.find();
// Then...
printAnnotated( stream);
}import org.cornutum.annotation.Annotated;
import org.cornutum.annotation.Finder;
import org.cornutum.annotation.PackageFilter;
@Test
public void findDeprecatedMethodsInSystemClassPath()
{
// When...
Stream<Annotated> stream =
new Finder()
// ...searching in: all members of the class path used to start the JVM
.inSystemClassPath()
// ...looking for: Deprecated elements
.filter( new PackageFilter( Deprecated.class))
// ...returning: only annotated methods
.find()
.filter( Annotated::isMethod);
// Then...
printAnnotated( stream);
}import org.cornutum.annotation.Annotated;
import org.cornutum.annotation.Finder;
import org.cornutum.annotation.PackageFilter;
@Test
public void findSpecificInJar()
{
// When...
Stream<Annotated> stream =
new Finder()
// ...searching in: external JAR files not on the class path
.inClasses(
getResourceFile( getClass(), "tcases-openapi.jar"),
getResourceFile( getClass(), "tcases-rest-assured.jar"))
// ...looking for: specific annotations in certain packages
.filter(
new PackageFilter()
.annotation(
"org.cornutum.tcases.openapi.testwriter.ApiTestCaseWriter",
"org.cornutum.tcases.openapi.testwriter.ApiTestWriter")
.inPackage( "org.cornutum.tcases.openapi.restassured"))
.find();
// Then...
printAnnotated( stream);
}-
How do I add this as a dependency to my Maven project?
Add this to your project POM:
<dependency> <groupId>org.cornutum.annotation</groupId> <artifactId>finder</artifactId> <version>...</version> </dependency>
-
How can I run the examples?
Try running the ExampleTest.
-
How does this compare with the
AnnotationDetector?The project was inspired by the
AnnotationDetectorfrom Ronald Muller (XIAM Solutions BV) and reuses some of its code. Like theAnnotationDetector, theFinderis fast and light-weight, with no additional dependencies. But theFinderalso offers some important new features.-
Stream interface: Results can be handled using all of the capabilities of a Java
Stream. In particular, you can usefindFirst()to terminate the search when a specific element is found. -
Extensible filtering: The "what" of the search is decoupled from the "where". You can easily inject your own
AnnotationFilterimplementation. You can use aPackageFilterto limit any search to specific packages. -
Decoupled from the class path: You can find references to annotation classes that are not currently loaded. You can search directories and JAR files that are not currently loaded.
-
Efficient search: Large classes are searched without reading the entire class file into memory. During the search, at most one class file input stream is open.
-