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);
}