[jboss-cvs] JBossAS SVN: r80963 - in projects/ejb3/trunk/common/src: main/java/org/jboss/ejb3/common/proxy and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Nov 13 16:52:00 EST 2008


Author: ALRubinger
Date: 2008-11-13 16:52:00 -0500 (Thu, 13 Nov 2008)
New Revision: 80963

Added:
   projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/
   projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainableProcessor.java
   projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainedProcessingInvocationHandler.java
   projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ProxyUtils.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/AddOneProcessor.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Addable.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/CalculatorServiceBean.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/ChangeInputProcessor.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Multipliable.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/MultiplyMixinProcessor.java
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/unit/
   projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/unit/InvocationHandlerChainTestCase.java
Log:
[EJBTHREE-1589] Add a generic runtime mixin mechanism (and tests)

Added: projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainableProcessor.java
===================================================================
--- projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainableProcessor.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainableProcessor.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.common.proxy;
+
+import java.lang.reflect.Method;
+
+
+/**
+ * ChainableInvocationHandler
+ * 
+ * An InvocationHandler that is chain-aware.  May perform
+ * its own processing before, after, or ignoring the rest of the 
+ * InvocationHandlers in the chain of which it is a part
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface ChainableProcessor
+{
+   /**
+    * Invokes this handler with the specified arguments.  Processing
+    * may be performed before or after the rest of the chain depending 
+    * upon when "chain.invokeNext()" is executed.
+    * 
+    * @param chain
+    * @param proxy
+    * @param method
+    * @param args
+    * @exception Throwable
+    * @return
+    */
+   Object invoke(ChainedProcessingInvocationHandler chain, Object proxy, Method method, Object[] args) throws Throwable;
+}

Added: projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainedProcessingInvocationHandler.java
===================================================================
--- projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainedProcessingInvocationHandler.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ChainedProcessingInvocationHandler.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,159 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.common.proxy;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * ChainedProcessingInvocationHandler
+ * 
+ * A Chain of Processors which may be invoked in
+ * succession.  At the end of the chain is an underlying 
+ * delegate instance to be invoked via reflection.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ChainedProcessingInvocationHandler implements InvocationHandler
+{
+   // ------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * The underlying delegate to be invoked when the chain has exhausted
+    */
+   private Object delegate;
+
+   /**
+    * A Chain of Processors
+    */
+   private ChainableProcessor[] processorChain;
+
+   /**
+    * Internal counter for the next handler to be invoked
+    */
+   private int nextHandlerIndex = 0;
+
+   // ------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   public ChainedProcessingInvocationHandler(Object delegate, ChainableProcessor[] handlerChain)
+   {
+      // Precondition check
+      assert delegate != null : "Requiste delegate was not supplied";
+
+      // Set specified properties
+      this.setDelegate(delegate);
+      this.setHandlerChain(handlerChain);
+   }
+
+   // ------------------------------------------------------------------------------||
+   // Functional Methods -----------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * Invokes the next processor in the chain with the 
+    * specified arguments.  In the event we've reached the end of the chain,
+    * the underlying delegate will be invoked via reflection
+    * 
+    * @param proxy
+    * @param method
+    * @param args
+    * @exception Throwable
+    * @return
+    */
+   public Object invokeNext(Object proxy, Method method, Object[] args) throws Throwable
+   {
+      // Initialize
+      Object returnValue = null;
+
+      // If no more handlers in the chain
+      if (this.getHandlerChain().length <= this.getNextHandlerIndex())
+      {
+         // Get the delegate
+         Object delegate = this.getDelegate();
+
+         // Ensure the delegate is supplied
+         assert delegate != null : "Requiste delegate was not supplied";
+
+         // Use reflection to pass the invocation to the delegate
+         return method.invoke(delegate, args);
+      }
+      // More handlers are present in the chain
+      else
+      {
+         // Invoke upon the next handler in the chain
+         returnValue = this.getHandlerChain()[this.nextHandlerIndex++].invoke(this, proxy, method, args);
+      }
+
+      // Return
+      return returnValue;
+   }
+
+   // ------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * Provides a base invocation mechanism under which the request
+    * is passed along to the delegate instance
+    */
+   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+   {
+      // Start the chain
+      return this.invokeNext(proxy, method, args);
+   }
+
+   // ------------------------------------------------------------------------------||
+   // Accessors / Mutators ---------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   protected Object getDelegate()
+   {
+      return delegate;
+   }
+
+   protected void setDelegate(Object delegate)
+   {
+      this.delegate = delegate;
+   }
+
+   protected ChainableProcessor[] getHandlerChain()
+   {
+      return processorChain == null ? new ChainableProcessor[]
+      {} : processorChain;
+   }
+
+   protected void setHandlerChain(ChainableProcessor[] handlerChain)
+   {
+      this.processorChain = handlerChain;
+   }
+
+   protected int getNextHandlerIndex()
+   {
+      return nextHandlerIndex;
+   }
+
+}

