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 library
 - Add listener interface to consume the Info objects
 - Added parser abstraction to use ASM or similar library to create the Info 
objects and invoke listener

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:

org.apache.commons.classscan.finder
 - 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


org.apache.commons.classscan.finder.archive
 - 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.

org.apache.commons.classscan.finder.filter
 - 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.


org.apache.commons.classscan.finder.meta
 - 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.

org.apache.commons.classscan.finder.model
 - 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.

org.apache.commons.classscan.finder.parse
 - 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.

org.apache.commons.classscan.finder.util
 - 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 objects.


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 scanning.

    public List<Package> findAnnotatedPackages(Class<? extends Annotation> 
annotation)
    public List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> 
annotation)
    public List<Method> findAnnotatedMethods(Class<? extends Annotation> 
annotation)
    public List<Constructor> findAnnotatedConstructors(Class<? extends 
Annotation> 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> 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> clazz)

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?


-David


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to