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/02 18:41:50 UTC

svn commit: r1427877 - in /openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: intercept/ intercept/webbeans/ util/

Author: struberg
Date: Wed Jan  2 17:41:49 2013
New Revision: 1427877

URL: http://svn.apache.org/viewvc?rev=1427877&view=rev
Log:
OWB-344 refactor interceptor handling

Added:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolution.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorDataImpl.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptorBean.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorDataImpl.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorDataImpl.java?rev=1427877&r1=1427876&r2=1427877&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorDataImpl.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorDataImpl.java Wed Jan  2 17:41:49 2013
@@ -427,8 +427,8 @@ public class InterceptorDataImpl impleme
                 BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();
 
                 WebBeansInterceptorBean<Object> actualInterceptor = (WebBeansInterceptorBean<Object>) webBeansInterceptor;
-                CreationalContext<Object> creationalContext = manager.createCreationalContext(actualInterceptor);
-                interceptor = manager.getReference(actualInterceptor, actualInterceptor.getBeanClass(), creationalContext);
+                CreationalContext<?> creationalContext = manager.createCreationalContext(webBeansInterceptor);
+                interceptor = manager.getReference(webBeansInterceptor, actualInterceptor.getBeanClass(), creationalContext);
 
                 actualInterceptor.setInjections(interceptor, creationalContext);
 

Added: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolution.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolution.java?rev=1427877&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolution.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolution.java Wed Jan  2 17:41:49 2013
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.webbeans.intercept;
+
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Decorator;
+import javax.enterprise.inject.spi.InterceptionType;
+import javax.enterprise.inject.spi.Interceptor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.logger.WebBeansLoggerFacade;
+import org.apache.webbeans.util.ClassUtil;
+
+/**
+ * Class to calculate static interceptor resolution information.
+ *
+ */
+public class InterceptorResolution
+{
+    private static final Logger logger = WebBeansLoggerFacade.getLogger(InterceptorResolution.class);
+
+
+    private WebBeansContext webBeansContext;
+
+    public InterceptorResolution(WebBeansContext webBeansContext)
+    {
+        this.webBeansContext = webBeansContext;
+    }
+
+
+    public ClassInterceptorInfo calculateInterceptorInfo(AnnotatedType annotatedType)
+    {
+        ClassInterceptorInfo interceptorInfo = new ClassInterceptorInfo();
+
+        List<AnnotatedMethod> interceptableAnnotatedMethods = getInterceptableAnnotatedMethods(annotatedType);
+
+        InterceptorUtil interceptorUtils = webBeansContext.getInterceptorUtil();
+
+        List<Interceptor> classLevelCdiInterceptors = new ArrayList<Interceptor>();
+        List<Interceptor> classLevelEjbInterceptors = new ArrayList<Interceptor>();
+
+
+        //X TODO pick up CDI interceptors from a class level
+        //X TODO pick up EJB interceptors from a class level
+        //X TODO pick up the decorators
+
+        //X TODO iterate over all methods and build up the interceptor stack
+        //X TODO sort the CDI interceptors
+
+        return interceptorInfo;
+    }
+
+    /**
+     * @return the list of all non-overloaded non-private and non-static methods
+     */
+    private List<AnnotatedMethod> getInterceptableAnnotatedMethods(AnnotatedType annotatedType)
+    {
+        List<Method> interceptableMethods = ClassUtil.getNonPrivateMethods(annotatedType.getJavaClass());
+
+        List<AnnotatedMethod> interceptableAnnotatedMethods = new ArrayList<AnnotatedMethod>();
+
+        Set<AnnotatedMethod> annotatedMethods = annotatedType.getMethods();
+        for (Method interceptableMethod : interceptableMethods)
+        {
+            for (AnnotatedMethod<?> annotatedMethod : annotatedMethods)
+            {
+                if (annotatedMethod.getJavaMember() == interceptableMethod)
+                {
+                    interceptableAnnotatedMethods.add(annotatedMethod);
+                }
+            }
+        }
+
+        return interceptableAnnotatedMethods;
+    }
+
+
+    /**
+     * static information about interceptors and decorators for a
+     * single bean.
+     */
+    public static class ClassInterceptorInfo
+    {
+        /**
+         * All the Interceptor Beans which are active on this class somewhere.
+         * This is only used to create the Interceptor instances.
+         */
+        private List<Interceptor> interceptors = new ArrayList<Interceptor>();
+
+        /**
+         * All the Decorator Beans active on this class.
+         */
+        private List<Decorator> decorators = new ArrayList<Decorator>();
+
+        /**
+         * For each method which is either decorated or intercepted we keep an entry.
+         * If there is no entry then the method has neither a decorator nor an interceptor.
+         */
+        private Map<Method, MethodInterceptorInfo> methodsInfo = new HashMap<Method, MethodInterceptorInfo>();
+
+
+    }
+
+    /**
+     * We track per method which Interceptors to invoke
+     */
+    public static class MethodInterceptorInfo
+    {
+        public MethodInterceptorInfo(InterceptionType interceptionType, List<Interceptor> methodEjbInterceptors, List<Interceptor> methodCdiInterceptors,
+                                     List<Decorator> methodDecorators)
+        {
+            this.interceptionType = interceptionType;
+            this.methodCdiInterceptors = methodCdiInterceptors;
+            this.methodDecorators = methodDecorators;
+            this.methodEjbInterceptors = methodEjbInterceptors;
+        }
+
+        private InterceptionType  interceptionType;
+        private List<Interceptor> methodEjbInterceptors = null;
+        private List<Interceptor> methodCdiInterceptors = null;
+        private List<Decorator>   methodDecorators = null;
+
+
+        /**
+         * This is needed for later invoking the correct
+         * interceptor method on the Interceptors.
+         * (e.g. &#064;AroundInvoke vs &#064;PostConstruct interceptors)
+         */
+        public InterceptionType getInterceptionType()
+        {
+            return interceptionType;
+        }
+
+        /**
+         * The (sorted) EJB-style ({@link javax.interceptor.Interceptors})
+         * Interceptor Beans for a specific method or <code>null</code>
+         * if no Interceptor exists for this method.
+         * They must be called <i>before</i> the {@link #methodCdiInterceptors}!
+         */
+        public List<Interceptor> getMethodEjbInterceptors()
+        {
+            return methodEjbInterceptors;
+        }
+
+        /**
+         * The (sorted) CDI Interceptor Beans for a specific method or <code>null</code>
+         * if no Interceptor exists for this method.
+         */
+        public List<Interceptor> getMethodCdiInterceptors()
+        {
+            return methodCdiInterceptors;
+        }
+
+        /**
+         * The (sorted) Decorator Beans for a specific method or <code>null</code>
+         * if no Decorator exists for this method.
+         */
+        public List<Decorator> getMethodDecorators()
+        {
+            return methodDecorators;
+        }
+
+    }
+}

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java?rev=1427877&r1=1427876&r2=1427877&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorUtil.java Wed Jan  2 17:41:49 2013
@@ -132,7 +132,7 @@ public final class InterceptorUtil
      * in the sense of the Interceptor specification
      * @param method
      * @return <code>true</code> if the given method is an interceptable business method