Added: projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ProxyUtils.java
===================================================================
--- projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ProxyUtils.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/main/java/org/jboss/ejb3/common/proxy/ProxyUtils.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.common.proxy;
+
+import java.lang.reflect.Proxy;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+
+/**
+ * ProxyUtils
+ * 
+ * Common Utility methods for use with the Proxies
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ProxyUtils
+{
+
+   // --------------------------------------------------------------------------------||
+   // Class Members ------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(ProxyUtils.class);
+
+   // --------------------------------------------------------------------------------||
+   // Constructor --------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * In place to enforce noninstantiability
+    */
+   private ProxyUtils()
+   {
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Utility Methods ----------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Wraps the existing Proxy in a new Proxy to extend functionality, adding 
+    * support of the specified interfaces via the specified 
+    * ChainedProcessingInvocationHandler
+    * (which contains a chain of processors)
+    * 
+    * May be used to, at runtime, extend a service
+    */
+   public static Object mixinProxy(Object delegate, Class<?>[] additionalInterfaces,
+         ChainedProcessingInvocationHandler chain)
+   {
+      // Initialize
+      Set<Class<?>> newInterfaces = new HashSet<Class<?>>();
+      Object newProxy = null;
+
+      // Get the interfaces supported by the existing proxy
+      Class<?>[] existingInterfaces = delegate.getClass().getInterfaces();
+
+      // Add all existing interfaces to those we'll support in our wrapped Proxy
+      for (Class<?> interfaze : existingInterfaces)
+      {
+         newInterfaces.add(interfaze);
+      }
+
+      // Add the new interfaces, if supplied
+      if (additionalInterfaces != null)
+      {
+         for (Class<?> interfaze : additionalInterfaces)
+         {
+            newInterfaces.add(interfaze);
+         }
+      }
+
+      // Make a new Proxy, using the Chain as the handler
+      newProxy = Proxy.newProxyInstance(delegate.getClass().getClassLoader(), newInterfaces.toArray(new Class<?>[]
+      {}), chain);
+
+      // Return
+      return newProxy;
+   }
+
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/AddOneProcessor.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/AddOneProcessor.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/AddOneProcessor.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy;
+
+import java.lang.reflect.Method;
+
+import org.jboss.ejb3.common.proxy.ChainableProcessor;
+import org.jboss.ejb3.common.proxy.ChainedProcessingInvocationHandler;
+
+/**
+ * AddOneProcessor
+ * 
+ * A test ChainableProcessor which adds a value of 1
+ * to the result
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class AddOneProcessor implements ChainableProcessor
+{
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.proxy.intf.ChainableInvocationHandler#invoke(org.jboss.ejb3.proxy.handler.ChainInvocationHandler, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+    */
+   public Object invoke(ChainedProcessingInvocationHandler chain, Object proxy, Method method, Object[] args) throws Throwable
+   {
+      // Send along to the rest of the chain
+      Object result = chain.invokeNext(proxy, method, args);
+
+      // Add 1
+      int newValue = ((Integer) result) + 1;
+
+      // Return
+      return newValue;
+   }
+
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Addable.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Addable.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Addable.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy;
+
+/**
+ * Addable
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface Addable
+{
+   // ------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * Returns the sum of the specified arguments
+    */
+   int add(int... args);
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/CalculatorServiceBean.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/CalculatorServiceBean.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/CalculatorServiceBean.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy;
+
+/**
+ * CalculatorServiceBean
+ * 
+ * Implementation of a test service that has 
+ * functions to perform simple calculations
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class CalculatorServiceBean implements Addable
+{
+   // ------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * Returns the sum of the specified arguments
+    */
+   public int add(int... args)
+   {
+      // Initialize
+      int result = 0;
+
+      // Add all arguments
+      for (int arg : args)
+      {
+         result += arg;
+      }
+
+      // Return
+      return result;
+   }
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/ChangeInputProcessor.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/ChangeInputProcessor.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/ChangeInputProcessor.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy;
+
+import java.lang.reflect.Method;
+
+import org.jboss.ejb3.common.proxy.ChainableProcessor;
+import org.jboss.ejb3.common.proxy.ChainedProcessingInvocationHandler;
+
+/**
+ * ChangeInputProcessor
+ * 
+ * A test ChainableProcessor which ignores the 
+ * specified input and replaces it with that specified
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ChangeInputProcessor implements ChainableProcessor
+{
+   /**
+    * Backing arguments to use
+    */
+   private int[] args;
+
+   public ChangeInputProcessor(int[] args)
+   {
+      this.args = args;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.proxy.intf.ChainableInvocationHandler#invoke(org.jboss.ejb3.proxy.handler.ChainInvocationHandler, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+    */
+   public Object invoke(ChainedProcessingInvocationHandler chain, Object proxy, Method method, Object[] args) throws Throwable
+   {
+      // Define new arguments
+      args = new Object[]
+      {this.args};
+
+      // Send along to the rest of the chain, passing overridden argument
+      return chain.invokeNext(proxy, method, args);
+   }
+
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Multipliable.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Multipliable.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/Multipliable.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy;
+
+/**
+ * Multipliable
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface Multipliable
+{
+   // ------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * Returns the product of the specified arguments
+    */
+   int multiply(int... args);
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/MultiplyMixinProcessor.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/MultiplyMixinProcessor.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/MultiplyMixinProcessor.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy;
+
+import java.lang.reflect.Method;
+
+import org.jboss.ejb3.common.proxy.ChainableProcessor;
+import org.jboss.ejb3.common.proxy.ChainedProcessingInvocationHandler;
+
+/**
+ * MultiplyMixinInvocationHandler
+ * 
+ * A test ChainableInvocationHandler which ignores the 
+ * specified input and replaces it with that specified
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class MultiplyMixinProcessor implements ChainableProcessor, Multipliable
+{
+
+   // ------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * The method we'll intercept and handle
+    */
+   private static final Method MULTIPLY_METHOD;
+   static
+   {
+      try
+      {
+         MULTIPLY_METHOD = Multipliable.class.getMethod("multiply", new Class<?>[]
+         {int[].class});
+      }
+      catch (NoSuchMethodException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   // ------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.proxy.intf.ChainableInvocationHandler#invoke(org.jboss.ejb3.proxy.handler.ChainInvocationHandler, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+    */
+   public Object invoke(ChainedProcessingInvocationHandler chain, Object proxy, Method method, Object[] args)
+         throws Throwable
+   {
+      // Do we handle this invocation?
+      if (this.handlesInvocation(proxy, method, args))
+      {
+         // Invoke
+         return new Integer(this.multiply((int[]) args[0]));
+      }
+      // We don't handle the invocation, send along the chain
+      else
+      {
+         return chain.invokeNext(proxy, method, args);
+      }
+
+   }
+
+   /**
+    * Returns the product of the specified arguments
+    */
+   public int multiply(int... args)
+   {
+      // Initialize
+      int result = 1;
+
+      // For each argument, get the product
+      for (int arg : args)
+      {
+         result *= arg;
+      }
+
+      // Return
+      return result;
+
+   }
+
+   // ------------------------------------------------------------------------------||
+   // Internal Helper Methods  -----------------------------------------------------||
+   // ------------------------------------------------------------------------------||
+
+   /**
+    * Determines whether this processor may handle the invocation
+    */
+   private boolean handlesInvocation(Object proxy, Method method, Object[] args)
+   {
+      /*
+       * Determine if we'll handle this invocation
+       */
+      if (method.equals(MULTIPLY_METHOD))
+      {
+         return true;
+      }
+
+      // Did not meet requirements
+      return false;
+   }
+
+}

Added: projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/unit/InvocationHandlerChainTestCase.java
===================================================================
--- projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/unit/InvocationHandlerChainTestCase.java	                        (rev 0)
+++ projects/ejb3/trunk/common/src/test/java/org/jboss/ejb3/test/common/proxy/unit/InvocationHandlerChainTestCase.java	2008-11-13 21:52:00 UTC (rev 80963)
@@ -0,0 +1,214 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.common.proxy.unit;
+
+import junit.framework.TestCase;
+
+import org.jboss.ejb3.common.proxy.ChainableProcessor;
+import org.jboss.ejb3.common.proxy.ChainedProcessingInvocationHandler;
+import org.jboss.ejb3.common.proxy.ProxyUtils;
+import org.jboss.ejb3.test.common.proxy.AddOneProcessor;
+import org.jboss.ejb3.test.common.proxy.Addable;
+import org.jboss.ejb3.test.common.proxy.CalculatorServiceBean;
+import org.jboss.ejb3.test.common.proxy.ChangeInputProcessor;
+import org.jboss.ejb3.test.common.proxy.Multipliable;
+import org.jboss.ejb3.test.common.proxy.MultiplyMixinProcessor;
+import org.jboss.logging.Logger;
+import org.junit.Test;
+
+/**
+ * InvocationHandlerChainTestCase
+ *
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class InvocationHandlerChainTestCase
+{
+   // --------------------------------------------------------------------------------||
+   // Class Members ------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   private static final Logger log = Logger.getLogger(InvocationHandlerChainTestCase.class);
+
+   // --------------------------------------------------------------------------------||
+   // Tests --------------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * The control for this test; passes along a simple invocation
+    * to the calculator service and checks the result as expected
+    */
+   @Test
+   public void testCalculatorServiceControl() throws Exception
+   {
+      // Initialize
+      Addable calc = new CalculatorServiceBean();
+      int[] args =
+      {1, 2, 3};
+
+      // Get the result from the service
+      int result = calc.add(args);
+
+      // Calculate the expected result
+      int expected = this.add(args);
+
+      // Test
+      TestCase.assertEquals("Control test for the CalculatorService failed", expected, result);
+
+   }
+
+   /**
+    * Tests that introducing an invocation handler to add 1
+    * to the result of the calculator service succeeds as expected
+    */
+   @Test
+   public void testCalculatorServiceInChain() throws Exception
+   {
+      // Initialize
+      Addable calc = new CalculatorServiceBean();
+      int[] args =
+      {1, 2, 3};
+
+      // Make the chain
+      ChainedProcessingInvocationHandler chain = new ChainedProcessingInvocationHandler(calc, new ChainableProcessor[]
+      {new AddOneProcessor()});
+
+      // Apply the chain
+      Addable newCalc = (Addable) ProxyUtils.mixinProxy(calc, null, chain);
+
+      // Get the result from the service
+      int result = newCalc.add(args);
+
+      // Calculate the expected result (adding all, plus 1)
+      int expected = this.add(args) + 1;
+
+      // Test
+      TestCase.assertEquals("Chain Invocation Handler did not work as expected", expected, result);
+
+   }
+
+   /**
+    * Tests that introducing more than one invocation handler in a chain
+    * succeeds as expected
+    */
+   @Test
+   public void testCalculatorServiceInMultiHandlerChain() throws Exception
+   {
+      // Initialize
+      Addable calc = new CalculatorServiceBean();
+      int[] args =
+      {1, 2, 3};
+      int[] overrideArgs =
+      {5, 10};
+
+      // Make the chain
+      ChainedProcessingInvocationHandler chain = new ChainedProcessingInvocationHandler(calc, new ChainableProcessor[]
+      {new ChangeInputProcessor(overrideArgs), new AddOneProcessor()});
+
+      // Mix it up
+      Addable newCalc = (Addable) ProxyUtils.mixinProxy(calc, null, chain);
+
+      // Get the result from the service
+      int result = newCalc.add(args);
+
+      // Calculate the expected result (overriden arguments sum, plus 1)
+      int expected = this.add(overrideArgs) + 1;
+
+      // Test
+      TestCase.assertEquals("Chain Invocation Handler in multi-processor chain did not work as expected", expected,
+            result);
+
+   }
+
+   /**
+    * Tests that a mixin-like introduction succeeds 
+    */
+   @Test
+   public void testCalculatorServiceAddingMixin() throws Exception
+   {
+      // Initialize
+      Addable calc = new CalculatorServiceBean();
+      int[] args =
+      {4, 7, 2};
+
+      // Make the chain
+      ChainedProcessingInvocationHandler chain = new ChainedProcessingInvocationHandler(calc, new ChainableProcessor[]
+      {new MultiplyMixinProcessor()});
+
+      // Mix it up
+      Multipliable newCalc = (Multipliable) ProxyUtils.mixinProxy(calc, new Class<?>[]
+      {Multipliable.class}, chain);
+
+      // Get the result from the service
+      int result = newCalc.multiply(args);
+
+      // Calculate the expected result (product of arguments)
+      int expected = this.multiply(args);
+
+      // Test
+      TestCase.assertEquals("Chain Invocation Handler did not work as expected", expected, result);
+      log.info("Arguments " + args + " multiplied got expected result: " + result);
+
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Internal Helper Methods --------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Adds all arguments
+    */
+   protected int add(int... args)
+   {
+      // Initialize
+      int returnValue = 0;
+
+      // Add all arguments
+      for (int arg : args)
+      {
+         returnValue += arg;
+      }
+
+      // Return
+      return returnValue;
+   }
+
+   /**
+    * Multiplies all arguments
+    */
+   protected int multiply(int... args)
+   {
+      // Initialize
+      int returnValue = 1;
+
+      // Add all arguments
+      for (int arg : args)
+      {
+         returnValue *= arg;
+      }
+
+      // Return
+      return returnValue;
+   }
+
+}




More information about the jboss-cvs-commits mailing list