You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by co...@apache.org on 2010/02/16 22:53:18 UTC

svn commit: r910710 - in /openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: intercept/WebBeansInterceptorConfig.java util/AnnotationUtil.java

Author: covener
Date: Tue Feb 16 21:53:17 2010
New Revision: 910710

URL: http://svn.apache.org/viewvc?rev=910710&view=rev
Log:
OWB-266 resolve transitive interceptor bindings for inherited annotations
OWB-267 resolve transitive interceptor bindings for inherited stereotypes
OWB-271 resolve transitive interceptor bindings for inherited/non-overridden method-level interceptors


Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java?rev=910710&r1=910709&r2=910710&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java Tue Feb 16 21:53:17 2010
@@ -16,6 +16,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -115,8 +116,9 @@
                 bindingTypeSet.add(ann);
             }
         }
-        
-        //check for stereotypes
+
+        // check for stereotypes _explicitly_ declared on the bean class (not
+        // inherited)
         Annotation[] stereoTypes = AnnotationUtil.getStereotypeMetaAnnotations(typeAnns);
         for (Annotation stero : stereoTypes)
         {
@@ -130,38 +132,68 @@
                 }
             }
         }
-        
-        //Look for inherited binding types
+
+        // Look for inherited binding types, keeping in mind that
+        // IBeanInheritedMetaData knows nothing of the transitive
+        // relationships of Interceptor Bindings or Stereotypes. We must resolve
+        // these here.
         IBeanInheritedMetaData metadata = component.getInheritedMetaData();
-        if(metadata != null)
+        if (metadata != null)
         {
             Set<Annotation> inheritedBindingTypes = metadata.getInheritedInterceptorBindings();
-            if(!inheritedBindingTypes.isEmpty())
+            if (!inheritedBindingTypes.isEmpty())
+            {
+                Annotation[] inherited_anns = new Annotation[inheritedBindingTypes.size()];
+                inherited_anns = inheritedBindingTypes.toArray(inherited_anns);
+                anns = AnnotationUtil.getInterceptorBindingMetaAnnotations(inherited_anns);
+                bindingTypeSet.addAll(Arrays.asList(anns));
+            }
+
+            // Retrieve inherited stereotypes, check for meta-annotations, and
+            // find the ultimate set of bindings
+            Set<Annotation> inheritedStereotypes = metadata.getInheritedStereoTypes();
+
+            if (!inheritedStereotypes.isEmpty())
             {
-                bindingTypeSet.addAll(inheritedBindingTypes);   
+                // We need AnnotationUtil to resolve the transitive relationship
+                // of stereotypes we've found
+                Annotation[] inherited = new Annotation[inheritedStereotypes.size()];
+                inherited = inheritedStereotypes.toArray(inherited);
+                Annotation[] transitive_stereotypes = AnnotationUtil.getStereotypeMetaAnnotations(inherited);
+
+                for (Annotation stereo : transitive_stereotypes)
+                {
+                    if (AnnotationUtil.hasInterceptorBindingMetaAnnotation(stereo.annotationType().getDeclaredAnnotations()))
+                    {
+                        Annotation[] steroInterceptorBindings = AnnotationUtil.getInterceptorBindingMetaAnnotations(stereo.annotationType().getDeclaredAnnotations());
+                        for (Annotation ann : steroInterceptorBindings)
+                        {
+                            bindingTypeSet.add(ann);
+                        }
+                    }
+                }
             }
         }
 
         anns = new Annotation[bindingTypeSet.size()];
         anns = bindingTypeSet.toArray(anns);
-        
-        if(anns.length > 0)
+
+        if (anns.length > 0)
         {
             componentInterceptors = findDeployedWebBeansInterceptor(anns);
 
             // Adding class interceptors
-            addComponentInterceptors(componentInterceptors, stack);            
+            addComponentInterceptors(componentInterceptors, stack);
         }
-                
 
         // Method level interceptors.
         if(annotatedType == null)
         {
-            addMethodInterceptors(clazz, stack, componentInterceptors);   
+            addMethodInterceptors(clazz, stack, componentInterceptors, bindingTypeSet);   
         }
         else
         {
-            addMethodInterceptors(annotatedType, stack, componentInterceptors);            
+            addMethodInterceptors(annotatedType, stack, componentInterceptors);
         }
         
         Collections.sort(stack, new InterceptorDataComparator());
@@ -194,62 +226,52 @@
 
     }
 
