[jboss-cvs] JBossAS SVN: r93197 - in projects/ejb3/trunk: core/src/main/java/org/jboss/ejb3 and 7 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Sep 4 04:51:14 EDT 2009
Author: jaikiran
Date: 2009-09-04 04:51:14 -0400 (Fri, 04 Sep 2009)
New Revision: 93197
Added:
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbackInterceptorMethodLazyInterceptor.java
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/LifecycleMethodInterceptorsInvocation.java
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/DummyBeanContext.java
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/FirstInterceptor.java
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/InterceptorInvocationOrderTracker.java
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/SecondInterceptor.java
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/unit/
projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/unit/LifecycleMethodInterceptorsInvocationTestCase.java
Removed:
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java
Modified:
projects/ejb3/trunk/core/pom.xml
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbacks.java
projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/AbstractContainer.java
Log:
EJBTHREE-1905 Lifecycle interceptors will be scanned only once per bean container per lifecycle
Modified: projects/ejb3/trunk/core/pom.xml
===================================================================
--- projects/ejb3/trunk/core/pom.xml 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/core/pom.xml 2009-09-04 08:51:14 UTC (rev 93197)
@@ -404,7 +404,7 @@
<dependency>
<groupId>org.jboss.ejb3</groupId>
<artifactId>jboss-ejb3-interceptors</artifactId>
- <version>1.0.3</version>
+ <version>1.0.4-SNAPSHOT</version>
</dependency>
<dependency>
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -25,7 +25,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -65,7 +64,6 @@
import org.jboss.aop.MethodInfo;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.annotation.AnnotationRepository;
-import org.jboss.aop.joinpoint.ConstructionInvocation;
import org.jboss.aop.microcontainer.annotations.DisableAOP;
import org.jboss.aop.util.MethodHashing;
import org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor;
@@ -80,7 +78,6 @@
import org.jboss.ejb3.injection.InjectionInvocation;
import org.jboss.ejb3.interceptor.InterceptorInfoRepository;
import org.jboss.ejb3.interceptor.InterceptorInjector;
-import org.jboss.ejb3.interceptors.aop.LifecycleCallbacks;
import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor;
import org.jboss.ejb3.interceptors.direct.DirectContainer;
import org.jboss.ejb3.interceptors.direct.IndirectContainer;
@@ -1121,65 +1118,11 @@
*/
protected void invokeCallback(BeanContext<?> beanContext, Class<? extends Annotation> callbackAnnotationClass)
{
- try
- {
- // Yes, ugly way of doing things. But, this is only way to be able to
- // support this existing invokeCallback(BeanContext<?> beanContext...)
- // API
- if (beanContext instanceof EnterpriseBeanContext)
- {
- // the EnterpriseBeanContext is capable of caching the AOP interceptor
- // instances and hence faster. So let's use that version of
- // invokeCallback(EnterpriseBeanContext, Class)
- EnterpriseBeanContext<?> enterpriseBeanContext = (EnterpriseBeanContext<?>) beanContext;
- this.invokeCallback(enterpriseBeanContext, callbackAnnotationClass);
- return;
- }
-
- // Do lifecycle callbacks
- List<Class<?>> lifecycleInterceptorClasses = beanContainer.getInterceptorRegistry().getLifecycleInterceptorClasses();
- Advisor advisor = getAdvisor();
- Interceptor interceptors[] = LifecycleCallbacks.createLifecycleCallbackInterceptors(advisor, lifecycleInterceptorClasses, beanContext, callbackAnnotationClass);
-
- Constructor<?> constructor = beanClass.getConstructor();
- Object initargs[] = null;
- ConstructionInvocation invocation = new ConstructionInvocation(interceptors, constructor, initargs);
- invocation.setAdvisor(advisor);
- invocation.setTargetObject(beanContext.getInstance());
- invocation.invokeNext();
- }
- catch(Throwable t)
- {
- throw new RuntimeException(t);
- }
+ // it's the BeanContainer's responsibility to invoke the callback
+ // through the correct interceptors. So let's pass the call to the beanContainer
+ this.getBeanContainer().invokeCallback(beanContext, callbackAnnotationClass);
}
- /**
- * Invokes the lifecycle callback(s) represented by <code>callbackAnnotationClass</code>
- * through a (cached) AOP interceptor chain, on the bean context represented by
- * <code>enterpriseBeanContext</code>.
- *
- * @param enterpriseBeanContext
- * @param callbackAnnotationClass
- */
- protected void invokeCallback(EnterpriseBeanContext<?> enterpriseBeanContext, Class<? extends Annotation> callbackAnnotationClass)
- {
- try
- {
- Interceptor interceptors[] = enterpriseBeanContext.getLifecycleInterceptors(callbackAnnotationClass);
- Constructor<?> constructor = beanClass.getConstructor();
- Object initargs[] = null;
- ConstructionInvocation invocation = new ConstructionInvocation(interceptors, constructor, initargs);
- invocation.setAdvisor(this.getAdvisor());
- invocation.setTargetObject(enterpriseBeanContext.getInstance());
- invocation.invokeNext();
- }
- catch(Throwable t)
- {
- throw new RuntimeException(t);
- }
- }
-
public void invokePostConstruct(BeanContext<?> beanContext)
{
// FIXME: This is a dirty hack to notify AS EJBTimerService about what's going on
@@ -1769,15 +1712,4 @@
this.semaphore.release();
}
}
-
- /**
- * Returns the lifecycle callback interceptors (javax.interceptor.Interceptors)
- * that have been defined on the bean
- *
- * @return
- */
- public List<Class<?>> getLifecycleInterceptorClasses()
- {
- return this.beanContainer.getInterceptorRegistry().getLifecycleInterceptorClasses();
- }
}
Deleted: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EnterpriseBeanContext.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -1,151 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.ejb3;
-
-import java.lang.annotation.Annotation;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.ejb.PostActivate;
-import javax.ejb.PrePassivate;
-
-import org.jboss.aop.Advisor;
-import org.jboss.aop.advice.Interceptor;
-import org.jboss.ejb3.interceptors.aop.LifecycleCallbacks;
-
-/**
- * EnterpriseBeanContext
- *
- * Represents a {@link BeanContext} for an {@link EJBContainer}
- *
- * @author Jaikiran Pai
- * @version $Revision: $
- */
-public abstract class EnterpriseBeanContext<T extends EJBContainer> extends BaseContext<T>
-{
-
- /**
- * Maintains a array of interceptors applicable to this bean context
- * for each of the lifecycle callbacks
- */
- protected transient Map<Class<? extends Annotation>, Interceptor[]> lifecycleCallbackInterceptors = new HashMap<Class<? extends Annotation>, Interceptor[]>();
-
- /**
- *
- * @param container Container instance associated with this bean
- * context
- */
- protected EnterpriseBeanContext(T container)
- {
- super(container);
- }
-
- /**
- *
- * @param container Container instance associated with this bean context
- * @param bean The instance of the bean implementation
- */
- protected EnterpriseBeanContext(T container, Object bean)
- {
- super(container, bean);
- }
-
- /**
- * Only for externalization use by subclass StatefulBeanContext; do not use elsewhere.
- *
- * @deprecated
- */
- protected EnterpriseBeanContext()
- {
-
- }
-
- /**
- * Returns the interceptor instances (which is a combination of our internal
- * AOP interceptors and bean developer defined {@link javax.interceptor.Interceptors}),
- * corresponding to the <code>lifecycleCallbackAnnotation</code>.
- *
- * Internally caches the interceptor instances corresponding to each of the lifecycle
- * callbacks, for this bean context
- *
- * @param lifecycleCallbackAnnotation Lifecycle callback annotations like {@link PrePassivate},
- * {@link PostActivate}, {@link PreDestroy}, {@link PostConstruct}
- *
- * @return Returns an empty array if there are no interceptor instances associated with this
- * bean context, for the <code>lifecycleCallbackAnnotation</code>. Else, returns the
- * array of interceptors applicable to this bean context for the
- * <code>lifecycleCallbackAnnotation</code>
- */
- public Interceptor[] getLifecycleInterceptors(Class<? extends Annotation> lifecycleCallbackAnnotation)
- {
- Interceptor[] interceptors = this.lifecycleCallbackInterceptors.get(lifecycleCallbackAnnotation);
- // If null then we haven't yet initialized the lifecycle callback interceptors, since
- // we intentionally do a lazy initialization per lifecycle callback. The initialization
- // happens only once, when this method is called for the first time on this bean context,
- // for the specific lifecycle callback annotation.
- if (interceptors == null)
- {
- interceptors = this.createLifecycleInterceptors(lifecycleCallbackAnnotation);
- if (interceptors == null)
- {
- // No interceptors available, so create an empty chain and maintain in the map,
- // to avoid trying to init again the next time
- // this method is called for this specifc lifecycle callback
- interceptors = new Interceptor[0];
- }
- this.lifecycleCallbackInterceptors.put(lifecycleCallbackAnnotation, interceptors);
- }
- return this.lifecycleCallbackInterceptors.get(lifecycleCallbackAnnotation);
- }
-
- /**
- * Creates an AOP interceptor chain out of the lifecycle interceptors for the
- * <code>lifecycleCallbackAnnotation</code>
- *
- * @param lifecycleCallbackAnnotation The lifecycle callback annotation
- * @return
- */
- protected Interceptor[] createLifecycleInterceptors(Class<? extends Annotation> lifecycleCallbackAnnotation)
- {
- // Get the lifecycle interceptor classes of the bean
- List<Class<?>> lifecycleInterceptorClasses = this.getContainer().getLifecycleInterceptorClasses();
- Advisor advisor = this.getContainer().getAdvisor();
- Interceptor interceptors[];
- try
- {
- // Create a AOP interceptor chain out of the lifecycle interceptor classes
- interceptors = LifecycleCallbacks.createLifecycleCallbackInterceptors(advisor, lifecycleInterceptorClasses,
- this, lifecycleCallbackAnnotation);
- }
- catch (Exception e)
- {
- throw new RuntimeException("Could not create lifecycle interceptor for lifecycle "
- + lifecycleCallbackAnnotation + " on bean context " + this);
- }
-
- return interceptors;
- }
-
-}
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDBContext.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -23,7 +23,7 @@
import javax.ejb.EJBContext;
-import org.jboss.ejb3.EnterpriseBeanContext;
+import org.jboss.ejb3.BaseContext;
/**
* Comment
@@ -31,7 +31,7 @@
* @author <a href="mailto:bill at jboss.org">Bill Burke</a>
* @version $Revision$
*/
-public class MDBContext extends EnterpriseBeanContext<MessagingContainer>
+public class MDBContext extends BaseContext<MessagingContainer>
{
protected EJBContext ejbContext;
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionBeanContext.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -23,7 +23,7 @@
import javax.ejb.EJBContext;
-import org.jboss.ejb3.EnterpriseBeanContext;
+import org.jboss.ejb3.BaseContext;
/**
* An instance of an enterprise bean link to its container.
@@ -31,7 +31,7 @@
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
* @version $Revision$
*/
-public abstract class SessionBeanContext<T extends SessionContainer> extends EnterpriseBeanContext<T>
+public abstract class SessionBeanContext<T extends SessionContainer> extends BaseContext<T>
{
protected EJBContext ejbContext;
Added: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbackInterceptorMethodLazyInterceptor.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbackInterceptorMethodLazyInterceptor.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbackInterceptorMethodLazyInterceptor.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,143 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.aop;
+
+import java.lang.reflect.Method;
+
+import javax.interceptor.InvocationContext;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.ejb3.interceptors.container.BeanContext;
+import org.jboss.ejb3.interceptors.container.LifecycleMethodInterceptorsInvocation;
+
+/**
+ * LifecycleCallbackInterceptorMethodLazyInterceptor
+ *
+ * An AOP interceptor wrapper for lifecycle callback methods on (javax.interceptor.Interceptors)
+ * interceptor classes. Unlike the {@link LifecycleCallbackInterceptorMethodInterceptor} AOP interceptor,
+ * this class does *not* require a interceptor class instance while creating this interceptor. Instead
+ * the interceptor instance is obtained through the {@link Invocation} when the {@link Interceptor#invoke(Invocation)}
+ * method is invoked
+ *
+ * @see #invoke(Invocation)
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class LifecycleCallbackInterceptorMethodLazyInterceptor implements Interceptor
+{
+
+ /**
+ * The lifecycle method
+ */
+ private Method lifecycleMethod;
+
+ /**
+ * Lifecycle interceptor class
+ */
+ private Class<?> lifecycleInterceptorClass;
+
+ /**
+ * Creates a {@link LifecycleCallbackInterceptorMethodLazyInterceptor} based on the
+ * interceptor class and the interceptor method.
+ *
+ * The interceptor instance, corresponding to the <code>interceptorClass</code>
+ * will be obtained through the {@link Invocation} (if it's available), when this interceptor is invoked.
+ *
+ * @param interceptorClass The interceptor class
+ * @param lifecycleCallbackMethod The interceptor method
+ *
+ * @see LifecycleCallbackInterceptorMethodLazyInterceptor#getInterceptorInstance(Invocation)
+ */
+ public LifecycleCallbackInterceptorMethodLazyInterceptor(Class<?> interceptorClass, Method lifecycleCallbackMethod)
+ {
+ if (interceptorClass == null || lifecycleCallbackMethod == null)
+ {
+ throw new IllegalArgumentException("Either interceptor class " + interceptorClass + " or interceptor method "
+ + lifecycleCallbackMethod + " is null. Both are required to be non-null");
+ }
+
+ this.lifecycleInterceptorClass = interceptorClass;
+ this.lifecycleMethod = lifecycleCallbackMethod;
+ }
+
+ /**
+ * @see Interceptor#getName()
+ */
+ public String getName()
+ {
+ return this.getClass().getSimpleName();
+ }
+
+ /**
+ * Invokes the lifecycle callback method on the interceptor.
+ * The interceptor instance is obtained from the <code>invocation</code>, if available
+ *
+ * @see #getInterceptorInstance(Invocation)
+ */
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ InvocationContext ctx = InvocationContextInterceptor.getInvocationContext(invocation);
+
+ Object args[] =
+ {ctx};
+ boolean accessible = this.lifecycleMethod.isAccessible();
+ this.lifecycleMethod.setAccessible(true);
+ try
+ {
+ Object interceptorInstance = this.getInterceptorInstance(invocation);
+ return this.lifecycleMethod.invoke(interceptorInstance, args);
+ }
+ finally
+ {
+ this.lifecycleMethod.setAccessible(accessible);
+ }
+
+ }
+
+ /**
+ * Returns the lifecycle callback interceptor instance, from the <code>invocation</code>, if available.
+ *
+ *
+ *
+ * @param invocation AOP invocation
+ * @return Returns the lifecycle callback interceptor instance
+ *
+ * @throws IllegalStateException if the interceptor instance cannot be
+ * obtained through <code>invocation</code>
+ */
+ protected Object getInterceptorInstance(final Invocation invocation)
+ {
+
+ // check if the invocation is capable of return the bean context
+ // and ultimately the interceptor instance
+ if (invocation instanceof LifecycleMethodInterceptorsInvocation)
+ {
+ LifecycleMethodInterceptorsInvocation lifecycleMethodInvocation = (LifecycleMethodInterceptorsInvocation) invocation;
+ BeanContext<?> beanContext = lifecycleMethodInvocation.getBeanContext();
+ return beanContext.getInterceptor(this.lifecycleInterceptorClass);
+ }
+ throw new IllegalStateException("Interceptor instance unavailable for invocation " + invocation);
+ }
+
+}
Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbacks.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbacks.java 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/LifecycleCallbacks.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -32,6 +32,7 @@
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
+import javax.interceptor.InvocationContext;
import org.jboss.aop.Advisor;
import org.jboss.aop.AspectManager;
@@ -54,6 +55,18 @@
{
private static final Logger log = Logger.getLogger(LifecycleCallbacks.class);
+ /**
+ *
+ * @param advisor
+ * @param lifecycleInterceptorClasses
+ * @param component
+ * @param lifecycleAnnotationType
+ * @return
+ * @throws Exception
+ *
+ * @deprecated Use {@link #createLifecycleCallbackInterceptors(Advisor, List, Class)} instead
+ */
+ @Deprecated
public static Interceptor[] createLifecycleCallbackInterceptors(Advisor advisor, List<Class<?>> lifecycleInterceptorClasses, BeanContext<?> component, Class<? extends Annotation> lifecycleAnnotationType) throws Exception
{
List<Interceptor> interceptors = new ArrayList<Interceptor>();
@@ -149,4 +162,96 @@
return "domain '" + ((Domain) manager).getDomainName() + "'";
return manager.toString();
}
+
+
+ /**
+ * Creates an AOP interceptor chain for the lifecycle represented by
+ * the <code>lifecycleAnnotationType</code>.
+ *
+ * Internally, the AOP interceptor chain consists of the LifecycleCallback AOP stack
+ * interceptors, the javax.interceptor.Interceptor(s) and the lifecycle methods on the bean
+ * implementation class
+ *
+ * @param advisor The bean class advisor
+ * @param lifecycleInterceptorClasses The lifecycle interceptor classes associated with the bean
+ * @param lifecycleAnnotationType The lifecycle annotation (ex: @PostConstruct, @PrePassivate and
+ * other similar lifecycle types).
+ * @return Returns an empty array if there are no interceptors corresponding to the bean for
+ * the <code>lifecycleAnnotationType</code>. Else returns the applicable interceptors
+ */
+ public static Interceptor[] createLifecycleCallbackInterceptors(Advisor advisor, List<Class<?>> lifecycleInterceptorClasses, Class<? extends Annotation> lifecycleAnnotationType)
+ {
+ List<Interceptor> interceptors = new ArrayList<Interceptor>();
+
+ AdviceStack stack = advisor.getManager().getAdviceStack("LifecycleCallbackStack");
+ if(stack == null)
+ {
+ log.warn("EJBTHREE-1480: LifecycleCallbackStack has not been defined for " + toString(advisor.getManager()));
+ interceptors.add(new CurrentInvocationInterceptor());
+ Interceptor invocationContextInterceptor;
+ try
+ {
+ invocationContextInterceptor = PerVmAdvice.generateInterceptor(null, new InvocationContextInterceptor(), "setup");
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Could not generate invocation context interceptor", e);
+ }
+ interceptors.add(invocationContextInterceptor);
+ }
+ else
+ {
+ interceptors.addAll(Arrays.asList(stack.createInterceptors(advisor, null)));
+ }
+
+ // 12.7 footnote 57: ignore method level interceptors
+ // The lifecycle callbacks on the interceptors must be invoked in order
+ for(Class<?> interceptorClass : lifecycleInterceptorClasses)
+ {
+ ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor);
+ HashSet<Class<?>> classes = null;
+ // Get all public/private/protected/package access methods of signature:
+ // void <MethodName> (InvocationContext)
+ Method[] possibleLifecycleInterceptorMethods = ClassHelper.getMethods(interceptorClass, void.class,new Class<?>[] {InvocationContext.class});
+ for(Method interceptorMethod : possibleLifecycleInterceptorMethods)
+ {
+ // Now check if the lifecycle annotation is present
+ if(interceptorAdvisor.isAnnotationPresent(interceptorClass, interceptorMethod, lifecycleAnnotationType)) //For Xml this returns true sometimes
+ {
+ // And finally consider it only if it's not overriden
+ if (!ClassHelper.isOverridden(interceptorClass, interceptorMethod))
+ {
+ classes = checkClass(classes, interceptorMethod, advisor, lifecycleAnnotationType);
+ interceptors.add(new LifecycleCallbackInterceptorMethodLazyInterceptor(interceptorClass, interceptorMethod));
+ }
+ }
+
+ }
+
+ }
+
+ // Bean lifecycle callbacks
+ Class<?> beanClass = advisor.getClazz();
+ HashSet<Class<?>> classes = null;
+ // Get all public/private/protected/package access methods of signature:
+ // void <MethodName> ()
+ Method[] possibleLifecycleMethods = ClassHelper.getMethods(beanClass, void.class, new Class<?>[] {});
+ for(Method beanMethod : possibleLifecycleMethods)
+ {
+ // Now check if the method is marked with a lifecycle annotation
+ if(advisor.hasAnnotation(beanMethod, lifecycleAnnotationType))
+ {
+ // And finally consider it only if it's not overriden
+ if (!ClassHelper.isOverridden(beanClass, beanMethod))
+ {
+ classes = checkClass(classes, beanMethod, advisor, lifecycleAnnotationType);
+ interceptors.add(new LifecycleCallbackBeanMethodInterceptor(beanMethod));
+
+ }
+ }
+
+ }
+
+ return interceptors.toArray(new Interceptor[0]);
+ }
}
Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/AbstractContainer.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/AbstractContainer.java 2009-09-04 07:24:29 UTC (rev 93196)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/AbstractContainer.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -21,19 +21,30 @@
*/
package org.jboss.ejb3.interceptors.container;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
+
import org.jboss.aop.Advisor;
import org.jboss.aop.AspectManager;
import org.jboss.aop.Domain;
import org.jboss.aop.DomainDefinition;
import org.jboss.aop.MethodInfo;
+import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.annotation.AnnotationRepository;
import org.jboss.aop.util.MethodHashing;
import org.jboss.ejb3.interceptors.InterceptorFactoryRef;
import org.jboss.ejb3.interceptors.annotation.AnnotationAdvisor;
import org.jboss.ejb3.interceptors.annotation.AnnotationAdvisorSupport;
+import org.jboss.ejb3.interceptors.aop.LifecycleCallbacks;
import org.jboss.ejb3.interceptors.lang.ClassHelper;
import org.jboss.ejb3.interceptors.registry.InterceptorRegistry;
import org.jboss.logging.Logger;
@@ -60,6 +71,13 @@
private BeanContextFactory<T, C> beanContextFactory;
/**
+ * Maintains a array of interceptors applicable to this bean context
+ * for each of the lifecycle callbacks
+ */
+ protected Map<Class<? extends Annotation>, Interceptor[]> lifecycleCallbackInterceptors = new HashMap<Class<? extends Annotation>, Interceptor[]>();
+
+
+ /**
* For a completely customized startup.
*
* Note that before construction ends advisor must be set!
@@ -217,6 +235,75 @@
}
/**
+ * Invokes the lifecycle callback(s) represented by the <code>callbackAnnotationClass</code>
+ * through (cached) AOP interceptor chain.
+ *
+ * Internally, the AOP interceptor chain consists of the LifecycleCallback AOP stack
+ * interceptors, the javax.interceptor.Interceptor(s) and the lifecycle methods on the bean
+ * implementation class
+ *
+ * @see AbstractContainer#getLifecycleInterceptors(Class) for more details.
+ *
+ * @param beanContext The bean context
+ * @param callbackAnnotationClass The lifecycle callback (ex: @PostConstruct, @PrePassivate etc...)
+ */
+ public void invokeCallback(BeanContext<?> beanContext, Class<? extends Annotation> callbackAnnotationClass)
+ {
+ try
+ {
+ Interceptor interceptors[] = this.getLifecycleInterceptors(callbackAnnotationClass);
+ LifecycleMethodInterceptorsInvocation invocation = new LifecycleMethodInterceptorsInvocation(beanContext,
+ interceptors);
+ invocation.setAdvisor(this.getAdvisor());
+ invocation.invokeNext();
+ }
+ catch (Throwable t)
+ {
+ throw new RuntimeException(t);
+ }
+ }
+
+ /**
+ * Returns the interceptor instances (which is a combination of our internal
+ * AOP interceptors and bean developer defined {@link javax.interceptor.Interceptors}),
+ * corresponding to the <code>lifecycleCallbackAnnotation</code>.
+ *
+ * Internally caches the interceptor instances corresponding to each of the lifecycle
+ * callbacks, for this bean context
+ *
+ * @param lifecycleCallbackAnnotation Lifecycle callback annotations like {@link PrePassivate},
+ * {@link PostActivate}, {@link PreDestroy}, {@link PostConstruct}
+ *
+ * @return Returns an empty array if there are no interceptor instances associated with this
+ * bean context, for the <code>lifecycleCallbackAnnotation</code>. Else, returns the
+ * array of interceptors applicable to this bean context for the
+ * <code>lifecycleCallbackAnnotation</code>
+ */
+ protected Interceptor[] getLifecycleInterceptors(Class<? extends Annotation> lifecycleCallbackAnnotation)
+ {
+ Interceptor[] interceptors = this.lifecycleCallbackInterceptors.get(lifecycleCallbackAnnotation);
+ // If null then we haven't yet initialized the lifecycle callback interceptors, since
+ // we intentionally do a lazy initialization per lifecycle callback. The initialization
+ // happens only once per bean for each lifecycle callback annotation type
+ if (interceptors == null)
+ {
+ List<Class<?>> lifecycleInterceptorClasses = this.getInterceptorRegistry().getLifecycleInterceptorClasses();
+ // create the interceptor chain
+ interceptors = LifecycleCallbacks.createLifecycleCallbackInterceptors(this.getAdvisor(),
+ lifecycleInterceptorClasses, lifecycleCallbackAnnotation);
+ if (interceptors == null)
+ {
+ // No interceptors available, so create an empty chain and maintain in the map,
+ // to avoid trying to init again the next time this method
+ // is called for this specific lifecycle callback
+ interceptors = new Interceptor[0];
+ }
+ this.lifecycleCallbackInterceptors.put(lifecycleCallbackAnnotation, interceptors);
+ }
+ return this.lifecycleCallbackInterceptors.get(lifecycleCallbackAnnotation);
+ }
+
+ /**
* Call a method upon a target object with all interceptors in place.
*
* @param target the target to invoke upon
Added: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/LifecycleMethodInterceptorsInvocation.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/LifecycleMethodInterceptorsInvocation.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/LifecycleMethodInterceptorsInvocation.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,120 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.container;
+
+import java.lang.reflect.Constructor;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.ConstructionInvocation;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.ejb3.interceptors.aop.LifecycleCallbackBeanMethodInterceptor;
+import org.jboss.ejb3.interceptors.aop.LifecycleCallbackInterceptorMethodInterceptor;
+
+/**
+ * LifecycleMethodInterceptorsInvocation
+ *
+ * An {@link Invocation} which is aware of the bean context.
+ * The {@link LifecycleMethodInterceptorsInvocation} is used for
+ * creating an AOP invocation for lifecycle callback methods defined
+ * either on the bean class or on the interceptor classes associated
+ * with the bean. The end target of the {@link LifecycleMethodInterceptorsInvocation},
+ * is always a bean instance. But the target (bean instance) is *never* invoked at the
+ * end of the interceptor chain. This is because the lifecycle method(s)
+ * may or may not be present on the bean class. If there are any lifecycle methods
+ * present on the bean class, then its the responsibility of the
+ * code using this {@link LifecycleMethodInterceptorsInvocation} to create
+ * an appropriate AOP interceptor (ex: {@link LifecycleCallbackBeanMethodInterceptor}
+ * and making it available in the interceptor chain that is passed to the constructor
+ * of this class
+ *
+ * @see LifecycleCallbackBeanMethodInterceptor
+ * @see LifecycleCallbackInterceptorMethodInterceptor
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class LifecycleMethodInterceptorsInvocation extends ConstructionInvocation
+{
+
+ /**
+ * Bean context
+ */
+ protected BeanContext<?> beanContext;
+
+ /**
+ * Constructor
+ *
+ * @param beanContext The bean context. Cannot be null
+ * @param interceptors The interceptors
+ * @throws IllegalArgumentException if <code>beanContext</code> is null
+ *
+ */
+ public LifecycleMethodInterceptorsInvocation(BeanContext<?> beanContext, Interceptor[] interceptors)
+ {
+ super(interceptors, null);
+
+ try
+ {
+ Object beanInstance = beanContext.getInstance();
+ Constructor<?> constructor = beanInstance.getClass().getConstructor();
+ // set the constructor and the target objects
+ this.setConstructor(constructor);
+ this.targetObject = beanInstance;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ this.beanContext = beanContext;
+ }
+
+ /**
+ * Returns the bean context associated with this invocation
+ * @return
+ */
+ public BeanContext<?> getBeanContext()
+ {
+ return this.beanContext;
+ }
+
+ @Override
+ public Object invokeTarget() throws Throwable
+ {
+ // we don't invoke on the bean target. See javadoc of this class
+ return null;
+ }
+
+ /**
+ * Throws exception since we do not allow setting the target object
+ * explicitly
+ *
+ * Don't allow set/overriding the target object. The target is inferred
+ * from the bean context passed to the constructor of this class
+ */
+ @Override
+ public void setTargetObject(Object targetObject)
+ {
+ throw new RuntimeException("Target should not be explicitly set on " + this.getClass()
+ + " - target will be infered from bean context");
+ }
+}
Added: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/DummyBeanContext.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/DummyBeanContext.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/DummyBeanContext.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,83 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.test.container;
+
+import org.jboss.ejb3.interceptors.container.BeanContext;
+import org.jboss.ejb3.interceptors.test.container.unit.LifecycleMethodInterceptorsInvocationTestCase;
+
+/**
+ * DummyBeanContext
+ *
+ * Dummy beancontext used in {@link LifecycleMethodInterceptorsInvocationTestCase}.
+ * Does not do anything useful
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class DummyBeanContext<T> implements BeanContext<T>
+{
+
+ /**
+ * Instance
+ */
+ private T instance;
+
+ /**
+ * Returns the instance
+ */
+ public T getInstance()
+ {
+ return this.instance;
+ }
+
+ /**
+ * Creates an returns a new instance of the <code>interceptorClasss</code>.
+ *
+ * Note: The <code>interceptorClass</code> is expected to have a default
+ * constructor.
+ */
+ public Object getInterceptor(Class<?> interceptorClass) throws IllegalArgumentException
+ {
+ try
+ {
+ return interceptorClass.newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Sets the bean instance
+ * @param beanInstance
+ */
+ public void setBeanInstance(T beanInstance)
+ {
+ this.instance = beanInstance;
+ }
+
+}
Added: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/FirstInterceptor.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/FirstInterceptor.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/FirstInterceptor.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,59 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.test.container;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.ejb3.interceptors.test.container.unit.LifecycleMethodInterceptorsInvocationTestCase;
+
+/**
+ * FirstInterceptor
+ *
+ * Simple {@link Interceptor} used in the {@link LifecycleMethodInterceptorsInvocationTestCase}
+ * Upon invocation, adds itself to the {@link InterceptorInvocationOrderTracker}'s list of
+ * invoked interceptors
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class FirstInterceptor implements Interceptor
+{
+
+ /**
+ * @see Interceptor#getName()
+ */
+ public String getName()
+ {
+ return this.getClass().getSimpleName();
+ }
+
+ /**
+ * Upon invocation, adds itself to the {@link InterceptorInvocationOrderTracker}'s list of
+ * invoked interceptors
+ */
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ InterceptorInvocationOrderTracker.getInstance().setInterceptorInvoked(this);
+ return invocation.invokeNext();
+ }
+
+}
Added: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/InterceptorInvocationOrderTracker.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/InterceptorInvocationOrderTracker.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/InterceptorInvocationOrderTracker.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,83 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.test.container;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.ejb3.interceptors.test.container.unit.LifecycleMethodInterceptorsInvocationTestCase;
+
+/**
+ * InterceptorInvocationOrderTracker
+ *
+ * Used in {@link LifecycleMethodInterceptorsInvocationTestCase} to maintain/track the order in which
+ * the interceptors are being invoked through the invocation.
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class InterceptorInvocationOrderTracker
+{
+
+ List<Interceptor> invokedInterceptors = new ArrayList<Interceptor>();
+
+ /**
+ * Singleton instance
+ */
+ private static InterceptorInvocationOrderTracker tracker;
+
+ /**
+ * Returns {@link InterceptorInvocationOrderTracker}
+ * @return
+ */
+ public static synchronized InterceptorInvocationOrderTracker getInstance()
+ {
+ if (tracker == null)
+ {
+ tracker = new InterceptorInvocationOrderTracker();
+ }
+ return tracker;
+ }
+
+ /**
+ * Adds this interceptor to the list of interceptors that were
+ * invoked
+ *
+ * @param interceptor The interceptor which was invoked
+ */
+ public void setInterceptorInvoked(Interceptor interceptor)
+ {
+ this.invokedInterceptors.add(interceptor);
+ }
+
+ /**
+ * Returns the invoked interceptors in the same order as they were invoked
+ *
+ * @return
+ */
+ public List<Interceptor> getInvokedInterceptors()
+ {
+ return this.invokedInterceptors;
+ }
+
+}
Added: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/SecondInterceptor.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/SecondInterceptor.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/SecondInterceptor.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,60 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.test.container;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.ejb3.interceptors.test.container.unit.LifecycleMethodInterceptorsInvocationTestCase;
+
+/**
+ * SecondInterceptor
+ *
+ * Simple {@link Interceptor} used in the {@link LifecycleMethodInterceptorsInvocationTestCase}
+ * Upon invocation, adds itself to the {@link InterceptorInvocationOrderTracker}'s list of
+ * invoked interceptors
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class SecondInterceptor implements Interceptor
+{
+
+ /**
+ *
+ * @see org.jboss.aop.advice.Interceptor#getName()
+ */
+ public String getName()
+ {
+ return this.getClass().getName();
+ }
+
+ /**
+ * Upon invocation, adds itself to the {@link InterceptorInvocationOrderTracker}'s list of
+ * invoked interceptors
+ */
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ InterceptorInvocationOrderTracker.getInstance().setInterceptorInvoked(this);
+ return invocation.invokeNext();
+ }
+
+}
Added: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/unit/LifecycleMethodInterceptorsInvocationTestCase.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/unit/LifecycleMethodInterceptorsInvocationTestCase.java (rev 0)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/interceptors/test/container/unit/LifecycleMethodInterceptorsInvocationTestCase.java 2009-09-04 08:51:14 UTC (rev 93197)
@@ -0,0 +1,108 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.interceptors.test.container.unit;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.ejb3.interceptors.container.BeanContext;
+import org.jboss.ejb3.interceptors.container.LifecycleMethodInterceptorsInvocation;
+import org.jboss.ejb3.interceptors.test.container.DummyBeanContext;
+import org.jboss.ejb3.interceptors.test.container.FirstInterceptor;
+import org.jboss.ejb3.interceptors.test.container.InterceptorInvocationOrderTracker;
+import org.jboss.ejb3.interceptors.test.container.SecondInterceptor;
+
+/**
+ * LifecycleMethodInterceptorsInvocationTestCase
+ *
+ * Tests {@link LifecycleMethodInterceptorsInvocation}
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class LifecycleMethodInterceptorsInvocationTestCase extends TestCase
+{
+
+ /**
+ * Test that the {@link LifecycleMethodInterceptorsInvocation} invokes
+ * the interceptors in the correct order
+ *
+ * @throws Throwable
+ */
+ public void testInterceptorInvocationOrder() throws Throwable
+ {
+ Interceptor[] interceptors = new Interceptor[2];
+ Interceptor firstInterceptor = new FirstInterceptor();
+ Interceptor secondInterceptor = new SecondInterceptor();
+
+ interceptors[0] = firstInterceptor;
+ interceptors[1] = secondInterceptor;
+
+ DummyBeanContext<Object> dummyBeanContext = new DummyBeanContext<Object>();
+ dummyBeanContext.setBeanInstance(new Object());
+ // Create an invocation with the beancontext and the interceptors
+ LifecycleMethodInterceptorsInvocation invocation = new LifecycleMethodInterceptorsInvocation(dummyBeanContext,
+ interceptors);
+ // invoke
+ Object result = invocation.invokeNext();
+
+ // now check the number of interceptors invoked and their order
+ assertNull(LifecycleMethodInterceptorsInvocation.class.getName() + " invocation returned a non-null result",
+ result);
+ List<Interceptor> invokedInterceptors = InterceptorInvocationOrderTracker.getInstance().getInvokedInterceptors();
+
+ assertNotNull("No interceptors were invoked", invokedInterceptors);
+ assertEquals("Unexpected number of interceptors invoked during invocation through "
+ + LifecycleMethodInterceptorsInvocation.class.getSimpleName(), 2, invokedInterceptors.size());
+
+ // check the order
+ assertEquals("First interceptor not invoked in the right order during invocation through "
+ + LifecycleMethodInterceptorsInvocation.class.getSimpleName(), firstInterceptor, invokedInterceptors.get(0));
+
+ assertEquals("Second interceptor not invoked in the right order during invocation through "
+ + LifecycleMethodInterceptorsInvocation.class.getSimpleName(), secondInterceptor, invokedInterceptors
+ .get(1));
+
+ }
+
+ /**
+ * Test that the "target" of a {@link LifecycleMethodInterceptorsInvocation} is inferred
+ * from the {@link BeanContext#getInstance()}
+ *
+ * @throws Throwable
+ */
+ public void testTargetObject() throws Throwable
+ {
+ DummyBeanContext<Object> dummyBeanContext = new DummyBeanContext<Object>();
+ Object beanInstance = new Object();
+ dummyBeanContext.setBeanInstance(beanInstance);
+ // Create a invocation out of the beancontext
+ LifecycleMethodInterceptorsInvocation invocation = new LifecycleMethodInterceptorsInvocation(dummyBeanContext,
+ new Interceptor[0]);
+ // now ensure that the target is the same as the bean instance (obtained through beancontext)
+ assertEquals("Unexpected target object in LifecycleMethodInterceptorsInvocation", beanInstance, invocation
+ .getTargetObject());
+
+ }
+}
More information about the jboss-cvs-commits
mailing list