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;
+ }
+ }
+}