-    private static void addMethodInterceptors(Class<?> clazz, List<InterceptorData> stack, Set<Interceptor<?>> componentInterceptors)
+    /**
+     * Add configured interceptors, combining the bindings at the component-level with annotations on methods
+     * @param clazz the bean class
+     * @param stack the current interceptor stack for the bean
+     * @param componentInterceptors the configured interceptors from the component level
+     * @param resolvedComponentInterceptorBindings complete (including transitive) set of component-level interceptor bindings
+     */
+    private static void addMethodInterceptors(Class<?> clazz, List<InterceptorData> stack, Set<Interceptor<?>> componentInterceptors, Set<Annotation> resolvedComponentInterceptorBindings)
     {
-        Method[] methods = clazz.getDeclaredMethods();
-        
+        // All methods, not just those declared
+        Method[] methods = clazz.getMethods();
+
         for (Method method : methods)
         {
             Set<Annotation> interceptorAnns = new HashSet<Annotation>();
-
-            if (AnnotationUtil.hasInterceptorBindingMetaAnnotation(method.getAnnotations()))
-            {                
-                Annotation[] anns = AnnotationUtil.getInterceptorBindingMetaAnnotations(method.getDeclaredAnnotations());
-                Annotation[] annsClazz = AnnotationUtil.getInterceptorBindingMetaAnnotations(clazz.getDeclaredAnnotations());
-
+            if (AnnotationUtil.hasInterceptorBindingMetaAnnotation(method.getDeclaredAnnotations()))
+            {
+                Annotation[] anns = AnnotationUtil.getInterceptorBindingMetaAnnotations(method.getAnnotations());
                 for (Annotation ann : anns)
                 {
                     interceptorAnns.add(ann);
                 }
-
-                for (Annotation ann : annsClazz)
-                {
-                    interceptorAnns.add(ann);
-                }
             }
 
-            Annotation[] stereoTypes = AnnotationUtil.getStereotypeMetaAnnotations(clazz.getDeclaredAnnotations());
-            for (Annotation stero : stereoTypes)
-            {
-                if (AnnotationUtil.hasInterceptorBindingMetaAnnotation(stero.annotationType().getDeclaredAnnotations()))
-                {
-                    Annotation[] steroInterceptorBindings = AnnotationUtil.getInterceptorBindingMetaAnnotations(stero.annotationType().getDeclaredAnnotations());
-
-                    for (Annotation ann : steroInterceptorBindings)
-                    {
-                        interceptorAnns.add(ann);
-                    }
-                }
-            }
+            // To find the right interceptors, we need to consider method and
+            // class-level combined
+            interceptorAnns.addAll(resolvedComponentInterceptorBindings);
 
             if (!interceptorAnns.isEmpty())
             {
                 Annotation[] result = new Annotation[interceptorAnns.size()];
                 result = interceptorAnns.toArray(result);
-    
+
                 Set<Interceptor<?>> setInterceptors = findDeployedWebBeansInterceptor(result);
-                
-                if(componentInterceptors != null)
+
+                if (componentInterceptors != null)
                 {
-                    setInterceptors.removeAll(componentInterceptors);   
+                    setInterceptors.removeAll(componentInterceptors);
                 }
-    
+
                 Iterator<Interceptor<?>> it = setInterceptors.iterator();
-    
+
                 while (it.hasNext())
                 {
                     WebBeansInterceptor<?> interceptor = (WebBeansInterceptor<?>) it.next();
-    
+
                     WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), AroundInvoke.class, true, true, stack, method, true);
                     WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PostConstruct.class, true, true, stack, method, true);
                     WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PreDestroy.class, true, true, stack, method, true);

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java?rev=910710&r1=910709&r2=910710&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java Tue Feb 16 21:53:17 2010
@@ -986,11 +986,11 @@
     }
 
     /**
-     * If candidate class has an interceptor binding annotation type then return
+     * If any Annotations in the input is an interceptor binding annotation type then return
      * true, false otherwise.
      * 
-     * @param clazz interceptor candidate class
-     * @return true if candidate class has an interceptor binding annotation
+     * @param anns array of Annotations to check 
+     * @return true if one or moe of the input annotations are an interceptor binding annotation
      *         type false otherwise
      */
     public static boolean hasInterceptorBindingMetaAnnotation(Annotation[] anns)
@@ -1012,6 +1012,12 @@
         return false;
     }
 
+    /**
+     * Collect the interceptor bindings from an array of annotations, including
+     * transitively defined interceptor bindings.
+     * @param anns An array of annotations
+     * @return an array of interceptor binding annotations, including the input and any transitively declared annotations
+     */
     public static Annotation[] getInterceptorBindingMetaAnnotations(Annotation[] anns)
     {
         Asserts.assertNotNull(anns, "anns parameter can not be null");