Bill Burke a JBoss old timer, Red Hatter, and successful open source entrepreneur, as he calls himself here is one of the good people I read. He created in the past a very interesting and useful small tool. That tool is called Scannotation. You can find more on that from it's own place on web in the big house of sourceforge at this address http://scannotation.sourceforge.net/. The idea at least, if not the final code, which started Scannotation was the fact that Bill worked on JBoss EJB container and needed to know more about the annotated code.
There are two often seen scenarios on annotation usage. You can have classes or instances loaded by class loaders and you want to know which annotations provides these classes. That's the first scenario. The second one is when you want to know annotations used by classes before the class loader loads the definition of classes. Scannotation give you the second scenario.
You can have jars on classpath or even the bits of a class from a stream and you can use Scannotation to load annotations. You can also find annotations from a war type archive (Java EE web application module). The trick is that you don't need to load and spent a lot of processing time and memory to load classes just to know what annotations have. Scannotation parse the bits from the class definition and gives you annotations.
After you know what to parse you can parse and store annotation usages into a AnnotationDB object. That is not a real database. It contains only two maps. The first one gives you each class which have annotations and for each one the used ones. The second map gives you all annotations, and for each one the classes which uses them. You refine the class search by adding ignored packages. There are already some ignored packages by default, also. You can refine the search by setting to collect only some specific annotation place like annotations on classes, methods, parameters or fields.
The usage is really simple, and for that I will give you an excerpt from their own tests:
URL url = ClasspathUrlFinder.findClassBase(TestSmoke.class);
AnnotationDB db = new AnnotationDB();
db.scanArchives(url);
Map<String, Set<String>> annotationIndex = db.getAnnotationIndex();
Set<String> simpleClasses = annotationIndex.get(
SimpleAnnotation.class.getName());
Assert.assertTrue(simpleClasses.contains(
ClassWithFieldAnnotation.class.getName()));
Assert.assertTrue(simpleClasses.contains(
InterfaceWithParameterAnnotations.class.getName()));
Set<String> simpleAnnotations = db.getClassIndex().get(
ClassWithFieldAnnotation.class.getName());
Assert.assertTrue(simpleAnnotations.contains(
SimpleAnnotation.class.getName()));
simpleAnnotations = db.getClassIndex().get(
InterfaceWithParameterAnnotations.class.getName());
Assert.assertTrue(simpleAnnotations.contains(
SimpleAnnotation.class.getName()));
As you can see you feed the AnnoationDB instances with URLs. These URLs can be obtained using Scannotation tools. After that you use the two provided indexes.
Scannotation is small, fast and if you like, you can modify for you needs it it does not fit well. It's Open Source licensed with Apache License v2.0.
No comments:
Post a Comment