Author: covener
Date: Tue Sep 28 14:36:44 2010
New Revision: 1002180

URL: http://svn.apache.org/viewvc?rev=1002180&view=rev
Log:
[OWB-456] remove @AroundInvoke annotated methods of a superclass when a 
subclass 
has overridden the annotated method.

resolves a failure in 
org.jboss.jsr299.tck.interceptors.tests.aroundInvoke.order.InvocationOrderTest

Note: this moves some methods that are @Interceptors{...} related our of
EJBInterceptorConfig into InterceptorUtil, which we may want to refactor
later for clarity.

Submitted By: Rohit Kelapure
Reviewed By: Eric Covener


Modified:
    
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/interceptor/OpenWebBeansEjbInterceptor.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/ejb/EJBInterceptorConfig.java
    
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java

Modified: 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/interceptor/OpenWebBeansEjbInterceptor.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/interceptor/OpenWebBeansEjbInterceptor.java?rev=1002180&r1=1002179&r2=1002180&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/interceptor/OpenWebBeansEjbInterceptor.java
 (original)
+++ 
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/interceptor/OpenWebBeansEjbInterceptor.java
 Tue Sep 28 14:36:44 2010
@@ -527,6 +527,7 @@ public class OpenWebBeansEjbInterceptor 
 
                 // Filter both EJB and WebBeans interceptors
                 
InterceptorUtil.filterCommonInterceptorStackList(filteredInterceptorStack, 
method);
+                
InterceptorUtil.filterOverridenAroundInvokeInterceptor(injectionTarget.getBeanClass(),
 filteredInterceptorStack);
 
                 this.interceptedMethodMap.put(method, 
filteredInterceptorStack);
             }

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java?rev=1002180&r1=1002179&r2=1002180&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java
 Tue Sep 28 14:36:44 2010
@@ -249,7 +249,7 @@ public abstract class InterceptorHandler
         
                             // Filter both EJB and WebBeans interceptors
                             
InterceptorUtil.filterCommonInterceptorStackList(filteredInterceptorStack, 
method);
-        
+                            
InterceptorUtil.filterOverridenAroundInvokeInterceptor(bean.getBeanClass(), 
filteredInterceptorStack);
                             this.interceptedMethodMap.put(method, 
filteredInterceptorStack);
                         }
                         

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java?rev=1002180&r1=1002179&r2=1002180&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java
 Tue Sep 28 14:36:44 2010
@@ -39,12 +39,14 @@ import javax.inject.Inject;
 import javax.interceptor.AroundInvoke;
 import javax.interceptor.AroundTimeout;
 import javax.interceptor.ExcludeClassInterceptors;
+import javax.interceptor.Interceptors;
 import javax.interceptor.InvocationContext;
 
 import org.apache.webbeans.component.InjectionTargetBean;
 import org.apache.webbeans.context.creational.CreationalContextImpl;
 import org.apache.webbeans.exception.WebBeansConfigurationException;
 import org.apache.webbeans.exception.WebBeansException;
+import org.apache.webbeans.logger.WebBeansLogger;
 import org.apache.webbeans.plugins.OpenWebBeansEjbLCAPlugin;
 import org.apache.webbeans.plugins.PluginLoader;
 import org.apache.webbeans.util.AnnotationUtil;
@@ -57,6 +59,9 @@ public final class InterceptorUtil
     static OpenWebBeansEjbLCAPlugin ejbPlugin = null;
     static Class<? extends Annotation> prePassivateClass  = null;
     static Class<? extends Annotation> postActivateClass  = null;
+    
+    private static final WebBeansLogger logger = 
WebBeansLogger.getLogger(InterceptorUtil.class);
+
 
     private InterceptorUtil()
     {
@@ -620,4 +625,227 @@ public final class InterceptorUtil
         return impl.proceed();
     }
 
