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

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Apr 9 14:13:10 EDT 2010


Author: marius.bogoevici
Date: 2010-04-09 14:13:09 -0400 (Fri, 09 Apr 2010)
New Revision: 103760

Added:
   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/proxy/SubclassedProxy.java
   projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java
Modified:
   projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorMethodHandler.java
   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/util/InterceptionUtils.java
   projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/FootballTeam.java
Log:
Adding support for subclassing

Modified: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorMethodHandler.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorMethodHandler.java	2010-04-09 18:03:14 UTC (rev 103759)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorMethodHandler.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -61,7 +61,7 @@
    public Object doInvoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
    {
       ReflectionUtils.ensureAccessible(thisMethod);
-      if (!thisMethod.getDeclaringClass().equals(LifecycleMixin.class))
+      if (null != proceed)
       {
          if (!org.jboss.interceptor.util.InterceptionUtils.isInterceptionCandidate(thisMethod))
          {

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-09 18:03:14 UTC (rev 103759)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreator.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -28,4 +28,8 @@
    <T> T createProxyInstance(Class<T> proxyClass, MethodHandler interceptorMethodHandler);
 
    <T> MethodHandler createMethodHandler(Object target, Class<T> proxyClass, InterceptorMetadata interceptorMetadata);
+
+    <T> MethodHandler createSubclassingMethodHandler(Object target, 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-09 18:03:14 UTC (rev 103759)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorProxyCreatorImpl.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -18,6 +18,7 @@
 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;
@@ -56,10 +57,32 @@
 
    public <T> T createProxyFromInstance(final Object target, Class<T> proxifiedClass, Class<?>[] constructorTypes, Object[] constructorArguments, InterceptorMetadata interceptorClassMetadata)
    {
-      MethodHandler interceptorMethodHandler = createMethodHandler(target, proxifiedClass, interceptorClassMetadata);
+       MethodHandler interceptorMethodHandler = createMethodHandler(target, proxifiedClass, interceptorClassMetadata);
       return createProxyInstance(InterceptionUtils.createProxyClassWithHandler(proxifiedClass, interceptorMethodHandler), interceptorMethodHandler);
    }
 
+   public <T> T createProxyFromClass(Class<T> proxifiedClass, Class<?>[] constructorTypes, Object[] constructorArguments, InterceptorMetadata interceptorClassMetadata)
+   {
+      T instance = createAdvisedSubclassInstance(proxifiedClass, constructorTypes, constructorArguments);
+      MethodHandler interceptorMethodHandler = createSubclassingMethodHandler(instance, proxifiedClass, interceptorClassMetadata);
+      ((ProxyObject)instance).setHandler(interceptorMethodHandler);
+      return instance;
+   }
+
+   public <T> T createAdvisedSubclassInstance(Class<T> proxifiedClass, Class<?>[] constructorParameterTypes, Object[] constructorArguments)
+   {
+       try
+       {
+           Class<T> clazz = InterceptionUtils.createProxyClass(proxifiedClass, true);
+           Constructor<T> constructor = clazz.getConstructor(constructorParameterTypes);
+           return constructor.newInstance(constructorArguments);
+       }
+       catch (Exception e)
+       {
+           throw new InterceptorException(e);
+       }
+   }
+
    public <T> T createProxyInstance(Class<T> proxyClass, MethodHandler interceptorMethodHandler)
    {
       Constructor<T> constructor = null;
@@ -98,6 +121,12 @@
       return new InterceptorMethodHandler(target, proxyClass, getModelsFor(proxyClass), interceptionHandlerFactories, interceptorMetadata);
    }
 
+    public <T> MethodHandler createSubclassingMethodHandler(Object target, Class<T> proxyClass, InterceptorMetadata interceptorMetadata)
+    {
+       return new SubclassingInterceptorMethodHandler(target, proxyClass, getModelsFor(proxyClass), interceptionHandlerFactories, interceptorMetadata);
+    }
+
+
    private <T> List<InterceptionModel<Class<?>, ?>> getModelsFor(Class<T> proxyClass)
    {
       List<InterceptionModel<Class<?>, ?>> interceptionModels = new ArrayList<InterceptionModel<Class<?>, ?>>();

Copied: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java (from rev 103730, projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/InterceptorMethodHandler.java)
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java	                        (rev 0)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/proxy/SubclassingInterceptorMethodHandler.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -0,0 +1,141 @@
+package org.jboss.interceptor.proxy;
+
+import org.jboss.interceptor.model.InterceptionModel;
+import org.jboss.interceptor.model.InterceptionType;
+import org.jboss.interceptor.model.InterceptionTypeRegistry;
+import org.jboss.interceptor.model.InterceptorMetadata;
+import org.jboss.interceptor.util.InterceptionUtils;
+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.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Marius Bogoevici
+ */
+public class SubclassingInterceptorMethodHandler extends TargetInstanceProxyMethodHandler implements Serializable
+{
+
+   private Map<Object, InterceptionHandler> interceptorHandlerInstances = new HashMap<Object, InterceptionHandler>();
+   private InterceptorMetadata targetClassInterceptorMetadata;
+   private List<InterceptionModel<Class<?>, ?>> interceptionModels;
+
+   public SubclassingInterceptorMethodHandler(Object target, Class<?> targetClass, List<InterceptionModel<Class<?>, ?>> interceptionModels, List<InterceptionHandlerFactory<?>> interceptionHandlerFactories, InterceptorMetadata targetClassMetadata)
+   {
+      super(target, targetClass != null ? targetClass : target.getClass());
+      if (interceptionModels == null)
+      {
+         throw new IllegalArgumentException("Interception model must not be null");
+      }
+
+      if (interceptionHandlerFactories == null)
+      {
+         throw new IllegalArgumentException("Interception handler factory must not be null");
+      }
+
+      if (interceptionModels.size() != interceptionHandlerFactories.size())
+      {
+         throw new IllegalArgumentException("For each interception model, an interception factory must be provided");
+      }
+
+      this.interceptionModels = interceptionModels;
+
+      for (int i = 0; i < interceptionModels.size(); i++)
+      {
+         for (Object interceptorReference : this.interceptionModels.get(i).getAllInterceptors())
+         {
+            interceptorHandlerInstances.put(interceptorReference, ((InterceptionHandlerFactory) interceptionHandlerFactories.get(i)).createFor((Object) interceptorReference));
+         }
+      }
+      targetClassInterceptorMetadata = targetClassMetadata;
+   }
+
+   public Object doInvoke(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);
+         }
+         if (InterceptionTypeRegistry.supportsTimeoutMethods() && thisMethod.isAnnotationPresent(InterceptionTypeRegistry.getAnnotationClass(InterceptionType.AROUND_TIMEOUT)))
+         {
+            return executeInterception(proceed, thisMethod, args, InterceptionType.AROUND_TIMEOUT);
+         }
+         else
+         {
+            return executeInterception(proceed, thisMethod, args, InterceptionType.AROUND_INVOKE);
+         }
+      }
+      else
+      {
+         if (thisMethod.getName().equals(InterceptionUtils.POST_CONSTRUCT))
+         {
+            return executeInterception(null, null, null, InterceptionType.POST_CONSTRUCT);
+         }
+         else if (thisMethod.getName().equals(InterceptionUtils.PRE_DESTROY))
+         {
+            return executeInterception(null, null, null, InterceptionType.PRE_DESTROY);
+         }
+      }
+      return null;
+
+   }
+
+   private Object executeInterception(Method proceedingMethod, Method thisMethod, Object[] args, InterceptionType interceptionType) throws Throwable
+   {
+      List<InterceptionHandler> interceptionHandlers = new ArrayList<InterceptionHandler>();
+      for (InterceptionModel interceptionModel : interceptionModels)
+      {
+         List<?> interceptorList = interceptionModel.getInterceptors(interceptionType, thisMethod);
+         for (Object interceptorReference : interceptorList)
+         {
+            interceptionHandlers.add(interceptorHandlerInstances.get(interceptorReference));
+         }
+      }
+
+      if (targetClassInterceptorMetadata != null && targetClassInterceptorMetadata.getInterceptorMethods(interceptionType) != null && !targetClassInterceptorMetadata.getInterceptorMethods(interceptionType).isEmpty())
+      {
+         interceptionHandlers.add(new DirectClassInterceptionHandler<Class<?>>(getTargetInstance(), targetClassInterceptorMetadata));
+      }
+
+      InterceptionChain chain = new InterceptionChain(interceptionHandlers, interceptionType, getTargetInstance(), proceedingMethod, args);
+      return chain.invokeNext(new InterceptorInvocationContext(chain, getTargetInstance(), thisMethod, args));
+   }
+
+   private void writeObject(ObjectOutputStream objectOutputStream) throws IOException
+   {
+      try
+      {
+         executeInterception(null, null, null, InterceptionType.PRE_PASSIVATE);
+         objectOutputStream.defaultWriteObject();
+      }
+      catch (Throwable throwable)
+      {
+         throw new IOException("Error while serializing class", throwable);
+      }
+   }
+
+   private void readObject(ObjectInputStream objectInputStream) throws IOException
+   {
+      try
+      {
+         objectInputStream.defaultReadObject();
+         executeInterception(null, null, null, InterceptionType.POST_ACTIVATE);
+      }
+      catch (Throwable throwable)
+      {
+         throw new IOException("Error while deserializing class", throwable);
+      }
+   }
+
+}
\ No newline at end of file

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-09 18:03:14 UTC (rev 103759)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/InterceptionUtils.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -27,6 +27,7 @@
 import org.jboss.interceptor.proxy.LifecycleMixin;
 import org.jboss.interceptor.registry.InterceptorRegistry;
 import org.jboss.interceptor.InterceptorException;
+import org.jboss.interceptor.util.proxy.SubclassedProxy;
 import org.jboss.interceptor.util.proxy.TargetInstanceProxy;
 
 import org.slf4j.Logger;
@@ -126,6 +127,8 @@
    {
       // just a provisory implementation - any method which is not an interceptor method
       // is an interception candidate
+      if (method.getDeclaringClass().equals(Object.class))
+         return false;
       int modifiers = method.getModifiers();
       if (Modifier.isStatic(modifiers))
          return false;
@@ -255,7 +258,7 @@
 
    public static <T> T getRawInstance(T proxy)
    {
-      while (proxy instanceof TargetInstanceProxy)
+      while (proxy instanceof TargetInstanceProxy && !(proxy instanceof SubclassedProxy))
       {
          proxy = ((TargetInstanceProxy<T>)proxy).getTargetInstance();
       }
@@ -263,14 +266,17 @@
    }
 
 
-   public static <T> Class<T> createProxyClass(Class<T> proxyClass)
+   public static <T> Class<T> createProxyClass(Class<T> proxyClass, boolean forSubclassing)
    {
       ProxyFactory proxyFactory = new ProxyFactory();
       if (proxyClass != null)
       {
          proxyFactory.setSuperclass(proxyClass);
       }
-      proxyFactory.setInterfaces(new Class<?>[]{LifecycleMixin.class, TargetInstanceProxy.class});
+      if (forSubclassing)
+         proxyFactory.setInterfaces(new Class<?>[]{LifecycleMixin.class, TargetInstanceProxy.class, SubclassedProxy.class});
+      else
+         proxyFactory.setInterfaces(new Class<?>[]{LifecycleMixin.class, TargetInstanceProxy.class});
       Class<T> clazz = proxyFactory.createClass();
       return clazz;
    }

Added: projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/SubclassedProxy.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/SubclassedProxy.java	                        (rev 0)
+++ projects/interceptors/trunk/jboss-interceptor/src/main/java/org/jboss/interceptor/util/proxy/SubclassedProxy.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -0,0 +1,12 @@
+package org.jboss.interceptor.util.proxy;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: marius
+ * Date: Apr 9, 2010
+ * Time: 1:57:31 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface SubclassedProxy
+{
+}

Modified: projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/FootballTeam.java
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/FootballTeam.java	2010-04-09 18:03:14 UTC (rev 103759)
+++ projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/FootballTeam.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -17,15 +17,11 @@
 
 package org.jboss.interceptors.proxy;
 
-import java.io.Serializable;
-
-import org.jboss.interceptors.proxy.InterceptorTestLogger;
-
 import javax.annotation.PostConstruct;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
 import javax.interceptor.AroundInvoke;
 import javax.interceptor.InvocationContext;
-import javax.ejb.PrePassivate;
-import javax.ejb.PostActivate;
 
 /**
  * @author <a href="mailto:mariusb at redhat.com">Marius Bogoevici</a>
@@ -35,12 +31,7 @@
 
    private String teamName;
 
-    // an empty-argument constructor is required for proxifycation
-    public FootballTeam() {
-
-    }
-
-    public FootballTeam(String s) {
+   public FootballTeam(String s) {
         this.teamName = s;
     }
 

Copied: projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java (from rev 103730, projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/InterceptionTestCase.java)
===================================================================
--- projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java	                        (rev 0)
+++ projects/interceptors/trunk/jboss-interceptor/src/test/java/org/jboss/interceptors/proxy/SubclassingInterceptionTestCase.java	2010-04-09 18:13:09 UTC (rev 103760)
@@ -0,0 +1,415 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed 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.jboss.interceptors.proxy;
+
+import javassist.util.proxy.MethodHandler;
+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.registry.InterceptorMetadataRegistry;
+import org.jboss.interceptor.registry.InterceptorRegistry;
+import org.jboss.interceptor.registry.SimpleClassMetadataReader;
+import org.jboss.interceptor.util.InterceptionUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * @author <a href="mailto:mariusb at redhat.com">Marius Bogoevici</a>
+ */
+public class SubclassingInterceptionTestCase
+{
+   private static final String TEAM_NAME = "Ajax Amsterdam";
+
+   private String[] expectedLoggedValues = {
+         "org.jboss.interceptors.proxy.FirstInterceptor_postConstruct",
+         "org.jboss.interceptors.proxy.Team_postConstruct",
+         "org.jboss.interceptors.proxy.FootballTeam_postConstruct",
+         "org.jboss.interceptors.proxy.FirstInterceptor_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.SecondInterceptor_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.FootballTeam_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.FootballTeam_getName",
+         "org.jboss.interceptors.proxy.FootballTeam_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.SecondInterceptor_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.FirstInterceptor_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.SecondInterceptor_preDestroy"
+   };
+
+   private String[] expectedLoggedValuesWithGlobalsIgnored = {
+         "org.jboss.interceptors.proxy.FirstInterceptor_postConstruct",
+         "org.jboss.interceptors.proxy.Team_postConstruct",
+         "org.jboss.interceptors.proxy.FootballTeam_postConstruct",
+         "org.jboss.interceptors.proxy.SecondInterceptor_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.FootballTeam_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.FootballTeam_getName",
+         "org.jboss.interceptors.proxy.FootballTeam_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.SecondInterceptor_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.SecondInterceptor_preDestroy"
+   };
+
+   private String[] expectedLoggedValuesOnSerialization = {
+         "org.jboss.interceptors.proxy.FirstInterceptor_postConstruct",
+         "org.jboss.interceptors.proxy.Team_postConstruct",
+         "org.jboss.interceptors.proxy.FootballTeam_postConstruct",
+         "org.jboss.interceptors.proxy.FootballTeam_prePassivating",
+         "org.jboss.interceptors.proxy.FootballTeam_postActivating",
+         "org.jboss.interceptors.proxy.FirstInterceptor_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.SecondInterceptor_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.FootballTeam_aroundInvokeBefore",
+         "org.jboss.interceptors.proxy.FootballTeam_getName",
+         "org.jboss.interceptors.proxy.FootballTeam_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.SecondInterceptor_aroundInvokeAfter",
+         "org.jboss.interceptors.proxy.FirstInterceptor_aroundInvokeAfter",
+   };
+
+   private String[] expectedLoggedValuesWhenRaw = {
+         "org.jboss.interceptors.proxy.FootballTeam_getName",
+   };
+
+   private InterceptorRegistry<Class<?>, Class<?>> interceptorRegistry;
+
+   private DirectClassInterceptionHandlerFactory interceptionHandlerFactory;
+
+   private InterceptorMetadataRegistry interceptorMetadataRegistry;
+
+   @Before
+   public void setUp()
+   {
+      interceptorMetadataRegistry = new InterceptorMetadataRegistry(SimpleClassMetadataReader.getInstance());
+      interceptionHandlerFactory = new DirectClassInterceptionHandlerFactory(interceptorMetadataRegistry);
+   }
+
+   public void resetLogAndSetupClassesForMethod() throws Exception
+   {
+      InterceptorTestLogger.reset();
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("getName")).with(FirstInterceptor.class, SecondInterceptor.class);
+      builder.interceptPostConstruct().with(FirstInterceptor.class);
+      builder.interceptPreDestroy().with(SecondInterceptor.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel;
+      interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+   }
+
+   public void resetLogAndSetupClassesGlobally() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAll().with(FirstInterceptor.class, SecondInterceptor.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel;
+      interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+   }
+
+   public void resetLogAndSetupClassesMixed() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+      builder.interceptAll().with(FirstInterceptor.class);
+      builder.interceptPreDestroy().with(SecondInterceptor.class);
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("getName")).with(SecondInterceptor.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel;
+      interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+   }
+
+   public void resetLogAndSetupClassesWithGlobalsIgnored() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+      builder.interceptAll().with(FirstInterceptor.class);
+      builder.interceptPreDestroy().with(SecondInterceptor.class);
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("getName")).with(SecondInterceptor.class);
+      builder.ignoreGlobalInterceptors(FootballTeam.class.getMethod("getName"));
+      InterceptionModel<Class<?>, Class<?>> interceptionModel;
+      interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+   }
+
+
+   @Test
+   public void testInterceptionWithMethodRegisteredInterceptors() throws Exception
+   {
+      resetLogAndSetupClassesForMethod();
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      InterceptionUtils.executePostConstruct(proxy);
+      Assert.assertEquals(TEAM_NAME, proxy.getName());
+      InterceptionUtils.executePredestroy(proxy);
+      Object[] logValues = InterceptorTestLogger.getLog().toArray();
+      Assert.assertArrayEquals(iterateAndDisplay(logValues), expectedLoggedValues, logValues);
+      assertRawObject(proxy);
+   }
+
+   @Test
+   public void testInterceptionWithGlobalInterceptors() throws Exception
+   {
+      resetLogAndSetupClassesGlobally();
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      InterceptionUtils.executePostConstruct(proxy);
+      Assert.assertEquals(TEAM_NAME, proxy.getName());
+      InterceptionUtils.executePredestroy(proxy);
+      assertRawObject(proxy);
+   }
+
+   @Test
+   public void testInterceptionWithMixedInterceptors() throws Exception
+   {
+      resetLogAndSetupClassesMixed();
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      InterceptionUtils.executePostConstruct(proxy);
+      Assert.assertEquals(TEAM_NAME, proxy.getName());
+      InterceptionUtils.executePredestroy(proxy);
+      Object[] logValues = InterceptorTestLogger.getLog().toArray();
+      Assert.assertArrayEquals(iterateAndDisplay(logValues), expectedLoggedValues, logValues);
+      assertRawObject(proxy);
+   }
+
+   @Test
+   public void testInterceptionWithGlobalsIgnored() throws Exception
+   {
+      resetLogAndSetupClassesWithGlobalsIgnored();
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      InterceptionUtils.executePostConstruct(proxy);
+      Assert.assertEquals(TEAM_NAME, proxy.getName());
+      InterceptionUtils.executePredestroy(proxy);
+      Object[] logValues = InterceptorTestLogger.getLog().toArray();
+      Assert.assertArrayEquals(iterateAndDisplay(logValues), expectedLoggedValuesWithGlobalsIgnored, logValues);
+      assertRawObject(proxy);
+   }
+
+
+   @Test
+   public void testInterceptionWithSerializedProxy() throws Exception
+   {
+      resetLogAndSetupClassesForMethod();
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      InterceptionUtils.executePostConstruct(proxy);
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      new ObjectOutputStream(baos).writeObject(proxy);
+      proxy = (FootballTeam) new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())).readObject();
+      Assert.assertEquals(TEAM_NAME, proxy.getName());
+      Object[] logValues = InterceptorTestLogger.getLog().toArray();
+      Assert.assertArrayEquals(iterateAndDisplay(logValues), expectedLoggedValuesOnSerialization, logValues);
+      assertRawObject(proxy);
+   }
+
+
+   @Test
+   public void testMethodParameterOverriding() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echo", String.class)).with(ParameterOverridingInterceptor.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(42, proxy.echo("1"));
+   }
+
+   @Test
+   public void testMethodParameterOverridingWithPrimitive() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoInt", int.class)).with(ParameterOverridingInterceptorWithInteger.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(42, proxy.echoInt(1));
+   }
+
+   @Test(expected = IllegalArgumentException.class)
+   public void testMethodParameterOverridingWithObject() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoLongAsObject", Long.class)).with(ParameterOverridingInterceptorWithInteger.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(new Long(42), proxy.echoLongAsObject(1l));
+   }
+
+   @Test
+   public void testMethodParameterOverridingWithObjectSucceed() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoLongAsObject", Long.class)).with(ParameterOverridingInterceptorWithLong.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(new Long(42), proxy.echoLongAsObject(1l));
+   }
+
+   @Test
+   public void testMethodParameterOverridingWithPrimitiveWidening() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoLong", long.class)).with(ParameterOverridingInterceptorWithInteger.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(42, proxy.echoLong(1));
+   }
+
+   @Test(expected = IllegalArgumentException.class)
+   public void testMethodParameterOverridingWithPrimitiveNarrowing() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoInt", int.class)).with(ParameterOverridingInterceptorWithLong.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(42, proxy.echoInt(1));
+   }
+
+   @Test
+   public void testMethodParameterOverridingWithArray() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoObjectArray", Object[].class)).with(ParameterOverridingInterceptorWithLongArray.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(new Long[]{42l}, proxy.echoObjectArray(new Object[]{}));
+   }
+
+   @Test(expected = IllegalArgumentException.class)
+   public void testMethodParameterOverridingWithArrayOnString() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echoStringArray", String[].class)).with(ParameterOverridingInterceptorWithLongArray.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      this.interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      Assert.assertEquals(new Long[]{42l}, proxy.echoStringArray(new String[]{}));
+   }
+
+   @Test
+   public void testMethodParameterOverridingWithSubclass() throws Exception
+   {
+      InterceptorTestLogger.reset();
+
+
+      InterceptionModelBuilder<Class<?>, Class<?>> builder = InterceptionModelBuilder.newBuilderFor(FootballTeam.class, (Class) Class.class);
+
+      builder.interceptAroundInvoke(FootballTeam.class.getMethod("echo2", ValueBearer.class)).with(ParameterOverridingInterceptor2.class);
+      InterceptionModel<Class<?>, Class<?>> interceptionModel = builder.build();
+      this.interceptorRegistry = new InterceptorRegistry<Class<?>, Class<?>>();
+      interceptorRegistry.registerInterceptionModel(FootballTeam.class, interceptionModel);
+
+      FootballTeam proxy = createAdvisedInstance(FootballTeam.class, TEAM_NAME);
+      proxy.doNothing();
+      Assert.assertEquals(42, proxy.echo2(new ValueBearerImpl(1)));
+   }
+
+   public void assertRawObject(FootballTeam proxy)
+   {
+//      InterceptorTestLogger.reset();
+//      FootballTeam rawInstance = InterceptionUtils.getRawInstance(proxy);
+//      Assert.assertEquals(TEAM_NAME, rawInstance.getName());
+//      Object[] logValues = InterceptorTestLogger.getLog().toArray();
+//      Assert.assertArrayEquals(iterateAndDisplay(logValues), expectedLoggedValuesWhenRaw, logValues);logValues
+   }
+
+   private String iterateAndDisplay(Object[] logValues)
+   {
+      StringBuffer buffer = new StringBuffer();
+      for (Object logValue : logValues)
+      {
+         buffer.append(logValue.toString()).append("\n");
+      }
+      return buffer.toString();
+   }
+
+   private <T> T createAdvisedInstance(Class<? extends T> targetClass, Object... args) throws Exception
+   {
+       return createAdvisedSubclassedInstance(targetClass, args);
+   }
+
+   private <T> T createAdvisedSubclassedInstance(Class<? extends T> targetClass, Object... args)
+   {
+      InterceptorProxyCreator ipc = new InterceptorProxyCreatorImpl(interceptorRegistry, interceptionHandlerFactory);
+      return ipc.createProxyFromClass(targetClass, new Class<?>[]{String.class},args, interceptorMetadataRegistry.getInterceptorClassMetadata(ReflectiveClassReference.of(targetClass), true));
+   }
+
+   private <T> T createAdvisedProxifiedInstance(Class<? extends T> targetClass, Object... args) throws Exception
+   {
+      T instance = targetClass.getConstructor(String.class).newInstance(args);
+      InterceptorProxyCreator ipc = new InterceptorProxyCreatorImpl(interceptorRegistry, interceptionHandlerFactory);
+      MethodHandler methodHandler = ipc.createMethodHandler(instance, targetClass, interceptorMetadataRegistry.getInterceptorClassMetadata(ReflectiveClassReference.of(targetClass), true));
+      return ipc.createProxyInstance(InterceptionUtils.createProxyClassWithHandler(targetClass, methodHandler), methodHandler);
+   }
+}
\ No newline at end of file




More information about the jboss-cvs-commits mailing list