Author: jcarman
Date: Sat May 24 07:56:53 2008
New Revision: 659831

URL: http://svn.apache.org/viewvc?rev=659831&view=rev
Log:
Implemented a "chain" invoker.  Also moved getDefaultValue() method to 
ProxyUtils to avoid code duplication.

Added:
    
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java
    
commons/proper/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java
Modified:
    
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/ProxyUtils.java
    
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java

Modified: 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/ProxyUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/ProxyUtils.java?rev=659831&r1=659830&r2=659831&view=diff
==============================================================================
--- 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/ProxyUtils.java
 (original)
+++ 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/ProxyUtils.java
 Sat May 24 07:56:53 2008
@@ -39,6 +39,7 @@
     public static final Object[] EMPTY_ARGUMENTS = new Object[0];
     public static final Class[] EMPTY_ARGUMENT_TYPES = new Class[0];
     private static final Map wrapperClassMap = new HashMap();
+    public static Map defaultValueMap = new HashMap();
 
 
//**********************************************************************************************************************
 // Static Methods
@@ -56,6 +57,18 @@
         wrapperClassMap.put(Byte.TYPE, Byte.class);
     }
 
+    static
+    {
+        defaultValueMap.put(Integer.TYPE, new Integer(0));
+        defaultValueMap.put(Long.TYPE, new Long(0));
+        defaultValueMap.put(Short.TYPE, new Short(( short ) 0));
+        defaultValueMap.put(Byte.TYPE, new Byte(( byte ) 0));
+        defaultValueMap.put(Float.TYPE, new Float(0.0f));
+        defaultValueMap.put(Double.TYPE, new Double(0.0));
+        defaultValueMap.put(Character.TYPE, new Character(( char ) 0));
+        defaultValueMap.put(Boolean.TYPE, Boolean.FALSE);
+    }
+
     /**
      * Creates a "null object" which implements the <code>proxyClasses</code>.
      *
@@ -152,5 +165,22 @@
     {
         return ( Class ) wrapperClassMap.get(primitiveType);
     }
+
+    /**
+     * Returns the default value (null, zero, false) for a specified type.
+     * @param type the type
+     * @return the default value
+     */
+    public static Object getDefaultValue(Class type)
+    {
+        if( type.isPrimitive() )
+        {
+            return defaultValueMap.get(type);
+        }
+        else
+        {
+            return null;
+        }
+    }
 }
 

Added: 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java
URL: 
http://svn.apache.org/viewvc/commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java?rev=659831&view=auto
==============================================================================
--- 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java
 (added)
+++ 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/ChainInvoker.java
 Sat May 24 07:56:53 2008
@@ -0,0 +1,38 @@
+package org.apache.commons.proxy.invoker;
+
+import org.apache.commons.proxy.Invoker;
+import org.apache.commons.proxy.ProxyUtils;
+
+import java.lang.reflect.Method;
+
+/**
+ * A chain invoker will invoke the method on each object in the chain until 
one of them
+ * returns a non-default value
+ *
+ * @author James Carman
+ * @since 1.1
+ */
+public class ChainInvoker implements Invoker
+{
+    private final Object[] targets;
+
+    public ChainInvoker(Object[] targets)
+    {
+        this.targets = targets;
+    }
+
+    public Object invoke(Object proxy, Method method, Object[] arguments) 
throws Throwable
+    {
+        for (int i = 0; i < targets.length; i++)
+        {
+            Object target = targets[i];
+            Object value = method.invoke(target, arguments);
+            if (value != null && 
!value.equals(ProxyUtils.getDefaultValue(method.getReturnType())))
+            {
+                return value;
+            }
+        }
+        return ProxyUtils.getDefaultValue(method.getReturnType());
+    }
+}
+

Modified: 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java
URL: 
http://svn.apache.org/viewvc/commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java?rev=659831&r1=659830&r2=659831&view=diff
==============================================================================
--- 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java
 (original)
+++ 
commons/proper/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/NullInvoker.java
 Sat May 24 07:56:53 2008
@@ -18,11 +18,10 @@
 package org.apache.commons.proxy.invoker;
 
 import org.apache.commons.proxy.Invoker;
+import org.apache.commons.proxy.ProxyUtils;
 
 import java.io.Serializable;
 import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * An [EMAIL PROTECTED] Invoker} implementation which merely returns null for 