+        
+
+    /**
+     * Return true if candidate class is a super class of given interceptor
+     * class.
+     * 
+     * @param interceptorClass interceptor class
+     * @param candidateClass candaite class
+     * @return true if candidate class is a super class of given interceptor
+     *         class
+     */
+    public static boolean checkInInterceptorHierarchy(Class<?> 
interceptorClass, Class<?> candidateClass)
+    {
+        Class<?> superClassInterceptor = interceptorClass.getSuperclass();
+        if (superClassInterceptor != null && 
!superClassInterceptor.equals(Object.class))
+        {
+            if (superClassInterceptor.equals(candidateClass))
+            {
+                return true;
+            }
+
+            else
+            {
+                return checkInInterceptorHierarchy(superClassInterceptor, 
candidateClass);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Remove bean inherited and overriden lifecycle interceptor method from 
its
+     * stack list.
+     * 
+     * @param clazz bean class
+     * @param stack bean interceptor stack
+     */
+    public static void filterOverridenLifecycleInterceptor(Class<?> beanClass, 
List<InterceptorData> stack)
+    {
+        List<InterceptorData> overridenInterceptors = new 
ArrayList<InterceptorData>();
+        Iterator<InterceptorData> it = stack.iterator();
+        while (it.hasNext())
+        {
+            InterceptorData interceptorData = it.next();
+            if (interceptorData.isLifecycleInterceptor())
+            {
+                InterceptorData overridenInterceptor = 
getOverridenInterceptor(beanClass, interceptorData, stack);
+                if (null != overridenInterceptor)
+                {
+                    if (logger.wblWillLogDebug())
+                    {
+                        logger.debug("REMOVING parent " + 
overridenInterceptor);
+                    }
+
+                    it.remove();
+                }
+            }
+        }
+        stack.removeAll(overridenInterceptors);
+    }
+
+    /**
+     * If an AroundInvoke method is overridden by another method (regardless of
+     * whether that method is itself an AroundInvoke method), it will not be
+     * invoked. Remove bean inherited but overriden around invoke interceptor
+     * method from its stack list.
+     * 
+     * @param clazz bean class
+     * @param stack bean interceptor stack
+     */
+    public static void filterOverridenAroundInvokeInterceptor(Class<?> 
beanClass, List<InterceptorData> stack)
+    {
+
+        List<InterceptorData> overridenInterceptors = new 
ArrayList<InterceptorData>();
+        Iterator<InterceptorData> it = stack.iterator();
+        while (it.hasNext())
+        {
+            InterceptorData interceptorData = it.next();
+            if (false == interceptorData.isLifecycleInterceptor())
+            {
+                InterceptorData overridenInterceptor = 
getOverridenInterceptor(beanClass, interceptorData, stack);
+                if (null != overridenInterceptor)
+                {
+                    overridenInterceptors.add(overridenInterceptor);
+                    if (logger.wblWillLogDebug())
+                    {
+                        logger.debug("REMOVING parent " + 
overridenInterceptor);
+                    }
+
+                }
+            }
+        }
+
+        stack.removeAll(overridenInterceptors);
+    }
+
+    /**
+     * Check to see if any parent class in the hierarchy is in this interceptor
+     * stack If any method in the current interceptor has the same name and
+     * signature as the parent's interceptor method remove the parent
+     * interceptor from the stack
+     * 
+     * @param interceptorData
+     * @param stack
+     * @return the overriden InterceptorData that represents the parent
+     */
+    private static InterceptorData getOverridenInterceptor(Class<?> clazz, 
InterceptorData interceptorData, List<InterceptorData> stack)
+    {
+        Method interceptor = interceptorData.getInterceptorMethod();
+        Class<?> interceptorClass = interceptor.getDeclaringClass();
+
+        for (InterceptorData superInterceptorData : stack)
+        {
+
+            if 
(interceptorClass.equals(superInterceptorData.getInterceptorClass()))
+            {
+                continue; // we are looking at ourself
+            }
+
+            // parent interceptor in the interceptor stack
+            if (checkInInterceptorHierarchy(interceptorClass, 
superInterceptorData.getInterceptorClass()))
+            {
+
+                // get the interceptor method of the parent
+                Method superInterceptorMethod = 
superInterceptorData.getInterceptorMethod();
+                Method childInterceptorMethod = 
ClassUtil.getDeclaredMethod(interceptorClass, superInterceptorMethod.getName(), 
superInterceptorMethod.getParameterTypes());
+
+                if (null != childInterceptorMethod && 
ClassUtil.isOverriden(childInterceptorMethod, superInterceptorMethod))
+                {
+                    if (logger.wblWillLogDebug())
+                    {
+                        logger.debug("KEEPING child " + interceptorData);
+                    }
+                    return superInterceptorData;
+                }
+            }
+            else
+            { // the class may be overriding the interceptor method
+                return removeInheritedButOverridenInterceptor(clazz, 
interceptorData);
+
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * This returns the Interceptor that is defined in a super class of the 
bean
+     * and has the same method as the bean. i.e. the bean method overrides the
+     * Interceptor method defined in the super class.
+     * 
+     * @param clazz
+     * @param interceptorData
+     * @return
+     */
+    private static InterceptorData 
removeInheritedButOverridenInterceptor(Class<?> clazz, InterceptorData 
interceptorData)
+    {
+        Method interceptor = interceptorData.getInterceptorMethod();
+        Class<?> declaringClass = interceptor.getDeclaringClass();
+
+        // Not look for Interceptor classes
+        if (checkGivenClassIsInInterceptorList(clazz, declaringClass))
+        {
+            return null;
+        }
+
+        if (!declaringClass.equals(clazz) && 
checkInInterceptorHierarchy(clazz, declaringClass))
+        {
+            Method found = ClassUtil.getDeclaredMethod(clazz, 
interceptor.getName(), interceptor.getParameterTypes());
+            if (found != null)
+            {
+                if (logger.wblWillLogDebug())
+                {
+                    logger.debug("KEEPING child " + clazz);
+                }
+                return interceptorData;
+            }
+            else
+            {
+                Class<?> superClass = clazz.getSuperclass();
+                if (superClass != null && !superClass.equals(Object.class))
+                {
+                    return removeInheritedButOverridenInterceptor(superClass, 
interceptorData);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Return true if given candidate is listed in interceptors list.
+     * 
+     * @param mainClass bean class
+     * @param candidateClass interceptor candidate class
+     * @return true if given candidate is listed in interceptors list
+     */
+    public static boolean checkGivenClassIsInInterceptorList(Class<?> 
mainClass, Class<?> candidateClass)
+    {
+        if (AnnotationUtil.hasClassAnnotation(mainClass, Interceptors.class))
+        {
+            Interceptors incs = mainClass.getAnnotation(Interceptors.class);
+            Class<?>[] intClasses = incs.value();
+
+            for (Class<?> intClass : intClasses)
+            {
+                if (intClass.equals(candidateClass))
+                {
+                    return true;
+                }
+                else
+                {
+                    if (checkInInterceptorHierarchy(intClass, candidateClass))
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
 }

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/ejb/EJBInterceptorConfig.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/ejb/EJBInterceptorConfig.java?rev=1002180&r1=1002179&r2=1002180&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/ejb/EJBInterceptorConfig.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/ejb/EJBInterceptorConfig.java
 Tue Sep 28 14:36:44 2010
@@ -20,7 +20,6 @@ package org.apache.webbeans.intercept.ej
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.annotation.PostConstruct;
@@ -30,6 +29,7 @@ import javax.interceptor.AroundTimeout;
 import javax.interceptor.Interceptors;
 
 import org.apache.webbeans.intercept.InterceptorData;
+import org.apache.webbeans.intercept.InterceptorUtil;
 import org.apache.webbeans.util.AnnotationUtil;
 import org.apache.webbeans.util.Asserts;
 import org.apache.webbeans.util.ClassUtil;
@@ -72,123 +72,9 @@ public final class EJBInterceptorConfig
             }
 
         }
-
-        configureBeanAnnots(clazz, stack);        
-        checkInheritedButOverridenMethod(clazz, stack);        
-    }
-    
-    /**
-     * Return true if given candidate is listed in interceptors list. 
-     * @param mainClass bean class
-     * @param candidateClass interceptor candidate class
-     * @return true if given candidate is listed in interceptors list
-     */
-    private static boolean checkGivenClassIsInInterceptorList(Class<?> 
mainClass, Class<?> candidateClass)
-    {
-        if (AnnotationUtil.hasClassAnnotation(mainClass, Interceptors.class))
-        {
-            Interceptors incs = mainClass.getAnnotation(Interceptors.class);
-            Class<?>[] intClasses = incs.value();
-            
-            for (Class<?> intClass : intClasses)
-            {
-                if(intClass.equals(candidateClass))
-                {
-                    return true;
-                }
-                else
-                {
-                    if(checkInInterceptorHierarchy(intClass, candidateClass))
-                    {
-                        return true;
-                    }
-                }
-            }
-        }
+        configureBeanAnnots(clazz, stack);
+        InterceptorUtil.filterOverridenLifecycleInterceptor(clazz, stack);
         
-        return false;
-    }
-    
-    /**
-     * Return true if candidate class is a super class of given interceptor 
class.
-     * @param interceptorClass interceptor class
-     * @param candidateClass candaite class
-     * @return true if candidate class is a super class of given interceptor 
class
-     */
-    private static boolean checkInInterceptorHierarchy(Class<?> 
interceptorClass, Class<?> candidateClass)
-    {
-        Class<?> superClassInterceptor = interceptorClass.getSuperclass();
-        if(superClassInterceptor != null && 
!superClassInterceptor.equals(Object.class))
-        {
-            if(superClassInterceptor.equals(candidateClass))
-            {
-                return true;
-            }
-            
-            else
-            {
-                return checkInInterceptorHierarchy(superClassInterceptor, 
candidateClass);
-            }
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Remove bean inherited but overriden lifecycle interceptor method from
-     * its stack list.
-     * @param clazz bean class
-     * @param stack bean interceptor stack
-     */
-    private static void checkInheritedButOverridenMethod(Class<?> 
clazz,List<InterceptorData> stack)
-    {
-        Iterator<InterceptorData> it = stack.iterator();
-        while(it.hasNext())
-        {
-            InterceptorData interceptorData = it.next();
-            
-            if(interceptorData.isLifecycleInterceptor())
-            {
-                if(removeInheritedButOverridenInterceptor(clazz, 
interceptorData))
-                {
-                    it.remove();
-                }                
-            }
-        }
-    }
-    
-    /**
-     * @see EJBInterceptorConfig#checkInheritedButOverridenMethod(Class, List) 
 
-     */
-    private static boolean removeInheritedButOverridenInterceptor(Class<?> 
clazz, InterceptorData interceptorData)
-    {    
-        Method interceptor = interceptorData.getInterceptorMethod();
-        Class<?> declaringClass = interceptor.getDeclaringClass();
-        
-        //Not look for Interceptor classes
-        if(checkGivenClassIsInInterceptorList(clazz, declaringClass))
-        {
-            return false;
-        }
-        
-        if(!declaringClass.equals(clazz))
-        {
-            Method found = 
ClassUtil.getDeclaredMethod(clazz,interceptor.getName(), 
interceptor.getParameterTypes());                
-            if(found != null)
-            {
-                return true;
-            }
-            else
-            {
-                Class<?> superClass = clazz.getSuperclass();
-                if(superClass != null && !superClass.equals(Object.class))
-                {
-                    return removeInheritedButOverridenInterceptor(superClass, 
interceptorData);   
-                }            
-            }            
-        }
-                
-        return false;
     }
     
     /**

Modified: 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java?rev=1002180&r1=1002179&r2=1002180&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java
 Tue Sep 28 14:36:44 2010
@@ -119,8 +119,8 @@ public class EJBInterceptComponentTest e
 
         String[] arr = (String[]) obj;
 
-        Assert.assertEquals(2, arr.length);
-        Assert.assertTrue("key".equals(arr[0]) && "key0".equals(arr[1]) || 
"key".equals(arr[1]) && "key0".equals(arr[0]));
+        Assert.assertEquals(1, arr.length);
+        Assert.assertTrue("key0".equals(arr[0]));
         ContextFactory.destroyRequestContext(null);
     }
 


Reply via email to