Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 5089 invoked from network); 11 Dec 2001 22:42:14 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 11 Dec 2001 22:42:14 -0000 Received: (qmail 11577 invoked by uid 97); 11 Dec 2001 22:42:15 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@jakarta.apache.org Received: (qmail 11518 invoked by uid 97); 11 Dec 2001 22:42:14 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 11500 invoked from network); 11 Dec 2001 22:42:13 -0000 Date: Tue, 11 Dec 2001 22:38:44 +0000 Subject: (Beanutils)[SUBMIT] MethodUtils Content-Type: multipart/mixed; boundary=Apple-Mail-8--261646002 Mime-Version: 1.0 (Apple Message framework v472) From: robert burrell donkin To: "Jakarta Commons Developers List" In-Reply-To: <20011211214342.29038.cpmta@c006.snv.cp.net> Message-Id: X-Mailer: Apple Mail (2.472) X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N --Apple-Mail-8--261646002 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed here's the new MethodUtils class. also included is a test case for this new class and associated testing patches. two methods were moved into MethodUtils from PropertyUtils and one made public (the other one could be public but i don't really think anyone will ever want to call it directly) together with a number of convenience wrapper methods. you'll probably wonder why the method is called invokeExactMethod (rather than invokeMethod, say). that's because i plan to add another method that searches for a correctly named method with compatible parameters (rather than exact matching) but i though that it'd be better to submit the patches required to fix Donnie's problem (and then add more functionality later). i've included the digester patch in a separate email. - robert --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=MethodUtils.java Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; x-unix-mode=0644; name="MethodUtils.java" /* * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software = itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products = derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.commons.beanutils; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.InvocationTargetException; /** *

Utility reflection methods focussed on methods in general rather = than properties in particular.

