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/05 23:08:30 UTC

svn commit: r1429397 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/intercept/ main/java/org/apache/webbeans/proxy/ test/java/org/apache/webbeans/newtests/interceptors/business/tests/ test/java/org/apache/webbeans/newtests/in...

Author: struberg
Date: Sat Jan  5 22:08:30 2013
New Revision: 1429397

URL: http://svn.apache.org/viewvc?rev=1429397&view=rev
Log:
OWB-344 store intercepted Method[] in a static field in the proxy class

Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/DefaultInterceptorHandler.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorHandler.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/business/tests/NewProxyTest.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/DefaultInterceptorHandler.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/DefaultInterceptorHandler.java?rev=1429397&r1=1429396&r2=1429397&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/DefaultInterceptorHandler.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/DefaultInterceptorHandler.java Sat Jan  5 22:08:30 2013
@@ -32,26 +32,22 @@ public class DefaultInterceptorHandler<T
 {
 
     private T target;
-    private List<Method> methods;
     private Map<Method, List<Interceptor<T>>> interceptors;
     private Map<Interceptor<T>, T> instances;
 
     public DefaultInterceptorHandler(T target,
-                                     List<Method> methods,
                                      Map<Method, List<Interceptor<T>>> interceptors,
                                      Map<Interceptor<T>, T> instances)
     {
         this.target = target;
-        this.methods = methods;
         this.instances = instances;
         this.interceptors = interceptors;
     }
 
-    public Object invoke(int index, Object[] parameters)
+    public Object invoke(Method method, Object[] parameters)
     {
         try
         {
-            Method method = methods.get(index);
             List<Interceptor<T>> interceptors = this.interceptors.get(method);
             InterceptorInvocationContext<T> ctx
                 = new InterceptorInvocationContext<T>(target, InterceptionType.AROUND_INVOKE, interceptors, instances, method, parameters);

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java?rev=1429397&r1=1429396&r2=1429397&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java Sat Jan  5 22:08:30 2013
@@ -24,7 +24,6 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.List;
 
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Label;
@@ -54,6 +53,9 @@ public class InterceptorDecoratorProxyFa
     /** the name of the field which stores the Interceptor + Decorator stack InterceptorHandler */
     public static final String FIELD_INTERCEPTOR_HANDLER = "owbIntDecHandler";
 
+    /** the name of the field which stores the Method[] of all intercepted methods */
+    public static final String FIELD_INTERCEPTED_METHODS = "owbIntDecMethods";
+
     //X TODO add caching of created proxy classes. This is needed to prevent class loading clashes.
     //X a generated proxy cannot easily get redefined later!
 
@@ -105,7 +107,7 @@ public class InterceptorDecoratorProxyFa
      * @return the proxy class
      */
     public synchronized <T> Class<T> createProxyClass(ClassLoader classLoader, Class<T> classToProxy,
-                                                      List<Method> interceptedMethods, List<Method> nonInterceptedMethods)
+                                                      Method[] interceptedMethods, Method[] nonInterceptedMethods)
             throws ProxyGenerationException
     {
         String proxyClassName = classToProxy.getName() + "$OwbInterceptProxy";
@@ -113,12 +115,25 @@ public class InterceptorDecoratorProxyFa
 
         final byte[] proxyBytes = generateProxy(classToProxy, proxyClassName, proxyClassFileName, interceptedMethods, nonInterceptedMethods);
 
-        return defineAndLoadClass(classLoader, proxyClassName, proxyBytes);
+        Class<T> clazz = defineAndLoadClass(classLoader, proxyClassName, proxyBytes);
+
+        try
+        {
+            Field interceptedMethodsField = clazz.getDeclaredField(FIELD_INTERCEPTED_METHODS);
+            interceptedMethodsField.setAccessible(true);
+            interceptedMethodsField.set(null, interceptedMethods);
+        }
+        catch (Exception e)
+        {
+            throw new ProxyGenerationException(e);
+        }
+
+        return clazz;
     }
 
 
     private byte[] generateProxy(Class<?> classToProxy, String proxyClassName, String proxyClassFileName,
-                                 List<Method> interceptedMethods, List<Method> nonInterceptedMethods)
+                                 Method[] interceptedMethods, Method[] nonInterceptedMethods)
             throws ProxyGenerationException
     {
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
@@ -150,10 +165,16 @@ public class InterceptorDecoratorProxyFa
     private void createInstanceVariables(ClassWriter cw, Class<?> classToProxy, String classFileName)
     {
         // variable #1, the delegation point
-        cw.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE, FIELD_PROXIED_INSTANCE, Type.getDescriptor(classToProxy), null, null).visitEnd();
+        cw.visitField(Opcodes.ACC_PRIVATE,
+                FIELD_PROXIED_INSTANCE, Type.getDescriptor(classToProxy), null, null).visitEnd();
 
         // variable #2, the invocation handler
-        cw.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE, FIELD_INTERCEPTOR_HANDLER, Type.getDescriptor(InterceptorHandler.class), null, null).visitEnd();
+        cw.visitField(Opcodes.ACC_PRIVATE,
+                FIELD_INTERCEPTOR_HANDLER, Type.getDescriptor(InterceptorHandler.class), null, null).visitEnd();
+
+        // variable #3, the Method[] of all intercepted methods.
+        cw.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
+                FIELD_INTERCEPTED_METHODS, Type.getDescriptor(Method[].class), null, null).visitEnd();
     }
 
     /**
@@ -203,7 +224,7 @@ public class InterceptorDecoratorProxyFa
      *
      * @param noninterceptedMethods all methods which are neither intercepted nor decorated
      */
