[jboss-cvs] JBossAS SVN: r71842 - in projects/ejb3/trunk/interceptors/src: main/java/org/jboss/ejb3/interceptors/container and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Apr 9 10:36:44 EDT 2008


Author: wolfc
Date: 2008-04-09 10:36:44 -0400 (Wed, 09 Apr 2008)
New Revision: 71842

Added:
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContextFactory.java
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/SimpleBeanContextFactory.java
Modified:
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/EJB3InterceptorInterceptor.java
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/ExtendedAdvisorHelper.java
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InterceptorsFactory.java
   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/BeanContext.java
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/DummyBeanContext.java
   projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java
   projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/DirectMethodInterceptor.java
   projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/unit/DirectTestCase.java
   projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/StatefulInterceptor.java
   projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/unit/InterceptorInstancesTestCase.java
Log:
EJBTHREE-1246: created BeanContextFactory

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/EJB3InterceptorInterceptor.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/EJB3InterceptorInterceptor.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/EJB3InterceptorInterceptor.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -21,6 +21,12 @@
  */
 package org.jboss.ejb3.interceptors.aop;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import javax.interceptor.InvocationContext;
+
 import org.jboss.aop.advice.Interceptor;
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.ejb3.interceptors.container.ContainerMethodInvocation;
@@ -31,16 +37,26 @@
  */
 public class EJB3InterceptorInterceptor implements Interceptor
 {
+   private static final Class<?> PARAMETER_TYPES[] = { InvocationContext.class };
+   
    private Class<?> interceptorClass;
+   private Method method;
    
    /**
     * @param interceptorClass
+    * @param businessMethodInterceptorMethod    a business method interceptor on the spec interceptor (@AroundInvoke)
     */
-   EJB3InterceptorInterceptor(Class<?> interceptorClass)
+   public EJB3InterceptorInterceptor(Class<?> interceptorClass, Method businessMethodInterceptorMethod)
    {
       assert interceptorClass != null : "interceptorClass is null";
+      assert businessMethodInterceptorMethod != null : "businessMethodInterceptorMethod is null";
+      assert interceptorClass.equals(businessMethodInterceptorMethod.getDeclaringClass()) : businessMethodInterceptorMethod + " does not belong to " + interceptorClass;
+      assert businessMethodInterceptorMethod.getReturnType() == Object.class : "return type must be Object " + businessMethodInterceptorMethod;
+      assert Arrays.equals(businessMethodInterceptorMethod.getParameterTypes(), PARAMETER_TYPES) : "wrong parameter signature";
+      // Ignore throw clause
       
       this.interceptorClass = interceptorClass;
+      this.method = businessMethodInterceptorMethod;
    }
 
    public String getName()
@@ -50,17 +66,38 @@
 
    public Object invoke(Invocation invocation) throws Throwable
    {
-      Object instances[] = ContainerMethodInvocation.getContainerMethodInvocation(invocation).getBeanContext().getInterceptors();
-      for(Object instance : instances)
+      // TODO: speed up
+      Object interceptors[] = ContainerMethodInvocation.getContainerMethodInvocation(invocation).getBeanContext().getInterceptors();
+      for(Object interceptor : interceptors)
       {
-         // FIXME
-         BusinessMethodInterceptorMethodInterceptor interceptor = (BusinessMethodInterceptorMethodInterceptor) instance;
-         if(interceptor.getRealClass().equals(interceptorClass))
-            return interceptor.invoke(invocation);
+         if(interceptor.getClass().equals(interceptorClass))
+            return invoke(interceptor, invocation);
       }
       //throw new IllegalStateException("Can't find an interceptor instance for " + interceptorClass + " among " + Arrays.toString(instances));
       // The business method interceptor method interceptor only exists when there is an aroundInvoke
       return invocation.invokeNext();
    }
 
+   private Object invoke(Object interceptor, final Invocation invocation) throws Throwable
+   {
+      InvocationContext ctx = InvocationContextInterceptor.getInvocationContext(invocation);
+      try
+      {
+         Object args[] = { ctx };
+         boolean accessible = method.isAccessible();
+         method.setAccessible(true);
+         try
+         {
+            return method.invoke(interceptor, args);
+         }
+         finally
+         {
+            method.setAccessible(accessible);
+         }
+      }
+      catch(InvocationTargetException e)
+      {
+         throw e.getCause();
+      }
+   }
 }

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/ExtendedAdvisorHelper.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/ExtendedAdvisorHelper.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/ExtendedAdvisorHelper.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -29,12 +29,20 @@
  * Comment
  *
  * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
