[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