[jboss-dev-forums] [JBoss Microcontainer Development] - Re: Supporting qualifiers in MC
kabir.khan@jboss.com
do-not-reply at jboss.com
Wed Dec 9 14:37:58 EST 2009
There is a problem with qualifier annotations applied via xml/beanmetadata. Currently, they if @Inject is used, e.g.
| public class InjectAnnotationPlugin extends PropertyAnnotationPlugin<Inject>
| {
| public final static InjectAnnotationPlugin INSTANCE = new InjectAnnotationPlugin();
|
| protected InjectAnnotationPlugin()
| {
| super(Inject.class);
| }
|
| @Override
| protected ValueMetaData createValueMetaData(PropertyInfo info, MetaData retrieval, Inject annotation)
| {
| return createTheMetaData(retrieval, annotation);
| }
|
| @Override
| public ValueMetaData createValueMetaData(ParameterInfo parameterInfo, MetaData retrieval, Inject annotation, ValueMetaData previousValue)
| {
| return createTheMetaData(retrieval, annotation);
| }
|
| private ValueMetaData createTheMetaData(MetaData retrieval, Inject annotation)
| {
| HashSet<Object> annotationSet = null;
| if (retrieval != null)
| {
| Annotation[] annotations = retrieval.getAnnotationsAnnotatedWith(Qualifier.class);
| if (annotations.length > 0)
| {
| annotationSet = new HashSet<Object>(annotations.length);
| for (Annotation ann : annotations)
| annotationSet.add(ann);
| }
| }
| return ValueUtil.createValueMetaData(annotation, annotationSet);
| }
|
| }
|
The annotationSet goes into AbstractInjectionValueMetaData as qualifiers. The annotation qualifiers are ignored if
| <inject/>
|
is used since then the InjectAnnotationPlugin is not triggered.
I am not handling these in any special way at the moment. I probably need to do something similar to what I have done for the supplied annotation qualifiers in CommonAnnotationAdapter
| protected void handleAnnotations(BeanInfo info, MetaData retrieval, U handle, boolean isApplyPhase) throws Throwable
| {
| ...
| //Existing code
| // class
| ClassInfo classInfo = info.getClassInfo();
| for (Annotation annotation : retrieval.getAnnotations())
| {
| for(T plugin : getPlugins(ElementType.TYPE, annotation, null, annotationClasses))
| {
| if (isApplyPhase)
| applyPlugin(plugin, annotation, classInfo, retrieval, handle);
| else
| cleanPlugin(plugin, annotation, classInfo, retrieval, handle);
| }
| }
|
| //New code to handle meta-annotations on class
| Map<Class<? extends Annotation>, Set<T>> metaAnnotationsForType = metaAnnotationsPluginsMap.get(ElementType.TYPE);
| if (metaAnnotationsForType != null)
| {
| for (Entry<Class<? extends Annotation>, Set<T>> entry : metaAnnotationsForType.entrySet()) //Qualifer is registered here
| {
| for (Annotation annotation : retrieval.getAnnotationsAnnotatedWith(entry.getKey()))
| {
| for (T plugin : entry.getValue())
| {
| if (isApplyPhase)
| applyPlugin(plugin, annotation, classInfo, retrieval, handle);
| else
| cleanPlugin(plugin, annotation, classInfo, retrieval, handle);
| }
| }
| }
| }
| ...
|
The plugin that handles adding the qualifiers
| public class SuppliedQualifierAnnotationPlugin extends ClassAnnotationPlugin<Annotation> implements MetaAnnotationPlugin<ClassInfo, Qualifier>
| {
| public static final SuppliedQualifierAnnotationPlugin INSTANCE = new SuppliedQualifierAnnotationPlugin();
|
| protected SuppliedQualifierAnnotationPlugin()
| {
| super(Annotation.class);
| addTypes(ElementType.TYPE);
| }
|
| protected boolean isElementTypeSupported(ElementType type)
| {
| return true;
| }
|
| @Override
| protected boolean isCleanup()
| {
| return true;
| }
|
| @Override
| protected List<? extends MetaDataVisitorNode> internalApplyAnnotation(ClassInfo info, MetaData retrieval, Annotation annotation, KernelControllerContext context) throws Throwable
| {
| if (context != null)
| {
| MetaDataRetrieval instanceMetaData = context.getKernel().getMetaDataRepository().getMetaDataRepository().getMetaDataRetrieval(context.getScopeInfo().getMutableScope());
| QualifiersMdrUtil.addQualifiersToMdrRetrieval(instanceMetaData, QualifierType.SUPPLIED, null, annotation);
| }
| return null;
| }
|
| @Override
| protected void internalCleanAnnotation(ClassInfo info, MetaData retrieval, Annotation annotation, KernelControllerContext context) throws Throwable
| {
| if (context != null)
| {
| MetaDataRetrieval instanceMetaData = context.getKernel().getMetaDataRepository().getMetaDataRepository().getMetaDataRetrieval(context.getScopeInfo().getMutableScope());
| QualifiersMdrUtil.removeQualifiersFromMdrRetrieval(instanceMetaData, QualifierType.SUPPLIED, null, annotation);
| }
| }
|
| //From MetaAnnotationPlugin
| public Class<Qualifier> getMetaAnnotation()
| {
| return Qualifier.class;
| }
| }
|
However, that means checking everything for qualifiers annotations in the annotation adapter. My initial idea is to do something along the lines of this pseudo-code for each parameter/property, but I will sleep on it
| for (ParameterMetaData pmd : constructorInfo.getParameters())
| {
| if (pmd.getValue() != null && pmd.getValue() instanceof AbstractInjectionValueMetaData)
| {
| Map<Class<? extends Annotation>, Set<T>> metaAnnotationsForType = metaAnnotationsPluginsMap.get(ElementType.PARAMETER);
|
| for (Entry<Class<? extends Annotation>, Set<T>> entry : metaAnnotationsForType.entrySet()) //Qualifer is registered here
| {
| for (Annotation annotation : retrieval.getAnnotationsAnnotatedWith(entry.getKey()))
| {
| for (T plugin : entry.getValue())
| applyMetaAnnotationPlugin(plugin, annotation, parameterInfo, pmd, retrieval, handle); //Can get the AbstractInjectionValueMetaData from pmd internally and set the annotation in the set of qualifiers there
| }
| }
| }
| }
|
If the value is a collection, array etc. I would also need to go into each element checking for AIVMD.
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4269861#4269861
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4269861
More information about the jboss-dev-forums
mailing list