* * @author Craig R. McClanahan * @author Ralph Schaer * @author Chris Audley * @author Rey Fran=E7ois * @author Gregor Ra=FDman * @author Jan Sorensen */ public class MethodUtils { // --------------------------------------------------------- Public = Methods /** *

Invoke a method whose parameter type matches exactly the = object type.

* *

This is a convenient wrapper for=20 * {@link #invokeExactMethod(Object object,String methodName,Object = [] args)}. * =20 * @param object invoke method on this object * @param methodName get method with this name * @param arg use this argument * * @throw NoSuchMethodException if there is no such accessible = method * @throw InvocationTargetException wraps an exception thrown by the = method invoked * @throw IllegalAccessException can think of any reason why you = should get this one */ public static Object invokeExactMethod( Object object, String methodName, Object arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Object [] args =3D {arg}; return invokeExactMethod(object, methodName, args); =20 } /** *

Invoke a method whose parameter types match exactly the = object types.

* *

This uses reflection to invoke the method obtained from a = call to=20 * {@link #getAccessibleMethod} * =20 * @param object invoke method on this object * @param methodName get method with this name * @param args use these arguments *=20 * @throw NoSuchMethodException if there is no such accessible = method * @throw InvocationTargetException wraps an exception thrown by the = method invoked * @throw IllegalAccessException can think of any reason why you = should get this one */ public static Object invokeExactMethod( Object object, String methodName, Object [] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { int arguments =3D args.length; Class parameterTypes [] =3D new Class[arguments]; for (int i=3D0; i Invoke a method whose parameter types match exactly the = parameter types givem.

* *

This uses reflection to invoke the method obtained from a = call to=20 * {@link #getAccessibleMethod} * =20 * @param object invoke method on this object * @param methodName get method with this name * @param args use these arguments * @param parameterTypes match these parameters *=20 * @throw NoSuchMethodException if there is no such accessible = method * @throw InvocationTargetException wraps an exception thrown by the = method invoked * @throw IllegalAccessException can think of any reason why you = should get this one */ public static Object invokeExactMethod( Object object, String methodName, Object [] args, Class [] parameterTypes) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { =20 Method method =3D getAccessibleMethod( object.getClass(), methodName, parameterTypes); if (method =3D=3D null) throw new NoSuchMethodException("No such = accessible method."); =20 return method.invoke(object, args); } /** *

Return an accessible method (that is, one that can be invoked = via * reflection) with given name and a single parameter. If no such = method * can be found, return null.=20 * Basically, a convenience wrapper that constructs a = Class * array for you. * * @param clazz get method from this class * @param methodName get method with this name * @param parameterType taking this type of parameter=20 */ public static Method getAccessibleMethod( Class clazz,=20 String methodName,=20 Class parameterType)=20 throws=20 NoSuchMethodException { Class [] parameterTypes =3D {parameterType}; return getAccessibleMethod(clazz, methodName, parameterTypes); }=20 =20 =20 /** *

Return an accessible method (that is, one that can be invoked = via * reflection) with given name and parameters. If no such method * can be found, return null.=20 * This is just a convenient wrapper for {@link = #getAccessibleMethod(Method method)}. * * @param clazz get method from this class * @param methodName get method with this name * @param parameterTypes with these parameters types */ public static Method getAccessibleMethod( Class clazz,=20 String methodName,=20 Class[] parameterTypes)=20 throws=20 NoSuchMethodException { return getAccessibleMethod( clazz.getMethod(methodName, parameterTypes)); } /** * Return an accessible method (that is, one that can be invoked via * reflection) that implements the specified Method. If no such = method * can be found, return null. * * @param method The method that we wish to call */ public static Method getAccessibleMethod(Method method) { // Make sure we have a method to check if (method =3D=3D null) { return (null); } // If the requested method is not public we cannot call it if (!Modifier.isPublic(method.getModifiers())) { return (null); } // If the declaring class is public, we are done Class clazz =3D method.getDeclaringClass(); if (Modifier.isPublic(clazz.getModifiers())) { return (method); } // Check the implemented interfaces and subinterfaces String methodName =3D method.getName(); Class[] parameterTypes =3D method.getParameterTypes(); method =3D getAccessibleMethodFromInterfaceNest(clazz, method.getName(), = method.getParameterTypes()); return (method); /* Class[] interfaces =3D clazz.getInterfaces(); for (int i =3D 0; i < interfaces.length; i++) { // Is this interface public? if (!Modifier.isPublic(interfaces[i].getModifiers())) { continue; } // Does the method exist on this interface? try { method =3D interfaces[i].getDeclaredMethod(methodName, = parameterTypes); } catch (NoSuchMethodException e) { continue; } // We have found what we are looking for return (method); } // We are out of luck return (null); */ } // --------------------------------------------------------- Private = Methods /** *

Return an accessible method (that is, one that can be invoked = via * reflection) that implements the specified method, by scanning = through * all implemented interfaces and subinterfaces. If no such method * can be found, return null.

* *

There isn't any good reason why this method must be private. * It is because there doesn't seem any reason why other classes = should * call this rather than the higher level methods.

* * @param clazz Parent class for the interfaces to be checked * @param methodName Method name of the method we wish to call * @param parameterTypes The parameter type signatures */ private static Method getAccessibleMethodFromInterfaceNest (Class clazz, String methodName, Class parameterTypes[]) { Method method =3D null; // Search up the superclass chain for ( ; clazz !=3D null; clazz =3D clazz.getSuperclass()) { // Check the implemented interfaces of the parent class Class interfaces[] =3D clazz.getInterfaces(); for (int i =3D 0; i < interfaces.length; i++) { // Is this interface public? if (!Modifier.isPublic(interfaces[i].getModifiers())) continue; // Does the method exist on this interface? try { method =3D = interfaces[i].getDeclaredMethod(methodName, = parameterTypes); } catch (NoSuchMethodException e) { ; } if (method !=3D null) break; // Recursively check our parent interfaces method =3D getAccessibleMethodFromInterfaceNest(interfaces[i], methodName, = parameterTypes); if (method !=3D null) break; } } // If we found a method return it if (method !=3D null) return (method); // We did not find anything return (null); } } --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=MethodUtilsTestCase.java Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0644; name="MethodUtilsTestCase.java" /* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.commons.beanutils; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.beanutils.priv.PrivateBeanFactory; /** *

Test case for MethodUtils

* */ public class MethodUtilsTestCase extends TestCase { // ---------------------------------------------------- Instance Variables protected PrivateBeanFactory privateBeanFactory; // ---------------------------------------------------------- Constructors /** * Construct a new instance of this test case. * * @param name Name of the test case */ public MethodUtilsTestCase(String name) { super(name); } // -------------------------------------------------- Overall Test Methods /** * Set up instance variables required by this test case. */ public void setUp() { privateBeanFactory = new PrivateBeanFactory(); } /** * Return the tests included in this test suite. */ public static Test suite() { return (new TestSuite(MethodUtilsTestCase.class)); } /** * Tear down instance variables required by this test case. */ public void tearDown() { privateBeanFactory = null; } // ------------------------------------------------ Individual Test Methods /** *

Test getAccessibleMethod. */ public void testGetAccessibleMethod() { // test MethodUtils.getAccessibleMethod // we'll make things easier by using the convenience methods // easy bit first - find a public method // METHOD ONE try { Method method = MethodUtils.getAccessibleMethod(TestBean.class, "setStringProperty",String.class); // check that we've found one that matches assertNotNull(method); assertEquals("method ONE is named correctly","setStringProperty",method.getName()); assertTrue("Method ONE is public", Modifier.isPublic(method.getModifiers())); } catch (NoSuchMethodException e) { // ONE fail("Cannot find method ONE"); } // trickier this one - find a method in a direct interface // METHOD TWO try { Method method = MethodUtils.getAccessibleMethod( privateBeanFactory.create().getClass(), "methodBar", String.class); // check that we've found one that matches assertNotNull(method); assertEquals("Method TWO is named correctly","methodBar",method.getName()); assertTrue("Method TWO is public", Modifier.isPublic(method.getModifiers())); } catch (NoSuchMethodException e) { // ONE fail("Cannot find method TWO"); } // trickier this one - find a method in a indirect interface // METHOD THREE try { Method method = MethodUtils.getAccessibleMethod( privateBeanFactory.createSubclass().getClass(), "methodBaz", String.class); // check that we've found one that matches assertNotNull(method); assertEquals("Method THREE is named correctly","methodBaz",method.getName()); assertTrue("Method THREE is public", Modifier.isPublic(method.getModifiers())); } catch (NoSuchMethodException e) { // ONE fail("Cannot find method TWO"); } } /** *

Test invokeExactMethod. */ public void testInvokeExactMethod() { // test MethodUtils.invokeExactMethod // easy bit first - invoke a public method // METHOD ONE try { TestBean bean = new TestBean(); Object ret = MethodUtils.invokeExactMethod(bean, "setStringProperty","TEST"); // check that the return's right and that the properties been set assertNull(ret); assertEquals("Method ONE was invoked","TEST",bean.getStringProperty()); } catch (Throwable t) { // ONE fail("Exception in method ONE prevented invokation: " + t.toString()); } // trickier this one - find a method in a direct interface // METHOD TWO FAILURE try { Object ret = MethodUtils.invokeExactMethod( privateBeanFactory.create(), "methodBar", "ANOTHER TEST"); // check that we've found one that matches assertEquals("Method TWO was invoked correctly","ANOTHER TEST",ret); } catch (Throwable t) { // METHOD TWO FAILURE fail("Exception in method TWO prevented invokation: " + t.toString()); } // trickier this one - find a method in a indirect interface // METHOD THREE try { Object ret = MethodUtils.invokeExactMethod( privateBeanFactory.createSubclass(), "methodBaz", "YET ANOTHER TEST"); // check that we've found one that matches assertEquals("Method TWO was invoked correctly","YET ANOTHER TEST",ret); } catch (Throwable t) { // METHOD THREE FAILURE fail("Exception in method THREE prevented invokation: " + t.toString()); } } } --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=build.xml Content-Transfer-Encoding: 7bit Content-Type: application/octet-stream; x-unix-mode=0644; name="build.xml" Index: beanutils/build.xml =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/build.xml,v retrieving revision 1.17 diff -u -r1.17 build.xml --- beanutils/build.xml 2001/09/22 17:54:55 1.17 +++ beanutils/build.xml 2001/12/11 22:16:43 @@ -208,7 +208,8 @@ @@ -232,7 +233,14 @@ - + + + + + + + --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=PrivateBean.txt Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0644; name="PrivateBean.txt" Index: beanutils/src/test/org/apache/commons/beanutils/priv/PrivateBean.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PrivateBean.java,v retrieving revision 1.1 diff -u -r1.1 PrivateBean.java --- beanutils/src/test/org/apache/commons/beanutils/priv/PrivateBean.java 2001/05/07 02:09:02 1.1 +++ beanutils/src/test/org/apache/commons/beanutils/priv/PrivateBean.java 2001/12/11 22:18:08 @@ -119,6 +119,13 @@ } + /** + * A method accessible via an directly implemented interface. + */ + public String methodBar(String in) + { + return in; + } /** * A property accessible via an indirectly implemented interface. @@ -130,7 +137,13 @@ return (this.baz); } - + /** + * A method accessible via an indirectly implemented interface. + */ + public String methodBaz(String in) + { + return in; + } } --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=PrivateDirect.txt Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0644; name="PrivateDirect.txt" Index: beanutils/src/test/org/apache/commons/beanutils/priv/PrivateDirect.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PrivateDirect.java,v retrieving revision 1.1 diff -u -r1.1 PrivateDirect.java --- beanutils/src/test/org/apache/commons/beanutils/priv/PrivateDirect.java 2001/05/07 02:09:02 1.1 +++ beanutils/src/test/org/apache/commons/beanutils/priv/PrivateDirect.java 2001/12/11 22:18:39 @@ -81,5 +81,8 @@ */ String getBar(); - + /** + * A method accessible via a directly implemented interface. + */ + String methodBar(String in); } --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=PrivateIndirect.txt Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0644; name="PrivateIndirect.txt" Index: beanutils/src/test/org/apache/commons/beanutils/priv/PrivateIndirect.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PrivateIndirect.java,v retrieving revision 1.1 diff -u -r1.1 PrivateIndirect.java --- beanutils/src/test/org/apache/commons/beanutils/priv/PrivateIndirect.java 2001/05/07 02:09:02 1.1 +++ beanutils/src/test/org/apache/commons/beanutils/priv/PrivateIndirect.java 2001/12/11 22:19:01 @@ -81,5 +81,8 @@ */ public String getBaz(); - + /** + * A method accessible via an indirectly implemented interface. + */ + public String methodBaz(String in); } --Apple-Mail-8--261646002 Content-Disposition: attachment; filename=PropertyUtils.txt Content-Transfer-Encoding: 7bit Content-Type: text/plain; x-unix-mode=0644; name="PropertyUtils.txt" Index: beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v retrieving revision 1.14 diff -u -r1.14 PropertyUtils.java --- beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java 2001/10/14 01:15:07 1.14 +++ beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java 2001/12/11 22:17:27 @@ -908,7 +908,7 @@ */ public static Method getReadMethod(PropertyDescriptor descriptor) { - return (getAccessibleMethod(descriptor.getReadMethod())); + return (MethodUtils.getAccessibleMethod(descriptor.getReadMethod())); } @@ -977,7 +977,7 @@ */ public static Method getWriteMethod(PropertyDescriptor descriptor) { - return (getAccessibleMethod(descriptor.getWriteMethod())); + return (MethodUtils.getAccessibleMethod(descriptor.getWriteMethod())); } @@ -1387,126 +1387,4 @@ writeMethod.invoke(bean, values); } - - - // -------------------------------------------------------- Private Methods - - - /** - * Return an accessible method (that is, one that can be invoked via - * reflection) that implements the specified Method. If no such method - * can be found, return null. - * - * @param method The method that we wish to call - */ - private static Method getAccessibleMethod(Method method) { - - // Make sure we have a method to check - if (method == null) { - return (null); - } - - // If the requested method is not public we cannot call it - if (!Modifier.isPublic(method.getModifiers())) { - return (null); - } - - // If the declaring class is public, we are done - Class clazz = method.getDeclaringClass(); - if (Modifier.isPublic(clazz.getModifiers())) { - return (method); - } - - // Check the implemented interfaces and subinterfaces - String methodName = method.getName(); - Class[] parameterTypes = method.getParameterTypes(); - method = - getAccessibleMethodFromInterfaceNest(clazz, - method.getName(), - method.getParameterTypes()); - return (method); - - /* - Class[] interfaces = clazz.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - // Is this interface public? - if (!Modifier.isPublic(interfaces[i].getModifiers())) { - continue; - } - // Does the method exist on this interface? - try { - method = interfaces[i].getDeclaredMethod(methodName, - parameterTypes); - } catch (NoSuchMethodException e) { - continue; - } - // We have found what we are looking for - return (method); - } - - // We are out of luck - return (null); - */ - - } - - - /** - * Return an accessible method (that is, one that can be invoked via - * reflection) that implements the specified method, by scanning through - * all implemented interfaces and subinterfaces. If no such Method - * can be found, return null. - * - * @param clazz Parent class for the interfaces to be checked - * @param methodName Method name of the method we wish to call - * @param parameterTypes The parameter type signatures - */ - private static Method getAccessibleMethodFromInterfaceNest - (Class clazz, String methodName, Class parameterTypes[]) { - - Method method = null; - - // Search up the superclass chain - for ( ; clazz != null; clazz = clazz.getSuperclass()) { - - // Check the implemented interfaces of the parent class - Class interfaces[] = clazz.getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - - // Is this interface public? - if (!Modifier.isPublic(interfaces[i].getModifiers())) - continue; - - // Does the method exist on this interface? - try { - method = interfaces[i].getDeclaredMethod(methodName, - parameterTypes); - } catch (NoSuchMethodException e) { - ; - } - if (method != null) - break; - - // Recursively check our parent interfaces - method = - getAccessibleMethodFromInterfaceNest(interfaces[i], - methodName, - parameterTypes); - if (method != null) - break; - - } - - } - - // If we found a method return it - if (method != null) - return (method); - - // We did not find anything - return (null); - - } - - } --Apple-Mail-8--261646002 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed --Apple-Mail-8--261646002 Content-Type: text/plain; charset=us-ascii -- To unsubscribe, e-mail: For additional commands, e-mail: --Apple-Mail-8--261646002--