-    private void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, List<Method> noninterceptedMethods)
+    private void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] noninterceptedMethods)
     {
         for (Method delegatedMethod : noninterceptedMethods)
         {
@@ -261,17 +282,17 @@ public class InterceptorDecoratorProxyFa
                "finalize".equals(delegatedMethod.getName());
     }
 
-    private void delegateInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, List<Method> interceptedMethods)
+    private void delegateInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] interceptedMethods)
             throws ProxyGenerationException
     {
-        for (int i = 0; i < interceptedMethods.size(); i++)
+        for (int i = 0; i < interceptedMethods.length; i++)
         {
-            Method proxiedMethod = interceptedMethods.get(i);
-            generateInvocationHandlerMethod(cw, proxiedMethod, i, classToProxy, proxyClassFileName);
+            Method proxiedMethod = interceptedMethods[i];
+            generateInterceptorHandledMethod(cw, proxiedMethod, i, classToProxy, proxyClassFileName);
         }
     }
 
-    private void generateInvocationHandlerMethod(ClassWriter cw, Method method, int methodIndex, Class<?> classToProxy, String proxyClassFileName)
+    private void generateInterceptorHandledMethod(ClassWriter cw, Method method, int methodIndex, Class<?> classToProxy, String proxyClassFileName)
             throws ProxyGenerationException
     {
         if ("<init>".equals(method.getName()))
@@ -359,9 +380,15 @@ public class InterceptorDecoratorProxyFa
         // get the invocationHandler field from this class
         mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, FIELD_INTERCEPTOR_HANDLER, Type.getDescriptor(InterceptorHandler.class));
 
-        // add the methodIndex as context as second parameter
+        // add the Method from the static array as first parameter
+        mv.visitFieldInsn(Opcodes.GETSTATIC, proxyClassFileName, FIELD_INTERCEPTED_METHODS, Type.getDescriptor(Method[].class));
+
+        // push the methodIndex of the current method
         mv.visitIntInsn(Opcodes.BIPUSH, methodIndex);
 
+        // and now load the Method from the array
+        mv.visitInsn(Opcodes.AALOAD);
+
         // need to construct the array of objects passed in
         // create the Object[]
         createArrayDefinition(mv, parameterTypes.length, Object.class);
@@ -406,7 +433,7 @@ public class InterceptorDecoratorProxyFa
 
         // invoke the invocationHandler
         mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(InterceptorHandler.class), "invoke",
-                "(I[Ljava/lang/Object;)Ljava/lang/Object;");
+                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
 
         // cast the result
         mv.visitTypeInsn(Opcodes.CHECKCAST, getCastType(returnType));

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorHandler.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorHandler.java?rev=1429397&r1=1429396&r2=1429397&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorHandler.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorHandler.java Sat Jan  5 22:08:30 2013
@@ -18,6 +18,8 @@
  */
 package org.apache.webbeans.proxy;
 
+import java.lang.reflect.Method;
+
 /**
  */
 public interface InterceptorHandler
@@ -25,10 +27,10 @@ public interface InterceptorHandler
 
     /**
      *
-     * @param methodIndex index to find the Method
+     * @param method Method which should get invoked
      * @param args
      * @return
      * @throws Throwable
      */
-    public Object invoke(int methodIndex, Object[] args);
+    public Object invoke(Method method, Object[] args);
 }

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/business/tests/NewProxyTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/business/tests/NewProxyTest.java?rev=1429397&r1=1429396&r2=1429397&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/business/tests/NewProxyTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/business/tests/NewProxyTest.java Sat Jan  5 22:08:30 2013
@@ -69,15 +69,18 @@ public class NewProxyTest extends Abstra
         RuntimeExceptionBindingTypeBean target = (RuntimeExceptionBindingTypeBean) beanManager.getContext(RequestScoped.class).get(bean, creationalContext);
         RuntimeExceptionsInterceptor interceptor = (RuntimeExceptionsInterceptor) beanManager.getReference(interceptorBean, RuntimeExceptionsInterceptor.class, creationalContext);
 