+ * @version $Revision$
  */
 public class ExtendedAdvisorHelper
 {
    private static final Logger log = Logger.getLogger(ExtendedAdvisorHelper.class);
    
+   public static ExtendedAdvisor getExtendedAdvisor(Advisor advisor)
+   {
+      if(advisor instanceof ExtendedAdvisor)
+         return ExtendedAdvisor.class.cast(advisor);
+      
+      throw new RuntimeException("NYI");
+   }
+   
    public static ExtendedAdvisor getExtendedAdvisor(Advisor advisor, Object target)
    {
       if(advisor instanceof ExtendedAdvisor)

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InjectInterceptorsFactory.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -88,7 +88,14 @@
             List<Interceptor> interceptors = new ArrayList<Interceptor>();
             for(Class<?> interceptorClass : interceptorClasses)
             {
-               interceptors.add(new EJB3InterceptorInterceptor(interceptorClass));
+               ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor);
+               for(Method interceptorMethod : ClassHelper.getAllMethods(interceptorClass))
+               {
+                  if(interceptorAdvisor.isAnnotationPresent(interceptorClass, interceptorMethod, AroundInvoke.class))
+                  {
+                     interceptors.add(new EJB3InterceptorInterceptor(interceptorClass, interceptorMethod));
+                  }
+               }
             }
             Class<?> beanClass = advisor.getClazz();
             for(Method beanMethod : ClassHelper.getAllMethods(beanClass))
@@ -128,6 +135,13 @@
       {
          // postConstruct
          
+         if(advisor instanceof ManagedObjectAdvisor)
+         {
+            log.warn("EJBTHREE-1246: Do not use InjectInterceptorsFactory with a ManagedObjectAdvisor for lifecycle callbacks, should be done by the container");
+            // Note that the container delegates it to ejb3-callbacks or the MC bean factory
+            return new NopInterceptor();
+         }
+         
          List<Interceptor> interceptors = InterceptorsFactory.getLifeCycleInterceptors(instanceAdvisor, PostConstruct.class);
          
          log.debug("PostConstruct interceptors " + interceptors);

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InterceptorsFactory.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InterceptorsFactory.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/aop/InterceptorsFactory.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -44,6 +44,7 @@
 import org.jboss.ejb3.interceptors.InterceptorFactory;
 import org.jboss.ejb3.interceptors.InterceptorFactoryRef;
 import org.jboss.ejb3.interceptors.aop.annotation.DefaultInterceptors;
+import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor;
 import org.jboss.ejb3.interceptors.lang.ClassHelper;
 import org.jboss.logging.Logger;
 
@@ -112,6 +113,12 @@
    
    public Object createPerInstance(Advisor advisor, InstanceAdvisor instanceAdvisor)
    {
+      if(advisor instanceof ManagedObjectAdvisor)
+      {
+         log.warn("EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the container");
+         return new NopInterceptor();
+      }
+      
       try
       {
          log.debug("createPerInstance");

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	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/AbstractContainer.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -23,30 +23,17 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
 
-import javax.interceptor.AroundInvoke;
-
 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.advice.PerVmAdvice;
 import org.jboss.aop.annotation.AnnotationRepository;
-import org.jboss.aop.joinpoint.ConstructionInvocation;
 import org.jboss.aop.util.MethodHashing;
-import org.jboss.ejb3.interceptors.InterceptorFactory;
 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.BusinessMethodInterceptorMethodInterceptor;
-import org.jboss.ejb3.interceptors.aop.ExtendedAdvisor;
-import org.jboss.ejb3.interceptors.aop.ExtendedAdvisorHelper;
-import org.jboss.ejb3.interceptors.aop.InterceptorsFactory;
-import org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor;
 import org.jboss.ejb3.interceptors.lang.ClassHelper;
 import org.jboss.ejb3.interceptors.registry.InterceptorRegistry;
 import org.jboss.logging.Logger;
@@ -68,6 +55,10 @@
    
    private InterceptorRegistry interceptorRegistry;
    
+   //private Class<BeanContextFactory<T, C>> beanContextFactoryClass = SimpleBeanContextFactory.class;
+   private Class<? extends BeanContextFactory> beanContextFactoryClass = SimpleBeanContextFactory.class;
+   private BeanContextFactory<T, C> beanContextFactory;
+   
    /**
     * For a completely customized startup.
     * 
@@ -96,27 +87,21 @@
       {
          // TODO: ask the BeanFactory<BeanContext> for a new ctx
          
+         /*
          InterceptorFactoryRef interceptorFactoryRef = (InterceptorFactoryRef) advisor.resolveAnnotation(InterceptorFactoryRef.class);
          if(interceptorFactoryRef == null)
             throw new IllegalStateException("No InterceptorFactory specified on " + advisor.getName());
          log.debug("interceptor factory class = " + interceptorFactoryRef.value());
          InterceptorFactory interceptorFactory = interceptorFactoryRef.value().newInstance();
          
-         List<Interceptor> ejb3Interceptors = new ArrayList<Interceptor>();
+         List<Object> ejb3Interceptors = new ArrayList<Object>();
          for(Class<?> interceptorClass : getInterceptorRegistry().getInterceptorClasses())
          {
             Object interceptor = interceptorFactory.create(advisor, interceptorClass);
-            ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor, interceptor);
-            for(Method method : ClassHelper.getAllMethods(interceptorClass))
-            {
-               if(interceptorAdvisor.isAnnotationPresent(interceptorClass, method, AroundInvoke.class))
-               {
-                  ejb3Interceptors.add(new BusinessMethodInterceptorMethodInterceptor(interceptor, method));
-               }
-            }
+            ejb3Interceptors.add(interceptor);
          }
          
-         T targetObject = (T) advisor.invokeNew(initargs, idx);
+         T targetObject = getBeanClass().cast(advisor.invokeNew(initargs, idx));
          
          Interceptor interceptors[] = advisor.getConstructionInfos()[idx].getInterceptors();
          ConstructionInvocation invocation = new ConstructionInvocation(interceptors, constructor, initargs);
@@ -124,7 +109,9 @@
          invocation.setTargetObject(targetObject);
          invocation.invokeNext();
          
-         return new DummyBeanContext(targetObject, ejb3Interceptors);
+         return new DummyBeanContext<T>(targetObject, ejb3Interceptors);
+         */
+         return getBeanContextFactory().createBean();
       }
       catch(Throwable t)
       {
@@ -142,6 +129,7 @@
    
    protected void destroy(BeanContext<T> bean)
    {
+      /*
       try
       {
          // TODO: speed up
@@ -160,8 +148,39 @@
             throw (RuntimeException) t;
          throw new RuntimeException(t);
       }
+      */
+      getBeanContextFactory().destroyBean(bean);
    }
    
+   private BeanContextFactory<T, C> getBeanContextFactory()
+   {
+      if(beanContextFactory == null)
+      {
+         synchronized (this)
+         {
+            if(beanContextFactory == null)
+            {
+               if(beanContextFactoryClass == null)
+                  throw new IllegalStateException("beanContextFactoryClass has not been set");
+               try
+               {
+                  beanContextFactory = beanContextFactoryClass.newInstance();
+                  beanContextFactory.setContainer(this);
+               }
+               catch (InstantiationException e)
+               {
+                  throw new RuntimeException(e.getCause());
+               }
+               catch (IllegalAccessException e)
+               {
+                  throw new RuntimeException(e);
+               }
+            }
+         }
+      }
+      return beanContextFactory;
+   }
+   
    /**
     * Finalize construction of the abstract container by setting the advisor.
     * 
@@ -270,4 +289,9 @@
       Method method = ClassHelper.getMethod(target.getInstance().getClass(), methodName);
       return (R) invoke(target, method, args);
    }
+   
+   public void setBeanContextFactoryClass(Class<BeanContextFactory<T, C>> beanContextFactoryClass)
+   {
+      this.beanContextFactoryClass = beanContextFactoryClass;
+   }
 }

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContext.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContext.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContext.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -22,6 +22,9 @@
 package org.jboss.ejb3.interceptors.container;
 
 /**
+ * The intercepted component consisting of a bean instance and the interceptor
+ * instances.
+ * 
  * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
  * @version $Revision: $
  */

Added: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContextFactory.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContextFactory.java	                        (rev 0)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/BeanContextFactory.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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;
+
+/**
+ * A factory for bean contexts. After construction of the context the bean instance
+ * and interceptor instances have been injected and the post construct life cycle
+ * callback has been called.
+ * 
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public interface BeanContextFactory<T, C extends AbstractContainer<T, C>>
+{
+   BeanContext<T> createBean() throws Exception;
+   
+   void destroyBean(BeanContext<T> bean);
+   
+   void setContainer(AbstractContainer<T, C> container);
+}

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/DummyBeanContext.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/DummyBeanContext.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/DummyBeanContext.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -23,8 +23,6 @@
 
 import java.util.List;
 
-import org.jboss.aop.advice.Interceptor;
-
 /**
  * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
  * @version $Revision: $
@@ -39,7 +37,7 @@
       assert instance != null : "instance is null";
       assert interceptors != null : "interceptors is null";
       this.instance = instance;
-      this.interceptors = interceptors.toArray(new Interceptor[0]);
+      this.interceptors = interceptors.toArray(new Object[0]);
    }
    
    public T getInstance()

Added: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/SimpleBeanContextFactory.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/SimpleBeanContextFactory.java	                        (rev 0)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/container/SimpleBeanContextFactory.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -0,0 +1,163 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.ClassAdvisor;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.advice.PerVmAdvice;
+import org.jboss.aop.joinpoint.ConstructionInvocation;
+import org.jboss.ejb3.interceptors.InterceptorFactory;
+import org.jboss.ejb3.interceptors.InterceptorFactoryRef;
+import org.jboss.ejb3.interceptors.aop.ExtendedAdvisor;
+import org.jboss.ejb3.interceptors.aop.ExtendedAdvisorHelper;
+import org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor;
+import org.jboss.ejb3.interceptors.aop.LifecycleCallbackBeanMethodInterceptor;
+import org.jboss.ejb3.interceptors.aop.LifecycleCallbackInterceptorMethodInterceptor;
+import org.jboss.ejb3.interceptors.lang.ClassHelper;
+import org.jboss.logging.Logger;
+
+/**
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class SimpleBeanContextFactory<T, C extends AbstractContainer<T, C>> implements BeanContextFactory<T, C>
+{
+   private static final Logger log = Logger.getLogger(SimpleBeanContextFactory.class);
+   
+   private AbstractContainer<T, C> container;
+   
+   public BeanContext<T> createBean() throws Exception
+   {
+      try
+      {
+         ClassAdvisor advisor = container.getAdvisor();
+         InterceptorFactoryRef interceptorFactoryRef = (InterceptorFactoryRef) advisor.resolveAnnotation(InterceptorFactoryRef.class);
+         if(interceptorFactoryRef == null)
+            throw new IllegalStateException("No InterceptorFactory specified on " + advisor.getName());
+         log.debug("interceptor factory class = " + interceptorFactoryRef.value());
+         InterceptorFactory interceptorFactory = interceptorFactoryRef.value().newInstance();
+         
+         List<Object> ejb3Interceptors = new ArrayList<Object>();
+         for(Class<?> interceptorClass : container.getInterceptorRegistry().getInterceptorClasses())
+         {
+            Object interceptor = interceptorFactory.create(advisor, interceptorClass);
+            ejb3Interceptors.add(interceptor);
+         }
+         
+         Constructor<T> constructor = advisor.getClazz().getConstructor();
+         int idx = advisor.getConstructorIndex(constructor);
+         Object initargs[] = null;
+         T targetObject = container.getBeanClass().cast(advisor.invokeNew(initargs, idx));
+         
+         BeanContext<T> component = new DummyBeanContext<T>(targetObject, ejb3Interceptors);
+         
+         // Do lifecycle callbacks
+         Interceptor interceptors[] = createLifecycleInterceptors(component, PostConstruct.class);
+         
+         ConstructionInvocation invocation = new ConstructionInvocation(interceptors, constructor, initargs);
+         invocation.setAdvisor(advisor);
+         invocation.setTargetObject(targetObject);
+         invocation.invokeNext();
+         
+         return component;
+      }
+      catch(Error e)
+      {
+         throw e;
+      }
+      catch(Throwable t)
+      {
+         // TODO: decompose
+         throw new RuntimeException(t);
+      }
+   }
+
+   public void destroyBean(BeanContext<T> component)
+   {
+      try
+      {
+         Advisor advisor = container.getAdvisor();
+         Interceptor interceptors[] = createLifecycleInterceptors(component, PreDestroy.class);
+         
+         DestructionInvocation invocation = new DestructionInvocation(interceptors);
+         invocation.setAdvisor(advisor);
+         invocation.setTargetObject(component.getInstance());
+         invocation.invokeNext();
+      }
+      catch(Throwable t)
+      {
+         // TODO: disect
+         if(t instanceof RuntimeException)
+            throw (RuntimeException) t;
+         throw new RuntimeException(t);
+      }
+   }
+   
+   private Interceptor[] createLifecycleInterceptors(BeanContext<T> component, Class<? extends Annotation> lifecycleAnnotationType) throws Exception
+   {
+      List<Class<?>> lifecycleInterceptorClasses = container.getInterceptorRegistry().getLifecycleInterceptorClasses();
+      Advisor advisor = container.getAdvisor();
+      List<Interceptor> interceptors = new ArrayList<Interceptor>();
+      Object ejb3Interceptors[] = component.getInterceptors();
+      for(Object interceptor : ejb3Interceptors)
+      {
+         // 12.7 footnote 57: ignore method level interceptors
+         Class<?> interceptorClass = interceptor.getClass();
+         if(!lifecycleInterceptorClasses.contains(interceptorClass))
+            continue;
+         ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor, interceptor);
+         for(Method interceptorMethod : ClassHelper.getAllMethods(interceptorClass))
+         {
+            if(interceptorAdvisor.isAnnotationPresent(interceptorClass, interceptorMethod, lifecycleAnnotationType))
+            {
+               interceptors.add(new LifecycleCallbackInterceptorMethodInterceptor(interceptor, interceptorMethod));
+            }
+         }
+      }
+      Class<?> beanClass = container.getBeanClass();
+      for(Method beanMethod : ClassHelper.getAllMethods(beanClass))
+      {
+         if(advisor.hasAnnotation(beanMethod, lifecycleAnnotationType))
+         {
+            interceptors.add(new LifecycleCallbackBeanMethodInterceptor(beanMethod));
+         }
+      }
+      interceptors.add(0, PerVmAdvice.generateInterceptor(null, new InvocationContextInterceptor(), "setup"));
+      
+      return interceptors.toArray(new Interceptor[0]);
+   }
+   
+   public void setContainer(AbstractContainer<T, C> container)
+   {
+      this.container = container;
+   }
+}

Modified: projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/main/java/org/jboss/ejb3/interceptors/registry/InterceptorRegistry.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -51,6 +51,13 @@
    
    private List<Class<?>> interceptorClasses = new ArrayList<Class<?>>();
    private List<Class<?>> readOnlyInterceptorClasses = Collections.unmodifiableList(interceptorClasses);
+   
+   /**
+    * Interceptors who are interested in lifecycle callbacks.
+    */
+   private List<Class<?>> lifecycleInterceptorClasses = new ArrayList<Class<?>>();
+   private List<Class<?>> readOnlyLifecycleInterceptorClasses = Collections.unmodifiableList(lifecycleInterceptorClasses);
+   
    private Map<Method, List<Class<?>>> applicableInterceptorClasses = new HashMap<Method, List<Class<?>>>();
    
    public InterceptorRegistry(Advisor advisor)
@@ -74,6 +81,15 @@
       return readOnlyInterceptorClasses;
    }
    
+   /**
+    * All default and class interceptors (not method interceptors (12.7 footnote 57)
+    * @return
+    */
+   public List<Class<?>> getLifecycleInterceptorClasses()
+   {
+      return readOnlyLifecycleInterceptorClasses;
+   }
+   
    private void initialize()
    {
       DefaultInterceptors defaultInterceptorsAnnotation = (DefaultInterceptors) advisor.resolveAnnotation(DefaultInterceptors.class);
@@ -85,6 +101,7 @@
       }
       log.debug("Found default interceptors " + defaultInterceptorClasses);
       interceptorClasses.addAll(defaultInterceptorClasses);
+      lifecycleInterceptorClasses.addAll(defaultInterceptorClasses);
       
       Interceptors interceptorsAnnotation = (Interceptors) advisor.resolveAnnotation(Interceptors.class);
       List<Class<?>> classInterceptorClasses = new ArrayList<Class<?>>();
@@ -95,6 +112,8 @@
             classInterceptorClasses.add(classInterceptorClass);
             if(!interceptorClasses.contains(classInterceptorClass))
                interceptorClasses.add(classInterceptorClass);
+            if(!lifecycleInterceptorClasses.contains(classInterceptorClass))
+               lifecycleInterceptorClasses.add(classInterceptorClass);
          }
       }
       log.debug("Found class interceptors " + classInterceptorClasses);

Modified: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/DirectMethodInterceptor.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/DirectMethodInterceptor.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/DirectMethodInterceptor.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -31,7 +31,7 @@
  * To be put on a method.
  *
  * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
+ * @version $Revision$
  */
 public class DirectMethodInterceptor
 {
@@ -44,6 +44,7 @@
    {
       log.info("postConstruct");
       postConstructs++;
+      ctx.proceed();
    }
    
    @AroundInvoke

Modified: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/unit/DirectTestCase.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/unit/DirectTestCase.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/direct/unit/DirectTestCase.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -102,7 +102,7 @@
       assertEquals("intercept didn't invoke DirectInterceptor.aroundInvoke", 3, DirectInterceptor.aroundInvokes);
       assertEquals("DirectInterceptor postConstruct must have been called once", 1, DirectInterceptor.postConstructs);
       // 12.7 footnote 57
-      assertEquals("DirectMethodInterceptor.postConstruct must not have been called", 0, DirectMethodInterceptor.postConstructs);
+      assertEquals("DirectMethodInterceptor.postConstruct must not have been called (12.7 footnote 57)", 0, DirectMethodInterceptor.postConstructs);
       
       //((Destructable) bean)._preDestroy();
       bean = null;

Modified: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/StatefulInterceptor.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/StatefulInterceptor.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/StatefulInterceptor.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -23,6 +23,7 @@
 
 import java.lang.reflect.Method;
 
+import javax.annotation.PostConstruct;
 import javax.interceptor.AroundInvoke;
 import javax.interceptor.InvocationContext;
 
@@ -35,6 +36,8 @@
  */
 public class StatefulInterceptor
 {
+   public static int postConstructs = 0;
+   private boolean constructed = false;
    private int state;
    
    @AroundInvoke
@@ -58,6 +61,17 @@
       return state;
    }
 
+   @PostConstruct
+   public void postConstruct(InvocationContext ctx) throws Exception
+   {
+      // Make sure postConstruct only gets called once (else it will probably be called on the wrong instance)
+      if(constructed)
+         throw new IllegalStateException(this + " is already constructed");
+      constructed = true;
+      
+      postConstructs++;
+   }
+   
    private void setState(int state)
    {
       this.state = state;

Modified: projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/unit/InterceptorInstancesTestCase.java
===================================================================
--- projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/unit/InterceptorInstancesTestCase.java	2008-04-09 14:33:44 UTC (rev 71841)
+++ projects/ejb3/trunk/interceptors/src/test/java/org/jboss/ejb3/test/interceptors/instances/unit/InterceptorInstancesTestCase.java	2008-04-09 14:36:44 UTC (rev 71842)
@@ -28,6 +28,7 @@
 import org.jboss.aop.AspectXmlLoader;
 import org.jboss.ejb3.interceptors.proxy.ProxyContainer;
 import org.jboss.ejb3.test.interceptors.instances.SimpleBean;
+import org.jboss.ejb3.test.interceptors.instances.StatefulInterceptor;
 import org.jboss.ejb3.test.interceptors.instances.StatefulInterceptorInterface;
 import org.jboss.logging.Logger;
 
@@ -56,6 +57,8 @@
       
       ProxyContainer<SimpleBean> container = new ProxyContainer<SimpleBean>("InterceptorInstancesTestCase", "InterceptorContainer", SimpleBean.class);
       
+      assertEquals(0, StatefulInterceptor.postConstructs);
+      
       StatefulInterceptorInterface bean1 = container.constructProxy(new Class[] { StatefulInterceptorInterface.class });
       StatefulInterceptorInterface bean2 = container.constructProxy(new Class[] { StatefulInterceptorInterface.class });
       
@@ -64,5 +67,7 @@
       
       assertEquals(1, bean1.getState());
       assertEquals(2, bean2.getState());
+      
+      assertEquals(2, StatefulInterceptor.postConstructs);
    }
 }




More information about the jboss-cvs-commits mailing list