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

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Apr 13 01:31:26 EDT 2010


Author: marius.bogoevici
Date: 2010-04-13 01:31:25 -0400 (Tue, 13 Apr 2010)
New Revision: 103882

Added:
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/javassist/
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/javassist/CompositeHandler.java
Modified:
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreator.java
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreatorImpl.java
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/InterceptionUtils.java
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/TargetInstanceProxyMethodHandler.java
   projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java
   projects/interceptors/trunk/pom.xml
Log:
Adding support for subclassing

Added: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/javassist/CompositeHandler.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/javassist/CompositeHandler.java	                        (rev 0)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/javassist/CompositeHandler.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -0,0 +1,21 @@
+package org.jboss.interceptor.javassist;
+
+import javassist.util.proxy.MethodHandler;
+
+import java.lang.reflect.Method;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: marius
+ * Date: Apr 9, 2010
+ * Time: 7:44:21 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class CompositeHandler implements MethodHandler
+{
+
+   public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
+   {
+      return null;  //To change body of implemented methods use File | Settings | File Templates.
+   }
+}

Modified: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreator.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreator.java	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreator.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -29,7 +29,7 @@
 
    <T> MethodHandler createMethodHandler(Object target, Class<T> proxyClass, InterceptorMetadata interceptorMetadata);
 
-    <T> MethodHandler createSubclassingMethodHandler(Object target, Class<T> proxyClass, InterceptorMetadata interceptorMetadata);
+    <T> MethodHandler createSubclassingMethodHandler(Object targetInstance, Class<T> proxyClass, InterceptorMetadata interceptorMetadata);
 
     <T> T createProxyFromClass(Class<T> proxifiedClass, Class<?>[] constructorTypes, Object[] constructorArguments, InterceptorMetadata interceptorClassMetadata);
 }

Modified: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreatorImpl.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreatorImpl.java	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreatorImpl.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -18,7 +18,6 @@
 package org.jboss.interceptor.proxy;
 
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -121,9 +120,9 @@
       return new InterceptorMethodHandler(target, proxyClass, getModelsFor(proxyClass), interceptionHandlerFactories, interceptorMetadata);
    }
 
-    public <T> MethodHandler createSubclassingMethodHandler(Object target, Class<T> proxyClass, InterceptorMetadata interceptorMetadata)
+    public <T> MethodHandler createSubclassingMethodHandler(Object targetInstance, Class<T> proxyClass, InterceptorMetadata interceptorMetadata)
     {
-       return new SubclassingInterceptorMethodHandler(target, proxyClass, getModelsFor(proxyClass), interceptionHandlerFactories, interceptorMetadata);
+       return new SubclassingInterceptorMethodHandler(targetInstance, proxyClass, getModelsFor(proxyClass), interceptionHandlerFactories, interceptorMetadata);
     }
 
 

Modified: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -1,5 +1,7 @@
 package org.jboss.interceptor.proxy;
 
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyObject;
 import org.jboss.interceptor.model.InterceptionModel;
 import org.jboss.interceptor.model.InterceptionType;
 import org.jboss.interceptor.model.InterceptionTypeRegistry;
@@ -8,10 +10,7 @@
 import org.jboss.interceptor.util.ReflectionUtils;
 import org.jboss.interceptor.util.proxy.TargetInstanceProxyMethodHandler;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
+import java.io.*;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -21,16 +20,27 @@
 /**
  * @author Marius Bogoevici
  */