-        List<Method> interceptedMethods = Arrays.asList(RuntimeExceptionBindingTypeBean.class.getMethod("business"));
+        Method[] interceptedMethods = {RuntimeExceptionBindingTypeBean.class.getMethod("business")};
         Map<Method, List<Interceptor<RuntimeExceptionBindingTypeBean>>> interceptors = new HashMap<Method, List<Interceptor<RuntimeExceptionBindingTypeBean>>>();
-        interceptors.put(interceptedMethods.iterator().next(), Arrays.<Interceptor<RuntimeExceptionBindingTypeBean>> asList(interceptorBean));
+        interceptors.put(interceptedMethods[0], Arrays.<Interceptor<RuntimeExceptionBindingTypeBean>> asList(interceptorBean));
         Map instances = new HashMap();
         instances.put(interceptorBean, interceptor);
-        InterceptorHandler interceptorHandler = new DefaultInterceptorHandler<RuntimeExceptionBindingTypeBean>(target, interceptedMethods, interceptors, (Map<Interceptor<RuntimeExceptionBindingTypeBean>, RuntimeExceptionBindingTypeBean>) instances);
+        InterceptorHandler interceptorHandler
+                = new DefaultInterceptorHandler<RuntimeExceptionBindingTypeBean>(target, interceptors, (Map<Interceptor<RuntimeExceptionBindingTypeBean>, RuntimeExceptionBindingTypeBean>) instances);
         
         InterceptorDecoratorProxyFactory factory = new InterceptorDecoratorProxyFactory();
-        Class<RuntimeExceptionBindingTypeBean> proxyClass = factory.createProxyClass(Thread.currentThread().getContextClassLoader(), RuntimeExceptionBindingTypeBean.class, interceptedMethods, new ArrayList<Method>());
+        Class<RuntimeExceptionBindingTypeBean> proxyClass
+                = factory.createProxyClass(Thread.currentThread().getContextClassLoader(), RuntimeExceptionBindingTypeBean.class, interceptedMethods, null);
+
         RuntimeExceptionBindingTypeBean instance = factory.createProxyInstance(proxyClass, target, interceptorHandler);
         int result = instance.business();
         Assert.assertEquals(42, result);

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java?rev=1429397&r1=1429396&r2=1429397&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java Sat Jan  5 22:08:30 2013
@@ -54,8 +54,8 @@ public class InterceptorDecoratorProxyFa
 
         List<Method> methods = ClassUtil.getNonPrivateMethods(ClassInterceptedClass.class);
 
-        List<Method> interceptedMethods = methods;
-        List<Method> nonInterceptedMethods = null;
+        Method[] interceptedMethods = methods.toArray(new Method[methods.size()]);
+        Method[] nonInterceptedMethods = null;
 
 
         Class<ClassInterceptedClass> proxyClass = pf.createProxyClass(classLoader, ClassInterceptedClass.class, interceptedMethods, nonInterceptedMethods);
@@ -64,7 +64,7 @@ public class InterceptorDecoratorProxyFa
         ClassInterceptedClass internalInstance = new ClassInterceptedClass();
         internalInstance.init();
 
-        TestInvocationHandler testInvocationHandler = new TestInvocationHandler(internalInstance, interceptedMethods);
+        TestInvocationHandler testInvocationHandler = new TestInvocationHandler(internalInstance);
 
         ClassInterceptedClass proxy = pf.createProxyInstance(proxyClass, internalInstance, testInvocationHandler);
         Assert.assertNotNull(proxy);
@@ -94,24 +94,25 @@ public class InterceptorDecoratorProxyFa
         public List<String> invokedMethodNames = new ArrayList<String>();
 
         private Object instance;
-        private List<Method> interceptedMethods;
 
-        public TestInvocationHandler(Object instance, List<Method> interceptedMethods)
+        public TestInvocationHandler(Object instance)
         {
             this.instance = instance;
-            this.interceptedMethods = interceptedMethods;
         }
 
         @Override
-        public Object invoke(int methodIndex, Object[] args)
+        public Object invoke(Method method, Object[] args)
         {
-            invokedMethodNames.add(interceptedMethods.get(methodIndex).getName());
+            if (!method.getName().equals("toString"))
+            {
+                invokedMethodNames.add(method.getName());
+            }
 
-            System.out.println("TestInvocationHandler got properly invoked for method " + interceptedMethods.get(methodIndex).getName());
+            System.out.println("TestInvocationHandler got properly invoked for method " + method.getName());
 
             try
             {
-                return interceptedMethods.get(methodIndex).invoke(instance, args);
+                return method.invoke(instance, args);
             }
             catch (IllegalAccessException e)
             {