commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <>
Subject Re: [classscan] Experiment on xbean-finder
Date Wed, 06 Jun 2012 04:57:10 GMT

On Jun 5, 2012, at 1:12 PM, Matt Benson wrote:

> Welcome, David!

Thanks, Matt!

Ok, so I refactored it a bit to work in some of the ideas I was hearing on IRC today.

Those changes were primarily:
 - Promote Info objects that represent class data to a separate package not tied to any bytecode
 - Add listener interface to consume the Info objects
 - Added parser abstraction to use ASM or similar library to create the Info objects and invoke

The code was there and generally written somewhat decoupled with those parts in mind.  Took
a bit of snipping and cutting here and there to fully decouple it and separate everything
out into separate packages.

There's no ParserFacory yet, that could easily be created.  I figured there was enough there
to show how things work.

Here's an overview of the code:

 - AnnotationFinder
 - IAnnotationFinder
 - ResourceFinder

AnnotationFinder is essentially the "db" and has methods to query.

ResourceFinder is for basic file location such as "META-INF/persistence.xml" and can also
be used as part of a ServiceLoader replacement.  See the ResourceFinder.mdtext for details

 - Archive
 - ArchiveIterator
 - ClassesArchive
 - ClasspathArchive
 - CompositeArchive
 - FileArchive
 - FilteredArchive
 - JarArchive

The Archive interface allows for sources of class files to be abstracted.  The JarArchive,
ClassesArchive and FileArchive are concrete implementations.  CompositeArchive is simply a
collection of Archive implementations.  FilteredArchive allows for the archive itself to be
filtered in various ways.

 - ClassFilter
 - ContainsFilter
 - ExcludeIncludeFilter
 - Filter
 - FilterList
 - Filters
 - IncludeExcludeFilter
 - PackageFilter
 - PatternFilter
 - PrefixFilter
 - SuffixFilter

The Filter interface simply allows you to give a yay or nay to a String.  This is of course
useful for greatly limiting the classes actually scanned when combined with an Archive via
wrapping it with a FilteredArchive and supplying a Filter.

FilterList is a Filter implementation that combines one or more filters.  Both "yes" and "no"
filters can be used via IncludeExcludeFilter or ExcludeIncludeFilter which are modeled after
HTTPd allowed host pattern.

PackageFilter, ClassFilter, SuffixFilter, PrefixFilter, ContainsFilter and PatternFilter are
concrete implementations of Filter that each have a simple approach to testing the string
to give a yay or nay.

The Filters class is a convenience class that makes it easy to construct the various filters
with little syntax as well as performs unwrapping when necessary if it sees things like a
FilterList with only one filter or a FilterList containing another FilterList.

 - Annotated
 - AnnotatedMember
 - AnnotatedMethod
 - MetaAnnotated
 - MetaAnnotatedClass
 - MetaAnnotatedConstructor
 - MetaAnnotatedElement
 - MetaAnnotatedField
 - MetaAnnotatedMethod
 - MetaAnnotation

This package provides basic support for meta-annotations which are simply annotation reuse
or inheritance.  CDI, Bean Validation and JAX-RS all have similar concepts of inheritance.
 This code does a more generic approach to reuse that isn't tied to any one particular specification.
 Fun to play with, but not critical to the core concept of annotation scanning.

 - Annotatable
 - AnnotationInfo
 - ClassInfo
 - FieldInfo
 - Info
 - InfoHandler
 - MethodInfo
 - PackageInfo

The basic objects to model class metadata along with a listener.

There could easily be a InfoHandlerList which would be an implementation of InfoHandler that
allowed for a collection of InfoHandlers.

 - AsmParser
 - Parser

Abstracts out the actual bytecode parsing such as ASM.  The parser need only read from the
Archive and produce the model of Info objects and invoke the InfoHandler.

 - Classes
 - SingleLinkedList
 - UriSet
 - UrlSet

Just some utilities.  UrlSet and UriSet are essentially searchable collections of URL or URI
to allow for something as large as a classpath of URLs to be easily narrowed.  Was written
before the Filter API and only partially supports it.  Would be nice to have it updated. 
SingleLinkedList is a minimally functional list designed to save memory in the model Info

Overview of AnnotationFinder methods

    public AnnotationFinder(Archive archive)

Basic constructor.  The Parser or some ParserFactory should be added.

    public AnnotationFinder enableMetaAnnotations()
    public AnnotationFinder enableFindImplementations()
    public AnnotationFinder enableFindSubclasses()

Methods to enable some heavier lifting.  Each has a cost and none are essential to basic annotation

    public List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation)
    public List<Class<?>> findAnnotatedClasses(Class<? extends Annotation>
    public List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation)
    public List<Constructor> findAnnotatedConstructors(Class<? extends Annotation>
    public List<Field> findAnnotatedFields(Class<? extends Annotation> annotation)

Fairly self explanatory.

    public List<Annotated<Class<?>>> findMetaAnnotatedClasses(Class<?
extends Annotation> annotation)
    public List<Annotated<Method>> findMetaAnnotatedMethods(Class<? extends
Annotation> annotation)
    public List<Annotated<Field>> findMetaAnnotatedFields(Class<? extends Annotation>

Meta-annotation versions of the above.  Just noticed a couple missing :)

    public boolean isAnnotationPresent(Class<? extends Annotation> annotation)
    public List<Class<?>> findClassesInPackage(String packageName, boolean recursive)

Some trivial utility methods.

    public <T> List<Class<? extends T>> findSubclasses(Class<T> clazz)
    public <T> List<Class<? extends T>> findImplementations(Class<T>

These are quite heavy and not recommended for large sets of classes such as the entire JVM
classpath.  Works great for a handful of jars.  Beyond that is not recommended unless you
have heaps of Heap.

    public AnnotationFinder select(Class<?>... clazz)
    public AnnotationFinder select(String... clazz)
    public AnnotationFinder select(Iterable<String> clazz)

Newer methods that allow you to narrow down the scope of the AnnotationFinder.  Say you have
a finder for an entire .war file and you want to get the data for just a jar or specific class
or list of classes.  Likely there could be 'join' methods to mirror these.  As well there
could be a 'select' method that could easily take a Filter as an arg.

So that's more or less what is there :)  Of course anyone is welcome to play with the code.
 Consider it soft.  Delete, add, refactor, whatever you want.  It's all in svn so no harm
can be done.  Have fun.

Any missing features?  Thoughts?


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message