-     * @deprecated TODO remove this class as it does not take AnnotatedType/Extensions into account
+     * @deprecated TODO remove this method as it does not take AnnotatedType/Extensions into account
      */
     public boolean isWebBeansBusinessMethod(Method method)
     {

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=1427877&r1=1427876&r2=1427877&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  2 17:41:49 2013
@@ -108,11 +108,9 @@ public final class WebBeansInterceptorCo
         }
         WebBeansInterceptorBean<T> interceptor = new WebBeansInterceptorBean<T>(delegate);
 
-        List<Annotation> anns = Arrays.asList(interceptorBindingTypes);
-
         for (Annotation ann : interceptorBindingTypes)
         {
-            checkAnns(anns, ann, delegate);
+            checkInterceptorAnnotations(interceptorBindingTypes, ann, delegate);
             interceptor.addInterceptorBinding(ann.annotationType(), ann);
         }
 
@@ -121,9 +119,9 @@ public final class WebBeansInterceptorCo
 
     }
 
-    private void checkAnns(List<Annotation> list, Annotation ann, Bean<?> bean)
+    private void checkInterceptorAnnotations(Annotation[] interceptorBindingTypes, Annotation ann, Bean<?> bean)
     {
-        for(Annotation old : list)
+        for(Annotation old : interceptorBindingTypes)
         {
             if(old.annotationType().equals(ann.annotationType()))
             {
@@ -135,6 +133,8 @@ public final class WebBeansInterceptorCo
         }
     }
 
+
+
     /**
      * Configures the given class for applicable interceptors.
      *
@@ -143,54 +143,13 @@ public final class WebBeansInterceptorCo
     {
         Class<?> clazz = ((AbstractOwbBean<?>)component).getReturnType();
         AnnotatedType<?> annotatedType = component.getAnnotatedType();
-        Set<Annotation> annotations = null;
-
-        if(annotatedType != null)
-        {
-            annotations = annotatedType.getAnnotations();
-        }
-
-        Set<Interceptor<?>> componentInterceptors = null;
 
-        Set<Annotation> bindingTypeSet = new HashSet<Annotation>();
         Annotation[] anns;
-        Annotation[] typeAnns = null;
-        if(annotations != null)
-        {
-            typeAnns = annotations.toArray(new Annotation[annotations.size()]);
-        }
-        else
-        {
-            typeAnns = clazz.getDeclaredAnnotations();
-        }
-        AnnotationManager annotationManager = component.getWebBeansContext().getAnnotationManager();
-        if (annotationManager.hasInterceptorBindingMetaAnnotation(typeAnns))
-        {
-            anns = annotationManager.getInterceptorBindingMetaAnnotations(typeAnns);
-
-            for (Annotation ann : anns)
-            {
-                bindingTypeSet.add(ann);
-            }
-        }
 
-        // check for stereotypes _explicitly_ declared on the bean class (not
-        // inherited)
-        Annotation[] stereoTypes =
-            annotationManager.getStereotypeMetaAnnotations(typeAnns);
-        for (Annotation stero : stereoTypes)
-        {
-            if (annotationManager.hasInterceptorBindingMetaAnnotation(stero.annotationType().getDeclaredAnnotations()))
-            {
-                Annotation[] steroInterceptorBindings = annotationManager.getInterceptorBindingMetaAnnotations(
-                        stero.annotationType().getDeclaredAnnotations());
+        AnnotationManager annotationManager = webBeansContext.getAnnotationManager();
 
-                for (Annotation ann : steroInterceptorBindings)
-                {
-                    bindingTypeSet.add(ann);
-                }
-            }
-        }
+        Set<Interceptor<?>> componentInterceptors = null;
+        Set<Annotation> bindingTypeSet = getComponentInterceptors(annotatedType, clazz);
 
         // Look for inherited binding types, keeping in mind that
         // IBeanInheritedMetaData knows nothing of the transitive
@@ -239,10 +198,9 @@ public final class WebBeansInterceptorCo
         anns = bindingTypeSet.toArray(anns);
 
         //Spec Section 9.5.2
-        List<Annotation> beanAnnots = Arrays.asList(anns);
         for(Annotation checkAnn : anns)
         {
-            checkAnns(beanAnnots, checkAnn, component);
+            checkInterceptorAnnotations(anns, checkAnn, component);
         }
 
         if (anns.length > 0)
@@ -268,6 +226,58 @@ public final class WebBeansInterceptorCo
 
     }
 
+    private Set<Annotation> getComponentInterceptors(AnnotatedType<?> annotatedType, Class clazz)
+    {
+        Set<Annotation> annotations = null;
+
+        if(annotatedType != null)
+        {
+            annotations = annotatedType.getAnnotations();
+        }
+
+        Set<Annotation> bindingTypeSet = new HashSet<Annotation>();
+        Annotation[] anns;
+
+        Annotation[] typeAnns;
+        if(annotations != null)
+        {
+            typeAnns = annotations.toArray(new Annotation[annotations.size()]);
+        }
+        else
+        {
+            typeAnns = clazz.getDeclaredAnnotations();
+        }
+
+        AnnotationManager annotationManager = webBeansContext.getAnnotationManager();
+
+        anns = annotationManager.getInterceptorBindingMetaAnnotations(typeAnns);
+
+        for (Annotation ann : anns)
+        {
+            bindingTypeSet.add(ann);
+        }
+
+        // check for stereotypes _explicitly_ declared on the bean class (not
+        // inherited)
+        Annotation[] stereoTypes =
+                annotationManager.getStereotypeMetaAnnotations(typeAnns);
+        for (Annotation stero : stereoTypes)
+        {
+            if (annotationManager.hasInterceptorBindingMetaAnnotation(stero.annotationType().getDeclaredAnnotations()))
+            {
+                Annotation[] steroInterceptorBindings = annotationManager.getInterceptorBindingMetaAnnotations(
+                        stero.annotationType().getDeclaredAnnotations());
+
+                for (Annotation ann : steroInterceptorBindings)
+                {
+                    bindingTypeSet.add(ann);
+                }
+            }
+        }
+
+        return bindingTypeSet;
+    }
+
     private void filterInterceptorsPerBDA(AbstractInjectionTargetBean<?> component, List<InterceptorData> stack)
     {
 

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptorBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptorBean.java?rev=1427877&r1=1427876&r2=1427877&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptorBean.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptorBean.java Wed Jan  2 17:41:49 2013
@@ -247,6 +247,9 @@ public class WebBeansInterceptorBean<T> 
         return set;
     }
 
+    /**
+     * TODO WTF? these checks must not be done at runtime but boot time!
+     */
     private Method getMethod(InterceptionType type)
     {
         Method method = null;
@@ -390,7 +393,10 @@ public class WebBeansInterceptorBean<T> 
         return delegateBean.getStereotypes();
     }
 
-    public Object intercept(InterceptionType type, T instance,InvocationContext ctx)
+    /**
+     * This is the main invocation point for an interceptor!
+     */
+    public Object intercept(InterceptionType type, T instance, InvocationContext ctx)
     {
         Method method = getMethod(type);
         try

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java?rev=1427877&r1=1427876&r2=1427877&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java Wed Jan  2 17:41:49 2013
@@ -1985,6 +1985,7 @@ public final class WebBeansUtil
 
             if (delegate != null)
             {
+                delegate.setAnnotatedType(processInjectionTargetEvent.getAnnotatedType());
                 WebBeansDecoratorConfig.configureDecoratorClass(delegate);
             }
             else