[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