openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject svn commit: r1430942 - in /openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component: CdiInterceptorBean.java InterceptorBean.java SelfInterceptorBean.java
Date Wed, 09 Jan 2013 16:34:21 GMT
Author: struberg
Date: Wed Jan  9 16:34:21 2013
New Revision: 1430942

URL: http://svn.apache.org/viewvc?rev=1430942&view=rev
Log:
OWB-344 add Interceptor for EJB-style and self interceptors + multimethod support


Added:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/SelfInterceptorBean.java
      - copied, changed from r1430763, openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/EjbInterceptorBean.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/CdiInterceptorBean.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/InterceptorBean.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/CdiInterceptorBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/CdiInterceptorBean.java?rev=1430942&r1=1430941&r2=1430942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/CdiInterceptorBean.java
(original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/CdiInterceptorBean.java
Wed Jan  9 16:34:21 2013
@@ -20,18 +20,18 @@ package org.apache.webbeans.component;
 
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.InterceptionType;
-import javax.enterprise.inject.spi.Interceptor;
 import java.lang.annotation.Annotation;
 import java.util.Set;
 
 import org.apache.webbeans.config.WebBeansContext;
 
 /**
- * <p>{@link Interceptor} Bean implementation for CDI-style Beans.
+ * <p>{@link javax.enterprise.inject.spi.Interceptor}
+ * Bean implementation for CDI-style Beans.
  * This is Interceptors which got defined using
  * &#064;{@link javax.interceptor.InterceptorBinding}.</p>
  */
-public class CdiInterceptorBean<T> extends InterceptorBean<T> implements Interceptor<T>
+public class CdiInterceptorBean<T> extends InterceptorBean<T>
 {
     /**
      *

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/InterceptorBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/InterceptorBean.java?rev=1430942&r1=1430941&r2=1430942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/InterceptorBean.java
(original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/InterceptorBean.java
Wed Jan  9 16:34:21 2013
@@ -24,8 +24,8 @@ import javax.enterprise.inject.spi.Inter
 import javax.enterprise.inject.spi.Interceptor;
 import javax.interceptor.InvocationContext;
 import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.webbeans.config.WebBeansContext;
@@ -63,75 +63,85 @@ public abstract class InterceptorBean<T>
     private Set<InterceptionType> intercepts;
 
     /**
-     * The Method to be called for InterceptionType.AROUND_INVOKE.
+     * The Methods to be called for InterceptionType.AROUND_INVOKE.
      * The method signature must be
      * <pre>Object <METHOD>(InvocationContext) throws Exception</pre>
      */
-    private Method aroundInvokeMethod;
+    private Method[] aroundInvokeMethods;
 
     /**
-     * The Method to be called for InterceptionType.AROUND_TIMEOUT.
+     * The Methods to be called for InterceptionType.AROUND_TIMEOUT.
+     * They must be ordered by methods from superclass-first!
      * The method signature must be
      * <pre>Object <METHOD>(InvocationContext) throws Exception</pre>
      */
-    private Method aroundTimeoutMethod;
+    private Method[] aroundTimeoutMethods;
 
     /**
-     * All &#064;PostConstruct interceptor method
+     * All &#064;PostConstruct interceptor methods.
+     * They must be ordered by methods from superclass-first!
      * The method signature must be
      * <pre>void <METHOD>(InvocationContext) throws Exception</pre>
      */
-    private Method postConstructMethod;
+    private Method[] postConstructMethods;
 
     /**
-     * All &#064;PreDestroy interceptor method
+     * All &#064;PreDestroy interceptor methods.
+     * They must be ordered by methods from superclass-first!
      * The method signature must be
      * <pre>void <METHOD>(InvocationContext) throws Exception</pre>
      */
-    private Method preDestroyMethod;
+    private Method[] preDestroyMethods;
 
     /**
-     * All &#064;PrePassivate interceptor method
+     * All &#064;PrePassivate interceptor methods.
+     * They must be ordered by methods from superclass-first!
      * The method signature must be
      * <pre>void <METHOD>(InvocationContext) throws Exception</pre>
      */
-    private Method prePassivateMethod;
+    private Method[] prePassivateMethods;
 
     /**
-     * All &#064;PostActivate interceptor method
+     * All &#064;PostActivate interceptor methods.
+     * They must be ordered by methods from superclass-first!
      * The method signature must be
      * <pre>void <METHOD>(InvocationContext) throws Exception</pre>
      */
-    private Method postActivateMethod;
+    private Method[] postActivateMethods;
 
-    public void setAroundInvokeMethod(Method aroundInvokeMethod)
+    public void setAroundInvokeMethods(Method[] aroundInvokeMethod)
     {
-        this.aroundInvokeMethod = aroundInvokeMethod;
+        this.aroundInvokeMethods = aroundInvokeMethods;
     }
 
-    public void setAroundTimeoutMethod(Method aroundTimeoutMethod)
+    public void setAroundTimeoutMethods(Method[] aroundTimeoutMethods)
     {
-        this.aroundTimeoutMethod = aroundTimeoutMethod;
+        this.aroundTimeoutMethods = aroundTimeoutMethods;
     }
 
-    public void setPostActivateMethod(Method postActivateMethod)
+    public void setIntercepts(Set<InterceptionType> intercepts)
     {
-        this.postActivateMethod = postActivateMethod;
+        this.intercepts = intercepts;
     }
 
-    public void setPostConstructMethod(Method postConstructMethod)
+    public void setPostActivateMethods(Method[] postActivateMethods)
     {
-        this.postConstructMethod = postConstructMethod;
+        this.postActivateMethods = postActivateMethods;
     }
 
-    public void setPreDestroyMethod(Method preDestroyMethod)
+    public void setPostConstructMethods(Method[] postConstructMethods)
     {
-        this.preDestroyMethod = preDestroyMethod;
+        this.postConstructMethods = postConstructMethods;
     }
 
-    public void setPrePassivateMethod(Method prePassivateMethod)
+    public void setPreDestroyMethods(Method[] preDestroyMethods)
     {
-        this.prePassivateMethod = prePassivateMethod;
+        this.preDestroyMethods = preDestroyMethods;
+    }
+
+    public void setPrePassivateMethods(Method[] prePassivateMethods)
+    {
+        this.prePassivateMethods = prePassivateMethods;
     }
 
     /**
@@ -147,31 +157,31 @@ public abstract class InterceptorBean<T>
      * @param interceptionType
      * @return the underlying interceptor method for the given InterceptionType or <code>null</code>
      */
-    protected Method getInterceptorMethod(InterceptionType interceptionType)
+    protected Method[] getInterceptorMethods(InterceptionType interceptionType)
     {
         if (InterceptionType.AROUND_INVOKE.equals(interceptionType))
         {
-            return aroundInvokeMethod;
+            return aroundInvokeMethods;
         }
         if (InterceptionType.POST_CONSTRUCT.equals(interceptionType))
         {
-            return postConstructMethod;
+            return postConstructMethods;
         }
         if (InterceptionType.PRE_DESTROY.equals(interceptionType))
         {
-            return preDestroyMethod;
+            return preDestroyMethods;
         }
         if (InterceptionType.AROUND_TIMEOUT.equals(interceptionType))
         {
-            return aroundTimeoutMethod;
+            return aroundTimeoutMethods;
         }
         if (InterceptionType.POST_ACTIVATE.equals(interceptionType))
         {
-            return postActivateMethod;
+            return postActivateMethods;
         }
         if (InterceptionType.PRE_PASSIVATE.equals(interceptionType))
         {
-            return prePassivateMethod;
+            return prePassivateMethods;
         }
 
         throw new WebBeansException("InterceptionType not yet supported: " + interceptionType);
@@ -189,15 +199,130 @@ public abstract class InterceptorBean<T>
     {
         try
         {
-            return getInterceptorMethod(interceptionType).invoke(instance, invocationContext);
+            Method[] interceptorMethods = getInterceptorMethods(interceptionType);
+
+            if (interceptorMethods == null || interceptorMethods.length == 0)
+            {
+                throw new WebBeansException("No Interceptor method found for handling " +
invocationContext);
+            }
+            if (interceptorMethods.length == 1)
+            {
+                // directly invoke the InvocationContext
+                return interceptorMethods[0].invoke(instance, invocationContext);
+            }
+            else
+            {
+                // otherwise we need to wrap it for handling multiple interceptor methods
+
+                if (invocationContext instanceof MultiMethodInvocationContext)
+                {
+                    // this happens while we recurse through the interceptors which have
multiple interceptor-methods
+                    MultiMethodInvocationContext mmInvocationContext = (MultiMethodInvocationContext)
invocationContext;
+                    int methodIndex = mmInvocationContext.getCurrentInterceptorIdx();
+                    if (methodIndex < (interceptorMethods.length -1))
+                    {
+                        return interceptorMethods[methodIndex].invoke(instance, invocationContext);
+                    }
+                    else
+                    {
+                        return interceptorMethods[methodIndex].invoke(instance, mmInvocationContext.getWrapped());
+                    }
+                }
+                else
+                {
+                    // We need to create the wrapper InvocationContext on the first time.
+                    // This will internally walk through all the methods
+                    MultiMethodInvocationContext mmInvocationContext
+                            = new MultiMethodInvocationContext(invocationContext, interceptionType,
instance, this);
+                    return mmInvocationContext.proceed();
+                }
+
+            }
+
+        }
+        catch (Exception e)
+        {
+            throw ExceptionUtil.throwAsRuntimeException(e);
+        }
+    }
+
+    /**
+     * An InvocationContext wraper for handling multiple interceptor methods.
+     * We will first make sure the own interceptor methods get handled and only
+     * then continue with the wrapped InvocationHandler.
+     */
+    public static class MultiMethodInvocationContext implements InvocationContext
+    {
+        private final InvocationContext wrapped;
+        private final Interceptor interceptor;
+        private final InterceptionType interceptionType;
+        private final Object instance;
+        private int currentInterceptorIdx;
+
+        public MultiMethodInvocationContext(InvocationContext wrapped,
+                                            InterceptionType interceptionType,
+                                            Object instance,
+                                            Interceptor interceptor)
+        {
+            this.wrapped = wrapped;
+            this.interceptor = interceptor;
+            this.interceptionType = interceptionType;
+            this.instance = instance;
+            this.currentInterceptorIdx = 0; // we start with method 0
+        }
+
+        public int getCurrentInterceptorIdx()
+        {
+            return currentInterceptorIdx;
+        }
+
+        public InvocationContext getWrapped()
+        {
+            return wrapped;
+        }
+
+        @Override
+        public Object proceed() throws Exception
+        {
+            currentInterceptorIdx++;
+            return interceptor.intercept(interceptionType, instance, this);
+        }
+
+
+        @Override
+        public Map<String, Object> getContextData()
+        {
+            return wrapped.getContextData();
+        }
+
+        @Override
+        public Method getMethod()
+        {
+            return wrapped.getMethod();
+        }
+
+        @Override
+        public Object getTarget()
+        {
+            return wrapped.getTarget();
         }
-        catch (InvocationTargetException ite)
+
+        @Override
+        public Object getTimer()
         {
-            throw ExceptionUtil.throwAsRuntimeException(ite);
+            return wrapped.getTimer();
         }
-        catch (IllegalAccessException iae)
+
+        @Override
+        public Object[] getParameters()
+        {
+            return wrapped.getParameters();
+        }
+
+        @Override
+        public void setParameters(Object[] parameters)
         {
-            throw ExceptionUtil.throwAsRuntimeException(iae);
+            wrapped.setParameters(parameters);
         }
     }
 

Copied: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/SelfInterceptorBean.java
(from r1430763, openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/EjbInterceptorBean.java)
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/SelfInterceptorBean.java?p2=openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/SelfInterceptorBean.java&p1=openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/EjbInterceptorBean.java&r1=1430763&r2=1430942&rev=1430942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/EjbInterceptorBean.java
(original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/SelfInterceptorBean.java
Wed Jan  9 16:34:21 2013
@@ -28,11 +28,13 @@ import java.util.Set;
 import org.apache.webbeans.config.WebBeansContext;
 
 /**
- * <p>{@link javax.enterprise.inject.spi.Interceptor} Bean implementation for EJB-style
Beans.
- * This is Interceptors which got defined by being referenced via
- * &#064;{@link javax.interceptor.Interceptors}.</p>
+ * <p>Implicit self-interceptor Bean implementation.
+ * This is Interceptors which got defined by having an &#064;AroundInvoke,
+ * &#064;AroundTimeout, etc method inside a bean itself. In that case
+ * all business method invocations on that bean are intercepted via those methods
+ * in the bean.</p>
  */
-public class EjbInterceptorBean<T> extends InterceptorBean<T> implements Interceptor<T>
+public class SelfInterceptorBean<T> extends InterceptorBean<T> implements Interceptor<T>
 {
     /**
      *
@@ -41,9 +43,9 @@ public class EjbInterceptorBean<T> exten
      * @param webBeansContext
      * @param intercepts the InterceptionTypes this Bean handles on the intercepted target
      */
-    public EjbInterceptorBean(Class<T> returnType, AnnotatedType<T> annotatedType,
-                              WebBeansContext webBeansContext,
-                              Set<InterceptionType> intercepts)
+    public SelfInterceptorBean(Class<T> returnType, AnnotatedType<T> annotatedType,
+                               WebBeansContext webBeansContext,
+                               Set<InterceptionType> intercepts)
     {
         super(returnType, annotatedType, webBeansContext, intercepts);
     }
@@ -57,5 +59,4 @@ public class EjbInterceptorBean<T> exten
         return Collections.emptySet();
     }
 
-
 }



Mime
View raw message