Instance annotations from Object Models
adrian.brock Oct 16, 2007 8:06 AMI've written two simple examples of how to load instance annotations from
Object Models (xml).
PREPOPULATE
The first one works the same way as the MC and as I understand it the EJB3 container
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/scope/test/PopulateMetaDataRepositoryUnitTestCase.java
It explicitly adds the annotations to the mutable metadata context of the component instance
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/scope/support/TestComponentMetaDataRepositoryPopulator.java
METADATA LOADER
The second takes a more lazy approach
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/scope/test/LoaderMetaDataRepositoryUnitTestCase.java
instead of populating the context up front, it installs a MetaDataLoader
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/scope/support/TestComponentMetaDataRepositoryLoader.java
that will retrieve the annotations from the Object Model on the fly
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/scope/support/TestComponentMetaDataLoader.java
THE TESTS:
The tests are fairly trivial, they both do the same thing.
There is one test that uses an annotated class and another that uses an
unannotated class but supplies the annotation via the instance metadata.
An AOP proxy is created for each to show AOP can read both the class metadata
and the instance metadata when applying pointcuts and at runtime.
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/scope/support/TestComponentCreator.java
The tests then check that an aspect based on the annotation is being used
with the aspect retrieving the annotation in question.
METADATA POPULATION DEPLOYERS
The two alternate deployers that populate the instance metadata
both do two steps.
1) They add an AnnotatedElementMetaDataLoader for the class of the deployment component, this is the class scope that is also added to the deployment unit's scopeKey
so it appears in the full contextual metadata retrieved from DeploymentUnit.getMetaData()
and passed to AOP.
2) They maintain the instance metadata using one of the two mechanisms described
above.
FOR THE REAL THING
On the MetaDataLoader approach, I've cheated in the test by making the object
model just have a list of class annotations. In practice, it would need to be more complex
in that it will have to navigate the object model in a less trivial way.
It would also need to implement Method and Field annotation retrieval,
an example of how to do this can be found in the "Class" MetaDataLoader:
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/container/src/main/org/jboss/metadata/plugins/loader/reflection/AnnotatedElementMetaDataLoader.java
Obviously, the MetaDataLoader can do what it likes to create the annotations
(even if the underlying model is not annotations).
See the AnnotationCreator
https://svn.jboss.org/repos/jbossas/projects/microcontainer/trunk/container/src/main/org/jboss/annotation/factory/AnnotationCreator.java
e.g.
MyAnnotation annotation = (MyAnnotation) AnnotationCreator.createAnnotation("@com.acme.MyAnnocation(value=\"" + fromXML() + "\")", unit.getClassLoader());
A BUG
Finally, I found a bug in the AbstractDeploymentContext where the
getMutableMetaData() wasn't finding the metadata correctly.
The MemoryMetaDataLoader was wrapped in a MetaDataContext
so it didn't recognise it. I've fixed this problem, but it will need
an update of the snapshot if you want to use the prepopulate annotations
approach.