all method invocations.  This class is
@@ -34,42 +33,14 @@
 public class NullInvoker implements Invoker, Serializable
 {
 
//**********************************************************************************************************************
-// Fields
-//**********************************************************************************************************************
-
-    private static Map primitiveValueMap = new HashMap();
-
-//**********************************************************************************************************************
-// Static Methods
-//**********************************************************************************************************************
-
-    static
-    {
-        primitiveValueMap.put(Integer.TYPE, new Integer(0));
-        primitiveValueMap.put(Long.TYPE, new Long(0));
-        primitiveValueMap.put(Short.TYPE, new Short(( short ) 0));
-        primitiveValueMap.put(Byte.TYPE, new Byte(( byte ) 0));
-        primitiveValueMap.put(Float.TYPE, new Float(0.0f));
-        primitiveValueMap.put(Double.TYPE, new Double(0.0));
-        primitiveValueMap.put(Character.TYPE, new Character(( char ) 0));
-        primitiveValueMap.put(Boolean.TYPE, Boolean.FALSE);
-    }
-
-//**********************************************************************************************************************
 // Invoker Implementation
 
//**********************************************************************************************************************
 
     public Object invoke( Object proxy, Method method, Object[] args ) throws 
Throwable
     {
         final Class returnType = method.getReturnType();
-        if( returnType.isPrimitive() )
-        {
-            return primitiveValueMap.get(returnType);
-        }
-        else
-        {
-            return null;
-        }
+        return ProxyUtils.getDefaultValue(returnType);
     }
+
 }
 

Added: 
commons/proper/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java
URL: 
http://svn.apache.org/viewvc/commons/proper/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java?rev=659831&view=auto
==============================================================================
--- 
commons/proper/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java
 (added)
+++ 
commons/proper/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestChainInvoker.java
 Sat May 24 07:56:53 2008
@@ -0,0 +1,157 @@
+package org.apache.commons.proxy.invoker;
+
+import org.apache.commons.proxy.util.AbstractTestCase;
+import org.apache.commons.proxy.ProxyFactory;
+
+/**
+ * @since 1.1
+ */
+public class TestChainInvoker extends AbstractTestCase
+{
+    public void testSkipDefaultValues()
+    {
+        final ChainInvoker invoker = new ChainInvoker(new Object[]{new 
DefaultTester(), new NonDefaultTester()});
+        Tester tester = (Tester)new ProxyFactory().createInvokerProxy(invoker, 
new Class[] { Tester.class });
+        assertEquals(true,tester.booleanMethod());
+        assertEquals(1, tester.byteMethod());
+        assertEquals('1', tester.charMethod());
+        assertEquals(1.0, tester.doubleMethod(), 0.0);
+        assertEquals(1.0f, tester.floatMethod(), 0.0f);
+        assertEquals(1, tester.intMethod());
+        assertEquals(1, tester.longMethod());
+        assertEquals(1, tester.shortMethod());
+        assertEquals("One", tester.objectMethod());
+    }
+
+    public void testReturnDefaultValue()
+    {
+        final ChainInvoker invoker = new ChainInvoker(new Object[]{new 
DefaultTester(), new DefaultTester()});
+        Tester tester = (Tester)new ProxyFactory().createInvokerProxy(invoker, 
new Class[] { Tester.class });
+        assertEquals(false,tester.booleanMethod());
+        assertEquals(0, tester.byteMethod());
+        assertEquals(0, tester.charMethod());
+        assertEquals(0.0, tester.doubleMethod(), 0.0);
+        assertEquals(0.0f, tester.floatMethod(), 0.0f);
+        assertEquals(0, tester.intMethod());
+        assertEquals(0, tester.longMethod());
+        assertEquals(0, tester.shortMethod());
+        assertEquals(null, tester.objectMethod());
+    }
+
+    public static interface Tester
+    {
+        public int intMethod();
+
+        public long longMethod();
+
+        public short shortMethod();
+
+        public byte byteMethod();
+
+        public double doubleMethod();
+
+        public float floatMethod();
+
+        public boolean booleanMethod();
+
+        public char charMethod();
+
+        public Object objectMethod();
+    }
+
+    public class NonDefaultTester implements Tester
+    {
+        public boolean booleanMethod()
+        {
+            return true;
+        }
+
+        public byte byteMethod()
+        {
+            return 1;
+        }
+
+        public char charMethod()
+        {
+            return '1';
+        }
+
+        public double doubleMethod()
+        {
+            return 1.0;
+        }
+
+        public float floatMethod()
+        {
+            return 1.0f;
+        }
+
+        public int intMethod()
+        {
+            return 1;
+        }
+
+        public long longMethod()
+        {
+            return 1;
+        }
+
+        public Object objectMethod()
+        {
+            return "One";
+        }
+
+        public short shortMethod()
+        {
+            return 1;
+        }
+    }
+
+    public class DefaultTester implements Tester
+    {
+        public boolean booleanMethod()
+        {
+            return false;
+        }
+
+        public byte byteMethod()
+        {
+            return 0;
+        }
+
+        public char charMethod()
+        {
+            return 0;
+        }
+
+        public double doubleMethod()
+        {
+            return 0;
+        }
+
+        public float floatMethod()
+        {
+            return 0;
+        }
+
+        public int intMethod()
+        {
+            return 0;
+        }
+
+        public long longMethod()
+        {
+            return 0;
+        }
+
+        public Object objectMethod()
+        {
+            return null;
+        }
+
+        public short shortMethod()
+        {
+            return 0;
+        }
+    }
+}


Reply via email to