You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2013/01/16 22:22:52 UTC

svn commit: r1434411 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/component/creation/ main/java/org/apache/webbeans/intercept/ main/java/org/apache/webbeans/portable/ test/java/org/apache/webbeans/test/unittests/intercept/

Author: struberg
Date: Wed Jan 16 21:22:52 2013
New Revision: 1434411

URL: http://svn.apache.org/viewvc?rev=1434411&view=rev
Log:
OWB-344 implement self-interception

Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/InterceptorBeanBuilder.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/ManagedBeanBuilder.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/SelfInterceptorBeanBuilder.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolutionService.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/InjectionTargetImpl.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/InterceptorBeanBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/InterceptorBeanBuilder.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/InterceptorBeanBuilder.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/InterceptorBeanBuilder.java Wed Jan 16 21:22:52 2013
@@ -157,8 +157,9 @@ public abstract class InterceptorBeanBui
      *     <li>There must only be a single method for each InterceptorType in the same class.</li>
      * </ul>
      * </p>
+     * @return <code>true</code> if we found some interceptor methods
      */
-    protected void defineInterceptorMethods()
+    public boolean defineInterceptorMethods()
     {
         List<Class> classHierarchy = webBeansContext.getInterceptorUtil().getReverseClassHierarchy(getAnnotated().getJavaClass());
 
@@ -171,6 +172,8 @@ public abstract class InterceptorBeanBui
         List<AnnotatedMethod> prePassivateMethods = new ArrayList<AnnotatedMethod>();
         List<AnnotatedMethod> postActivateMethods = new ArrayList<AnnotatedMethod>();
 
+        boolean interceptorFound = false;
+
         Set<AnnotatedMethod<? super T>> methods = getAnnotated().getMethods();
 
         for (Class clazz : classHierarchy)
@@ -251,30 +254,38 @@ public abstract class InterceptorBeanBui
 
         if (aroundInvokeMethod != null)
         {
+            interceptorFound = true;
             interceptionMethods.put(InterceptionType.AROUND_INVOKE, new Method[]{aroundInvokeMethod.getJavaMember()});
         }
 
         if (postConstructMethods.size() > 0)
         {
+            interceptorFound = true;
             interceptionMethods.put(InterceptionType.POST_CONSTRUCT, getMethodArray(postConstructMethods));
         }
         if (preDestroyMethods.size() > 0)
         {
+            interceptorFound = true;
             interceptionMethods.put(InterceptionType.PRE_DESTROY, getMethodArray(preDestroyMethods));
         }
         if (aroundTimeoutMethods.size() > 0)
         {
+            interceptorFound = true;
             interceptionMethods.put(InterceptionType.AROUND_TIMEOUT, getMethodArray(aroundTimeoutMethods));
         }
 
         if (prePassivateMethods.size() > 0)
         {
+            interceptorFound = true;
             interceptionMethods.put(InterceptionType.PRE_PASSIVATE, getMethodArray(prePassivateMethods));
         }
         if (postActivateMethods.size() > 0)
         {
+            interceptorFound = true;
             interceptionMethods.put(InterceptionType.POST_ACTIVATE, getMethodArray(postActivateMethods));
         }
+
+        return interceptorFound;
     }
 
     /**

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/ManagedBeanBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/ManagedBeanBuilder.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/ManagedBeanBuilder.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/ManagedBeanBuilder.java Wed Jan 16 21:22:52 2013
@@ -76,9 +76,6 @@ public class ManagedBeanBuilder<T, M ext
     }
 
 
-    /**
-     * {@inheritDoc}
-     */
     public void defineConstructor()
     {
         constructor = getBeanConstructor();

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/SelfInterceptorBeanBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/SelfInterceptorBeanBuilder.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/SelfInterceptorBeanBuilder.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/SelfInterceptorBeanBuilder.java Wed Jan 16 21:22:52 2013
@@ -35,6 +35,7 @@ import org.apache.webbeans.config.WebBea
  */
 public class SelfInterceptorBeanBuilder<T> extends InterceptorBeanBuilder<T, SelfInterceptorBean<T>>
 {
+    private boolean enabled = false;
 
     public SelfInterceptorBeanBuilder(WebBeansContext webBeansContext, AnnotatedType<T> annotatedType)
     {
@@ -43,13 +44,19 @@ public class SelfInterceptorBeanBuilder<
 
     public void defineSelfInterceptorRules()
     {
-        checkInterceptorConditions();
-        defineInterceptorRules();
+
+        // we do NOT invoke checkInterceptorConditions();
+        // self-interceptors have different rules!
+
+        // we do NOT invoke defineInterceptorRules() !
+
+        defineApiType();
+        enabled = defineInterceptorMethods();
     }
 
     public boolean isInterceptorEnabled()
     {
-        return true;
+        return enabled;
     }
 
     @Override

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolutionService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolutionService.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolutionService.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolutionService.java Wed Jan 16 21:22:52 2013
@@ -44,6 +44,8 @@ import java.util.Set;
 import java.util.logging.Logger;
 
 import org.apache.webbeans.annotation.AnnotationManager;
+import org.apache.webbeans.component.SelfInterceptorBean;
+import org.apache.webbeans.component.creation.SelfInterceptorBeanBuilder;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.logger.WebBeansLoggerFacade;
 import org.apache.webbeans.plugins.OpenWebBeansEjbLCAPlugin;
@@ -169,11 +171,29 @@ public class InterceptorResolutionServic
         List<Interceptor<?>> cdiInterceptors = new ArrayList<Interceptor<?>>(allUsedCdiInterceptors);
         Collections.sort(cdiInterceptors, new InterceptorComparator(webBeansContext));
 
+        SelfInterceptorBean<T> selfInterceptorBean = resolveSelfInterceptorBean(annotatedType);
 
-        return new BeanInterceptorInfo(decorators, allUsedEjbInterceptors, cdiInterceptors, businessMethodInterceptorInfos,
+        return new BeanInterceptorInfo(decorators, allUsedEjbInterceptors, cdiInterceptors, selfInterceptorBean,
+                                       businessMethodInterceptorInfos,
                                        nonInterceptedMethods, lifecycleMethodInterceptorInfos);
     }
 
+    /**
+     * Check whether this class has any method which intercepts the whole bean itself.
+     * @return SelfInterceptorBean or <code>null</code> if this bean doesn't intercept itself
+     */
+    private <T> SelfInterceptorBean<T> resolveSelfInterceptorBean(AnnotatedType<T> annotatedType)
+    {
+        SelfInterceptorBeanBuilder sibb = new SelfInterceptorBeanBuilder(webBeansContext, annotatedType);
+        sibb.defineSelfInterceptorRules();
+        if (!sibb.isInterceptorEnabled())
+        {
+            return null;
+        }
+
+        return (SelfInterceptorBean<T>) sibb.getBean();
+    }
+
     private void addLifecycleMethods(Map<InterceptionType, LifecycleMethodInfo> lifecycleMethodInterceptorInfos,
                                      AnnotatedType<?> annotatedType,
                                      InterceptionType interceptionType,
@@ -356,7 +376,7 @@ public class InterceptorResolutionServic
     /**
      * Determine the {@link InterceptionType} of the given AnnotatedMethod
      * of an intercepted method.
-     * An empty list means that this is an AroundInvoke method
+     * An empty list means that this is an AroundInvoke method.
      */
     private Set<InterceptionType> collectInterceptionTypes(AnnotatedMethod interceptableAnnotatedMethod)
     {
@@ -428,6 +448,7 @@ public class InterceptorResolutionServic
         public BeanInterceptorInfo(List<Decorator<?>> decorators,
                                    LinkedHashSet<Interceptor<?>> ejbInterceptors,
                                    List<Interceptor<?>> cdiInterceptors,
+                                   SelfInterceptorBean<?> selfInterceptorBean,
                                    Map<Method, BusinessMethodInterceptorInfo> businessMethodsInfo,
                                    List<Method> nonInterceptedMethods,
                                    Map<InterceptionType, LifecycleMethodInfo> lifecycleMethodInterceptorInfos)
@@ -435,6 +456,7 @@ public class InterceptorResolutionServic
             this.decorators = decorators;
             this.ejbInterceptors = ejbInterceptors;
             this.cdiInterceptors = cdiInterceptors;
+            this.selfInterceptorBean = selfInterceptorBean;
             this.businessMethodsInfo = businessMethodsInfo;
             this.nonInterceptedMethods = nonInterceptedMethods;
             this.lifecycleMethodInterceptorInfos = lifecycleMethodInterceptorInfos;
@@ -444,14 +466,19 @@ public class InterceptorResolutionServic
          * All the EJB-style Interceptor Beans which are active on this class somewhere.
          * The Interceptors are sorted according to their definition.
          */
-        private LinkedHashSet<Interceptor<?>> ejbInterceptors = null;
+        private LinkedHashSet<Interceptor<?>> ejbInterceptors;
 
         /**
          * All the CDI-style Interceptor Beans which are active on this class somewhere.
          * This is only used to create the Interceptor instances.
          * The Interceptors are not sorted according to beans.xml .
          */
-        private List<Interceptor<?>> cdiInterceptors = null;
+        private List<Interceptor<?>> cdiInterceptors;
+
+        /**
+         * Set if this class intercepts itself.
+         */
+        private SelfInterceptorBean<?> selfInterceptorBean;
 
         /**
          * All the Decorator Beans active on this class.
@@ -492,6 +519,11 @@ public class InterceptorResolutionServic
             return cdiInterceptors;
         }
 
+        public SelfInterceptorBean<?> getSelfInterceptorBean()
+        {
+            return selfInterceptorBean;
+        }
+
         public Map<Method, BusinessMethodInterceptorInfo> getBusinessMethodsInfo()
         {
             return businessMethodsInfo;

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java Wed Jan 16 21:22:52 2013
@@ -124,6 +124,15 @@ public final class WebBeansInterceptorCo
                         activeInterceptors.add(i);
                     }
                 }
+                if (interceptorInfo.getSelfInterceptorBean() != null)
+                {
+                    if (interceptedMethod.getAnnotation(AroundInvoke.class) == null) // this check is a dirty hack for now to prevent infinite loops
+                    {
+                        // add self-interception as last interceptor in the chain.
+                        activeInterceptors.add(interceptorInfo.getSelfInterceptorBean());
+                    }
+                }
+
                 if (activeInterceptors.size() > 0)
                 {
                     methodInterceptors.put(interceptedMethod, activeInterceptors);

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/InjectionTargetImpl.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/InjectionTargetImpl.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/InjectionTargetImpl.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/InjectionTargetImpl.java Wed Jan 16 21:22:52 2013
@@ -47,7 +47,6 @@ import javax.enterprise.inject.spi.Inter
 import javax.inject.Inject;
 import javax.interceptor.InvocationContext;
 
-import org.apache.webbeans.component.SelfInterceptorBean;
 import org.apache.webbeans.config.OWBLogConst;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.context.creational.CreationalContextImpl;
@@ -158,25 +157,25 @@ public class InjectionTargetImpl<T> exte
             InterceptorDecoratorProxyFactory pf = webBeansContext.getInterceptorDecoratorProxyFactory();
 
             Map<Interceptor<?>,Object> interceptorInstances  = new HashMap<Interceptor<?>, Object>();
+
+            // create EJB-style interceptors
             for (Interceptor interceptorBean : interceptorInfo.getEjbInterceptors())
             {
-                Object interceptorInstance;
-                if (interceptorBean instanceof SelfInterceptorBean)
-                {
-                    interceptorInstance = instance;
-                }
-                else
-                {
-                    interceptorInstance = interceptorBean.create(creationalContext);
-                }
-                interceptorInstances.put(interceptorBean, interceptorInstance);
+                interceptorInstances.put(interceptorBean, interceptorBean.create(creationalContext));
             }
 
+            // create CDI-style interceptors
             for (Interceptor interceptorBean : interceptorInfo.getCdiInterceptors())
             {
                 interceptorInstances.put(interceptorBean, interceptorBean.create(creationalContext));
             }
 
+            // register the bean itself for self-interception
+            if (interceptorInfo.getSelfInterceptorBean() != null)
+            {
+                interceptorInstances.put(interceptorInfo.getSelfInterceptorBean(), instance);
+            }
+
             InterceptorHandler interceptorHandler = new DefaultInterceptorHandler<T>(instance, methodInterceptors, interceptorInstances);
 
             T proxyInstance = pf.createProxyInstance(proxyClass, instance, interceptorHandler);

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java?rev=1434411&r1=1434410&r2=1434411&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/intercept/EJBInterceptComponentTest.java Wed Jan 16 21:22:52 2013
@@ -41,7 +41,6 @@ public class EJBInterceptComponentTest e
         beanClasses.add(InterceptedComponent.class);
         startContainer(beanClasses, null);
 
-
         shutDownContainer();
     }
 
@@ -55,7 +54,7 @@ public class EJBInterceptComponentTest e
         InterceptedComponent comp = getInstance(InterceptedComponent.class);
         Object s = comp.hello(null);
 
-        Assert.assertEquals(new Integer(5), s);
+        Assert.assertEquals(5, s);
 
         shutDownContainer();
     }