-public class SubclassingInterceptorMethodHandler extends TargetInstanceProxyMethodHandler implements Serializable
+public class SubclassingInterceptorMethodHandler implements MethodHandler,Serializable
 {
 
    private Map<Object, InterceptionHandler> interceptorHandlerInstances = new HashMap<Object, InterceptionHandler>();
    private InterceptorMetadata targetClassInterceptorMetadata;
    private List<InterceptionModel<Class<?>, ?>> interceptionModels;
+   private Object targetInstance;
 
-   public SubclassingInterceptorMethodHandler(Object target, Class<?> targetClass, List<InterceptionModel<Class<?>, ?>> interceptionModels, List<InterceptionHandlerFactory<?>> interceptionHandlerFactories, InterceptorMetadata targetClassMetadata)
+   private static MethodHandler DEFAULT_METHOD_HANDLER = new MethodHandler() {
+
+        public Object invoke(Object self, Method m,
+                             Method proceed, Object[] args)
+            throws Exception
+        {
+            return proceed.invoke(self, args);
+        }
+   };
+
+   public SubclassingInterceptorMethodHandler(Object targetInstance, Class<?> targetClass, List<InterceptionModel<Class<?>, ?>> interceptionModels, List<InterceptionHandlerFactory<?>> interceptionHandlerFactories, InterceptorMetadata targetClassMetadata)
    {
-      super(target, targetClass != null ? targetClass : target.getClass());
+      this.targetInstance = targetInstance;
       if (interceptionModels == null)
       {
          throw new IllegalArgumentException("Interception model must not be null");
@@ -58,40 +68,40 @@
       targetClassInterceptorMetadata = targetClassMetadata;
    }
 
-   public Object doInvoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
+   public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
    {
       ReflectionUtils.ensureAccessible(thisMethod);
       if (null != proceed)
       {
          if (!InterceptionUtils.isInterceptionCandidate(thisMethod))
          {
-            return proceed.invoke(getTargetInstance(), args);
+            return proceed.invoke(self, args);
          }
          if (InterceptionTypeRegistry.supportsTimeoutMethods() && thisMethod.isAnnotationPresent(InterceptionTypeRegistry.getAnnotationClass(InterceptionType.AROUND_TIMEOUT)))
          {
-            return executeInterception(proceed, thisMethod, args, InterceptionType.AROUND_TIMEOUT);
+            return executeInterception(self, proceed, thisMethod, args, InterceptionType.AROUND_TIMEOUT);
          }
          else
          {
-            return executeInterception(proceed, thisMethod, args, InterceptionType.AROUND_INVOKE);
+            return executeInterception(self, proceed, thisMethod, args, InterceptionType.AROUND_INVOKE);
          }
       }
       else
       {
          if (thisMethod.getName().equals(InterceptionUtils.POST_CONSTRUCT))
          {
-            return executeInterception(null, null, null, InterceptionType.POST_CONSTRUCT);
+            return executeInterception(self, null, null, null, InterceptionType.POST_CONSTRUCT);
          }
          else if (thisMethod.getName().equals(InterceptionUtils.PRE_DESTROY))
          {
-            return executeInterception(null, null, null, InterceptionType.PRE_DESTROY);
+            return executeInterception(self, null, null, null, InterceptionType.PRE_DESTROY);
          }
       }
       return null;
 
    }
 
-   private Object executeInterception(Method proceedingMethod, Method thisMethod, Object[] args, InterceptionType interceptionType) throws Throwable
+   private Object executeInterception(Object self, Method proceedingMethod, Method thisMethod, Object[] args, InterceptionType interceptionType) throws Throwable
    {
       List<InterceptionHandler> interceptionHandlers = new ArrayList<InterceptionHandler>();
       for (InterceptionModel interceptionModel : interceptionModels)
@@ -105,18 +115,18 @@
 
       if (targetClassInterceptorMetadata != null && targetClassInterceptorMetadata.getInterceptorMethods(interceptionType) != null && !targetClassInterceptorMetadata.getInterceptorMethods(interceptionType).isEmpty())
       {
-         interceptionHandlers.add(new DirectClassInterceptionHandler<Class<?>>(getTargetInstance(), targetClassInterceptorMetadata));
+         interceptionHandlers.add(new DirectClassInterceptionHandler<Class<?>>(self, targetClassInterceptorMetadata));
       }
 
-      InterceptionChain chain = new InterceptionChain(interceptionHandlers, interceptionType, getTargetInstance(), proceedingMethod, args);
-      return chain.invokeNext(new InterceptorInvocationContext(chain, getTargetInstance(), thisMethod, args));
+      InterceptionChain chain = new InterceptionChain(interceptionHandlers, interceptionType,self, proceedingMethod, args);
+      return chain.invokeNext(new InterceptorInvocationContext(chain, self, thisMethod, args));
    }
 
    private void writeObject(ObjectOutputStream objectOutputStream) throws IOException
    {
       try
       {
-         executeInterception(null, null, null, InterceptionType.PRE_PASSIVATE);
+         executeInterception(targetInstance, null, null, null, InterceptionType.PRE_PASSIVATE);
          objectOutputStream.defaultWriteObject();
       }
       catch (Throwable throwable)
@@ -130,7 +140,15 @@
       try
       {
          objectInputStream.defaultReadObject();
-         executeInterception(null, null, null, InterceptionType.POST_ACTIVATE);
+         // it is reasonably safe to assume that all the fields from targetInstance
+         // have already been serialized because the MethodHandler is a field of the
+         // generated subclass, therefore it is deserialized after the fields of the
+         // superclass, which is the actual class of targetInstance, but we need a
+         // non-empty MethodHandler in order to be able to execute the methods
+         // set the DEFAULT_METHOD_HANDLER temporarily and let the deserialization
+         // process to overwrite it
+        ((ProxyObject)targetInstance).setHandler(DEFAULT_METHOD_HANDLER);
+         executeInterception(targetInstance, null, null, null, InterceptionType.POST_ACTIVATE);
       }
       catch (Throwable throwable)
       {

Modified: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/InterceptionUtils.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/InterceptionUtils.java	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/InterceptionUtils.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -272,7 +272,9 @@
       if (proxyClass != null)
       {
          proxyFactory.setSuperclass(proxyClass);
+         proxyFactory.setUseWriteReplace(false);
       }
+
       if (forSubclassing)
          proxyFactory.setInterfaces(new Class<?>[]{LifecycleMixin.class, TargetInstanceProxy.class, SubclassedProxy.class});
       else

Modified: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/TargetInstanceProxyMethodHandler.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/TargetInstanceProxyMethodHandler.java	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/TargetInstanceProxyMethodHandler.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -37,15 +37,15 @@
       this.targetClass = targetClass;
    }
 
-   public final Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
+   public final Object invoke(Object proxyInstance, Method interceptedMethod, Method proceed, Object[] args) throws Throwable
    {
-      if (thisMethod.getDeclaringClass().equals(TargetInstanceProxy.class))
+      if (interceptedMethod.getDeclaringClass().equals(TargetInstanceProxy.class))
       {
-         if (thisMethod.getName().equals("getTargetInstance"))
+         if (interceptedMethod.getName().equals("getTargetInstance"))
          {
             return this.getTargetInstance();
          }
-         else if (thisMethod.getName().equals("getTargetClass"))
+         else if (interceptedMethod.getName().equals("getTargetClass"))
          {
             return this.getTargetClass();
          }
@@ -57,11 +57,12 @@
       }
       else
       {
-         return doInvoke(self, thisMethod, proceed, args);
+         return doInvoke(proxyInstance, interceptedMethod, proceed, args);
       }
    }
 
-   protected abstract Object doInvoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable;
+   /**/
+   protected abstract Object doInvoke(Object proxyInstance, Method interceptedMethod, Method proceedingMethod, Object[] invocationArguments) throws Throwable;
 
    public T getTargetInstance()
    {

Modified: projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java	2010-04-13 05:31:25 UTC (rev 103882)
@@ -18,12 +18,14 @@
 package org.jboss.interceptors.proxy;
 
 import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyObject;
 import org.jboss.interceptor.model.InterceptionModel;
 import org.jboss.interceptor.model.InterceptionModelBuilder;
 import org.jboss.interceptor.model.metadata.ReflectiveClassReference;
 import org.jboss.interceptor.proxy.DirectClassInterceptionHandlerFactory;
 import org.jboss.interceptor.proxy.InterceptorProxyCreator;
 import org.jboss.interceptor.proxy.InterceptorProxyCreatorImpl;
+import org.jboss.interceptor.proxy.SubclassingInterceptorMethodHandler;
 import org.jboss.interceptor.registry.InterceptorMetadataRegistry;
 import org.jboss.interceptor.registry.InterceptorRegistry;
 import org.jboss.interceptor.registry.SimpleClassMetadataReader;
@@ -225,11 +227,23 @@
       Assert.assertEquals(TEAM_NAME, proxy.getName());
       Object[] logValues = InterceptorTestLogger.getLog().toArray();
       Assert.assertArrayEquals(iterateAndDisplay(logValues), expectedLoggedValuesOnSerialization, logValues);
+      Assert.assertTrue(((ProxyObject)proxy).getHandler() instanceof SubclassingInterceptorMethodHandler);
       assertRawObject(proxy);
    }
 
 
    @Test
+   public void testSerialization() throws Exception
+   {
+      FootballTeam proxy = new FootballTeam("Ajax Amsterdam");
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      new ObjectOutputStream(baos).writeObject(proxy);
+      proxy = (FootballTeam) new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())).readObject();
+      Assert.assertNotNull(proxy);
+   }
+
+
+   @Test
    public void testMethodParameterOverriding() throws Exception
    {
       InterceptorTestLogger.reset();

Modified: projects/interceptors/trunk/pom.xml
===================================================================
--- projects/interceptors/trunk/pom.xml	2010-04-13 05:27:52 UTC (rev 103881)
+++ projects/interceptors/trunk/pom.xml	2010-04-13 05:31:25 UTC (rev 103882)
@@ -25,7 +25,7 @@
 
   <properties>
     <version.interceptor.api>1.1-CR1</version.interceptor.api>
-    <version.javassist>3.11.0.GA</version.javassist>
+    <version.javassist>3.12.0-SNAPSHOT</version.javassist>
      <version.junit>4.5</version.junit>
      <version.slf4j>1.5.6</version.slf4j>
   </properties>




More information about the jboss-cvs-commits mailing list