This is a bit rushed (so there may be dumb errors), but I wanted to send it out for Jon to look over (he's helping out with the performance issues -- he suggested this change).
Thanks, Dan Index: XmlRpcServer.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v retrieving revision 1.11 diff -u -u -r1.11 XmlRpcServer.java --- XmlRpcServer.java 18 Feb 2002 23:22:29 -0000 1.11 +++ XmlRpcServer.java 19 Feb 2002 00:16:17 -0000 @@ -376,12 +376,32 @@ // This class uses Java Reflection to call methods matching an XML-RPC call class Invoker implements XmlRpcHandler { + private static Class objectClass; + static + { + try + { + objectClass = Class.forName("java.lang.Object"); + } + catch (ClassNotFoundException e) + { + System.err.println(e.toString()); + //throw new ExceptionInInitializer(e.getMessage()); + } + } + + /** + * A mapping of method names to <code>Method</code> objects. + */ + private Hashtable methodsByName; private Object invokeTarget; + private Class targetClass; public Invoker(Object target) { + methodsByName = new Hashtable(); invokeTarget = target; targetClass = invokeTarget instanceof Class ? (Class) invokeTarget : invokeTarget.getClass(); @@ -390,12 +410,16 @@ } - // main method, sucht methode in object, wenn gefunden dann aufrufen. - public Object execute (String methodName, - Vector params) throws Exception + /** + * Main method, sucht methode in object, wenn gefunden dann + * aufrufen. + * + * @param methodName The name of the method to invoke. + * @param params The method parameters. + */ + public Object execute (String methodName, Vector params) + throws Exception { - - // Array mit Classtype bilden, ObjectAry mit Values bilden Class[] argClasses = null; Object[] argValues = null; @@ -417,36 +441,10 @@ } } - // Methode da ? - Method method = null; - - if (XmlRpc.debug) - { - System.err.println("Searching for method: " + methodName); - for (int i = 0; i < argClasses.length; i++) - System.err.println("Parameter " + i + ": " + - argClasses[i] + " = " + argValues[i]); - } + // Let's play, "Find that Method object!" + Method method = findMethod(methodName, argClasses, argValues); - try - { - method = targetClass.getMethod(methodName, argClasses); - } - // Wenn nicht da dann entsprechende Exception returnen - catch (NoSuchMethodException nsm_e) - { - throw nsm_e; - } - catch (SecurityException s_e) - { - throw s_e; - } - - // our policy is to make all public methods callable except the ones defined in java.lang.Object - if (method.getDeclaringClass () == Class.forName ("java.lang.Object")) - throw new XmlRpcException (0, "Invoker can't call methods defined in java.lang.Object"); - - // invoke + // Invoke the method. Object returnValue = null; try { @@ -475,4 +473,48 @@ return returnValue; } + /** + * Finds <code>methodName</code>, caching it if it is not already + * in the cache. + * + * @param methodName The name of the <code>Method</code> to find. + * @return The <code>Method</code> object named by + * <code>methodName</code>. + */ + protected Method findMethod(String methodName, Class[] argClasses, + Object[] argValues) + throws XmlRpcException, NoSuchMethodException + { + // Let's play, "Find that Method object!" + Method method = (Method) methodsByName.get(methodName); + if (method == null) + { + // Not yet cached. + synchronized (methodsByName) + { + if (XmlRpc.debug) + { + System.err.println("Searching for method: " + methodName); + for (int i = 0; i < argClasses.length; i++) + { + System.err.println("Parameter " + i + ": " + + argClasses[i] + "=" + argValues[i]); + } + } + + method = targetClass.getMethod(methodName, argClasses); + + // Our policy is to make all public methods callable + // except for the ones defined in java.lang.Object. + if (method.getDeclaringClass() == objectClass) + { + throw new XmlRpcException(0, "Invoker can't call methods " + + "defined in java.lang.Object"); + } + + methodsByName.put(methodName, method); + } + } + return method; + } }