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/09/28 18:07:09 UTC
svn commit: r580396 - in /commons/sandbox/proxy/trunk/src:
main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java
site/xdoc/index.xml
test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java
Author: jcarman
Date: Fri Sep 28 09:07:06 2007
New Revision: 580396
URL: http://svn.apache.org/viewvc?rev=580396&view=rev
Log:
SANDBOX-198: Duck Typing Invoker
Added:
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/site/xdoc/index.xml
Added: 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=580396&view=auto
==============================================================================
--- commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java (added)
+++ commons/sandbox/proxy/trunk/src/main/java/org/apache/commons/proxy/invoker/DuckTypingInvoker.java Fri Sep 28 09:07:06 2007
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.proxy.invoker;
+
+import org.apache.commons.proxy.Invoker;
+import org.apache.commons.proxy.ObjectProvider;
+
+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.
+ */
+public class DuckTypingInvoker implements Invoker
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Fields
+//----------------------------------------------------------------------------------------------------------------------
+
+ private final ObjectProvider targetProvider;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------------------------------------------------------
+
+ public DuckTypingInvoker( final ObjectProvider targetProvider )
+ {
+ this.targetProvider = targetProvider;
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Interface Invoker
+//----------------------------------------------------------------------------------------------------------------------
+
+ public Object invoke( final Object proxy, final Method method, final Object[] arguments ) throws Throwable
+ {
+ final Object target = targetProvider.getObject();
+ final Class targetClass = target.getClass();
+ try
+ {
+ final Method targetMethod = targetClass.getMethod( method.getName(), method.getParameterTypes() );
+ return targetMethod.invoke( target, arguments );
+ }
+ catch ( NoSuchMethodException e )
+ {
+ throw new UnsupportedOperationException("Target type " + targetClass.getName() + " does not have a method matching " + method + "." );
+ }
+ }
+}
Modified: commons/sandbox/proxy/trunk/src/site/xdoc/index.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/proxy/trunk/src/site/xdoc/index.xml?rev=580396&r1=580395&r2=580396&view=diff
==============================================================================
--- commons/sandbox/proxy/trunk/src/site/xdoc/index.xml (original)
+++ commons/sandbox/proxy/trunk/src/site/xdoc/index.xml Fri Sep 28 09:07:06 2007
@@ -103,6 +103,7 @@
<table border="0">
<tr><td><b>Null</b></td><td>Always returns a null (useful for the "Null Object" pattern)</td></tr>
<tr><td><b>Apache XML-RPC</b></td><td>Uses <a href="http://ws.apache.org/xmlrpc/">Apache XML-RPC</a> to fulfill the method invocation</td></tr>
+ <tr><td><b>Duck Typing</b></td><td>Supports "duck typing" by adapting a class to an interface it does not implement.</td></tr>
<tr><td><b>Invocation Handler Adapter</b></td><td>Adapts the JDK <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/InvocationHandler.html">InvocationHandler</a> interface
to the <em>Commons Proxy</em> <a href="apidocs/org/apache/commons/proxy/Invoker.html">Invoker</a> interface.</td></tr>
</table>
Added: 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=580396&view=auto
==============================================================================
--- commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java (added)
+++ commons/sandbox/proxy/trunk/src/test/java/org/apache/commons/proxy/invoker/TestDuckTypingInvoker.java Fri Sep 28 09:07:06 2007
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.proxy.invoker;
+
+import junit.framework.TestCase;
+import org.apache.commons.proxy.ObjectProvider;
+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;
+
+/**
+ *
+ */
+public class TestDuckTypingInvoker extends TestCase
+{
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public void testExactSignatureMatch()
+ {
+ final ObjectProvider targetProvider = new ConstantProvider(new DuckComparator());
+ final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
+ final Comparator c = ( Comparator )new ProxyFactory().createInvokerProxy( invoker, new Class[] { Comparator.class } );
+ assertEquals( 12345, c.compare( null, null ) );
+ }
+
+ public void testNoMatchingMethod()
+ {
+ final ObjectProvider targetProvider = new ConstantProvider(new DuckComparator());
+ final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider );
+ final Externalizable externalizable = ( Externalizable )new ProxyFactory().createInvokerProxy( invoker, new Class[] {
+ Externalizable.class } );
+ try
+ {
+ externalizable.writeExternal( null );
+ fail("No matching method should be found.");
+ }
+ catch(UnsupportedOperationException e )
+ {
+ // Do nothing, expected behavior!
+ }
+ catch ( IOException e )
+ {
+ fail("No IOException should be thrown here.");
+ }
+ }
+
+//----------------------------------------------------------------------------------------------------------------------
+// Inner Classes
+//----------------------------------------------------------------------------------------------------------------------
+
+ public static class DuckComparator
+ {
+//----------------------------------------------------------------------------------------------------------------------
+// Other Methods
+//----------------------------------------------------------------------------------------------------------------------
+
+ public int compare( final Object o1, final Object o2 )
+ {
+ return 12345;
+ }
+ }
+}