You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jc...@apache.org on 2007/10/02 16:36:29 UTC
svn commit: r581265 - in /commons/sandbox/proxy/trunk/src:
main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java
test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java
Author: jcarman
Date: Tue Oct 2 07:36:28 2007
New Revision: 581265
URL: http://svn.apache.org/viewvc?rev=581265&view=rev
Log:
Now checks return types to verify that they are compatible.
Modified:
commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java
commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java
Modified: commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java
URL: http://svn.apache.org/viewvc/commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java?rev=581265&r1=581264&r2=581265&view=diff
==============================================================================
--- commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java (original)
+++ commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java Tue Oct 2 07:36:28 2007
@@ -23,9 +23,32 @@
import java.lang.reflect.Method;
/**
- * An invoker which supports "duck typing", meaning that it finds a matching method
- * on the object returned from the target provider and invokes it. This class is useful for
- * adapting an existing class to an interface it does not implement.
+ * An invoker which supports <a href="http://en.wikipedia.org/wiki/Duck_typing">"duck typing"</a>, meaning
+ * that it finds a matching method on the object returned from the target provider and invokes it. This class is
+ * useful for adapting an existing class to an interface it does not implement.
+ * <p>
+ * <b>Example:</b>
+ * </p>
+ * <p>
+ * <pre>
+ * public class LegacyDuck // Does not implement interface!
+ * {
+ * public void quack()
+ * {
+ * // Quacking logic...
+ * }
+ * }
+ * <p/>
+ * public interface Duck
+ * {
+ * public void quack();
+ * }
+ * <p/>
+ * ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck()); // Always returns a "legacy" duck
+ * DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
+ * Duck duck = ( Duck )proxyFactory.createInvokerProxy( invoker, new Class[] { Duck.class } );
+ * </pre>
+ * </p>
*/
public class DuckTypingInvoker implements Invoker
{
@@ -48,6 +71,11 @@
// Interface Invoker
//----------------------------------------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------------------------------------
+// Interface Invoker
+//----------------------------------------------------------------------------------------------------------------------
+
public Object invoke( final Object proxy, final Method method, final Object[] arguments ) throws Throwable
{
final Object target = targetProvider.getObject();
@@ -55,11 +83,17 @@
try
{
final Method targetMethod = targetClass.getMethod( method.getName(), method.getParameterTypes() );
- return targetMethod.invoke( target, arguments );
+ if ( method.getReturnType().isAssignableFrom( targetMethod.getReturnType() ) )
+ {
+ return targetMethod.invoke( target, arguments );
+ }
+ throw new UnsupportedOperationException(
+ "Target type " + targetClass.getName() + " method has incompatible return type." );
}
catch ( NoSuchMethodException e )
{
- throw new UnsupportedOperationException("Target type " + targetClass.getName() + " does not have a method matching " + method + "." );
+ throw new UnsupportedOperationException(
+ "Target type " + targetClass.getName() + " does not have a method matching " + method + "." );
}
}
}
Modified: commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java
URL: http://svn.apache.org/viewvc/commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java?rev=581265&r1=581264&r2=581265&view=diff
==============================================================================
--- commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java (original)
+++ commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java Tue Oct 2 07:36:28 2007
@@ -22,9 +22,7 @@
import org.apache.commons.proxy.ProxyFactory;
import org.apache.commons.proxy.provider.ConstantProvider;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.util.Comparator;
+import java.io.Serializable;
/**
*
@@ -37,46 +35,106 @@
public void testExactSignatureMatch()
{
- final ObjectProvider targetProvider = new ConstantProvider(new DuckComparator());
+ final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() );
final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
- final Comparator c = ( Comparator )new ProxyFactory().createInvokerProxy( invoker, new Class[] { Comparator.class } );
- assertEquals( 12345, c.compare( null, null ) );
+ final Duck duck = ( Duck ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{ Duck.class } );
+ assertEquals( "Quack!", duck.sayQuack() );
}
public void testNoMatchingMethod()
{
- final ObjectProvider targetProvider = new ConstantProvider(new DuckComparator());
+ final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() );
final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
- final Externalizable externalizable = ( Externalizable )new ProxyFactory().createInvokerProxy( invoker, new Class[] {
- Externalizable.class } );
+ final Goose goose = ( Goose ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{ Goose.class } );
try
{
- externalizable.writeExternal( null );
- fail("No matching method should be found.");
+ goose.sayHonk();
+ fail( "No matching method should be found." );
}
- catch(UnsupportedOperationException e )
+ catch ( UnsupportedOperationException e )
{
// Do nothing, expected behavior!
}
- catch ( IOException e )
+ }
+
+ public void testMismatchingParameterType()
+ {
+ final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() );
+ final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
+ final ParameterizedDuck parameterizedDuck = ( ParameterizedDuck ) new ProxyFactory()
+ .createInvokerProxy( invoker, new Class[]{ ParameterizedDuck.class } );
+ try
{
- fail("No IOException should be thrown here.");
+ parameterizedDuck.sayQuack("Elmer");
+ fail( "No matching method should be found." );
+ }
+ catch ( UnsupportedOperationException e )
+ {
+ // Do nothing, expected behavior!
}
}
-//----------------------------------------------------------------------------------------------------------------------
-// Inner Classes
-//----------------------------------------------------------------------------------------------------------------------
+ public void testTargetHasCompatibleReturnType()
+ {
+ final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() );
+ final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
+ final SerializableDuck duck = ( SerializableDuck ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{
+ SerializableDuck.class } );
+ assertEquals("Quack!", duck.sayQuack() );
- public static class DuckComparator
+ }
+
+ public void testMismatchingReturnType()
{
+ final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() );
+ final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
+ final VoidReturnDuck voidDuck = ( VoidReturnDuck ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{
+ VoidReturnDuck.class } );
+ try
+ {
+ voidDuck.sayQuack();
+ fail( "No matching method should be found." );
+ }
+ catch ( UnsupportedOperationException e )
+ {
+ // Do nothing, expected behavior!
+ }
+ }
+
//----------------------------------------------------------------------------------------------------------------------
-// Other Methods
+// Inner Classes
//----------------------------------------------------------------------------------------------------------------------
- public int compare( final Object o1, final Object o2 )
+ public static class LegacyDuck
+ {
+ public String sayQuack()
{
- return 12345;
+ return "Quack!";
}
+ }
+
+ public interface Duck
+ {
+ public String sayQuack();
+ }
+
+ public interface SerializableDuck
+ {
+ public Serializable sayQuack();
+ }
+
+ public interface ParameterizedDuck
+ {
+ public String sayQuack( String recipient );
+ }
+
+ public interface VoidReturnDuck
+ {
+ public void sayQuack();
+ }
+
+ public interface Goose
+ {
+ public void sayHonk();
}
}