dlr 2002/08/26 10:41:57 Modified: src/java/org/apache/xmlrpc SystemHandler.java WebServer.java XmlRpcServer.java src/java/org/apache/xmlrpc/secure SecureWebServer.java src/test/org/apache/xmlrpc XmlWriterTest.java Added: src/java/org/apache/xmlrpc DefaultHandlerMapping.java ParseFailed.java XmlRpcHandlerMapping.java XmlRpcRequest.java XmlRpcRequestProcessor.java XmlRpcResponseProcessor.java XmlRpcWorker.java Log: Integrated a patch by Andrew Evers <[EMAIL PROTECTED]>: + XmlRpcHandlerMapping - the getHandler(String) throws Exception interface. + DefaultHandlerMapping - an implementation of HandlerMapping based on the existing XmlRpcServer implementation. + ParseFailed - A runtime exception a'la AuthenticationFailed. + Invoker - the Invoker class previously in XmlRpcServer.java, now public. + XmlRpcRequest - encapsulates an XML-RPC request. + XmlRpcRequestProcessor - decode a request Produce an XmlRpcRequest from an InputStream (optional user/pass). public XmlRpcRequest processRequest(InputStream, String, String) public XmlRpcRequest processRequest(InputStream) + XmlRpcResponseProcessor - encode a response/exception Produce a byte [] from either an Object - representing a return value or an Exception - representing an error. public byte [] processException(Exception x, String encoding) public byte [] processResponse(Object outParam, String encoding) + XmlRpcWorker - decode, process and encode a request/response. Ties everything together, but only communicates with the XmlRpcServer via XmlRpcServer -> XmlRpcWorker execute() and XmlRpcWorker calls via the XmlRpcHandlerMapping. + XmlRpcServer - handle a thread pool and a default handler mapping. Things changed a little from the patch I originally proposed. The whole thing is probably best explained by four lines in XmlRpcWorker: request = requestProcessor.processRequest(is, user, password); handler = handlerMapping.getHandler(request.getMethodName()); response = invokeHandler(handler, request); return responseProcessor.processResponse(response, requestProcessor.getEncoding()); The *Processor classes are public and have public entry points so that it is possible to build your own XmlRpcWorker-like classes, by assembly (ie. delegation) rather than by inheritance, which can be trickier. Revision Changes Path 1.3 +29 -14 xml-rpc/src/java/org/apache/xmlrpc/SystemHandler.java Index: SystemHandler.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/SystemHandler.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- SystemHandler.java 15 Aug 2002 16:26:52 -0000 1.2 +++ SystemHandler.java 26 Aug 2002 17:41:57 -0000 1.3 @@ -4,7 +4,7 @@ * The Apache Software License, Version 1.1 * * - * Copyright(c) 2001 The Apache Software Foundation. All rights + * Copyright(c) 2001,2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,20 +62,32 @@ * <code>system.multicall</code>. * * @author <a href="mailto:[EMAIL PROTECTED]">Adam Megacz</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> + * @since 1.2 */ public class SystemHandler { - private XmlRpcServer server = null; + private XmlRpcHandlerMapping handlerMapping = null; /** - * Creates a new instance which delegates its multicalls to the - * specified {@link org.apache.xmlrpc.XmlRpcServer}. + * Creates a new instance that delegates calls via the + * specified {@link org.apache.xmlrpc.XmlRpcHandlerMapping} + */ + public SystemHandler(XmlRpcHandlerMapping handlerMapping) + { + this.handlerMapping = handlerMapping; + } + + /** + * Creates a new instance that delegates its multicalls via + * the mapping used by the specified {@link org.apache.xmlrpc.XmlRpcServer}. * - * @param server The server to delegate RPC calls to. + * @param server The server to retrieve the XmlRpcHandlerMapping from. */ protected SystemHandler(XmlRpcServer server) { - this.server = server; + this(server.getHandlerMapping()); } /** @@ -85,25 +97,28 @@ * @param request The request containing multiple RPC calls. * @return The RPC response. */ - public Vector multicall(Vector request) + public Vector multicall(Vector requests) { Vector response = new Vector(); - for (int i = 0; i < request.size(); i++) + XmlRpcRequest request; + for (int i = 0; i < requests.size(); i++) { try { - Hashtable call = (Hashtable) request.elementAt(i); - String methodName = (String) call.get("methodName"); - Vector params = (Vector) call.get("params"); - Object handler = server.getHandler(methodName); + Hashtable call = (Hashtable) requests.elementAt(i); + request = new XmlRpcRequest((String) call.get("methodName"), + (Vector) call.get("params"), + null, null); + Object handler = handlerMapping.getHandler(request.getMethodName()); Vector v = new Vector(); - v.addElement(server.invokeHandler(handler, methodName, params, null, null)); + v.addElement(XmlRpcWorker.invokeHandler(handler, request)); response.addElement(v); } catch (Exception x) { String message = x.toString(); - int code = x instanceof XmlRpcException ? ((XmlRpcException) x).code : 0; + int code = (x instanceof XmlRpcException ? + ((XmlRpcException) x).code : 0); Hashtable h = new Hashtable(); h.put("faultString", message); h.put("faultCode", new Integer(code)); 1.18 +12 -4 xml-rpc/src/java/org/apache/xmlrpc/WebServer.java Index: WebServer.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v retrieving revision 1.17 retrieving revision 1.18 diff -u -u -r1.17 -r1.18 --- WebServer.java 21 Aug 2002 09:47:13 -0000 1.17 +++ WebServer.java 26 Aug 2002 17:41:57 -0000 1.18 @@ -75,7 +75,6 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> - * @version $Id$ */ public class WebServer implements Runnable { @@ -174,7 +173,7 @@ } /** - * Creates a Web server at the specified port number. + * Creates a web server at the specified port number. */ public WebServer(int port) { @@ -182,13 +181,22 @@ } /** - * Creates a Web server at the specified port number and IP address. + * Creates a web server at the specified port number and IP address. */ public WebServer(int port, InetAddress addr) { + this(port, addr, new XmlRpcServer()); + } + + /** + * Creates a web server at the specified port number and IP + * address. + */ + public WebServer(int port, InetAddress addr, XmlRpcServer xmlrpc) + { this.address = addr; this.port = port; - xmlrpc = new XmlRpcServer(); + this.xmlrpc = xmlrpc; accept = new Vector(); deny = new Vector(); threadpool = new Stack(); 1.33 +27 -466 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java Index: XmlRpcServer.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v retrieving revision 1.32 retrieving revision 1.33 diff -u -u -r1.32 -r1.33 --- XmlRpcServer.java 21 Aug 2002 09:45:48 -0000 1.32 +++ XmlRpcServer.java 26 Aug 2002 17:41:57 -0000 1.33 @@ -4,7 +4,7 @@ * The Apache Software License, Version 1.1 * * - * Copyright(c) 2001 The Apache Software Foundation. All rights + * Copyright(c) 2001,2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,16 +55,10 @@ * <http://www.apache.org/>. */ -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.EmptyStackException; -import java.util.Hashtable; import java.util.Stack; -import java.util.Vector; /** * A multithreaded, reusable XML-RPC server object. The name may be misleading @@ -74,15 +68,13 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> - * @version $Id$ + * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> */ public class XmlRpcServer { - private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - - private Hashtable handlers; private Stack pool; - private int workers; + private int nbrWorkers; + private DefaultHandlerMapping handlerMapping; /** * Construct a new XML-RPC server. You have to register handlers @@ -90,43 +82,33 @@ */ public XmlRpcServer() { - handlers = new Hashtable(); pool = new Stack(); - workers = 0; + nbrWorkers = 0; + handlerMapping = new DefaultHandlerMapping(); } /** - * Register a handler object with this name. Methods of this - * objects will be callable over XML-RPC as - * "handlername.methodname". For more information about XML-RPC - * handlers see the <a href="../index.html#1a">main documentation - * page</a>. - * - * @param handlername The name to identify the handler by. - * @param handler The handler itself. + * @see org.apache.xmlrpc.DefaultHandlerMapping#addHandler(String, Object) */ - public void addHandler(String handlername, Object handler) + public void addHandler(String handlerName, Object handler) { - if (handler instanceof XmlRpcHandler || - handler instanceof AuthenticatedXmlRpcHandler) - { - handlers.put(handlername, handler); - } - else if (handler != null) - { - handlers.put(handlername, new Invoker(handler)); - } + handlerMapping.addHandler(handlerName, handler); } /** - * Remove a handler object that was previously registered with - * this server. - * - * @param handlername The name identifying the handler to remove. + * @see org.apache.xmlrpc.DefaultHandlerMapping#removeHandler(String) + */ + public void removeHandler(String handlerName) + { + handlerMapping.removeHandler(handlerName); + } + + /** + * Return the current XmlRpcHandlerMapping. */ - public void removeHandler(String handlername) + public XmlRpcHandlerMapping getHandlerMapping() { - handlers.remove(handlername); + return handlerMapping; } /** @@ -147,7 +129,7 @@ */ public byte[] execute(InputStream is, String user, String password) { - Worker worker = getWorker(); + XmlRpcWorker worker = getWorker(); byte[] retval = worker.execute(is, user, password); pool.push(worker); return retval; @@ -158,446 +140,25 @@ * * @return A worker. */ - private final Worker getWorker() + protected XmlRpcWorker getWorker() { try { - return(Worker) pool.pop(); + return (XmlRpcWorker) pool.pop(); } catch(EmptyStackException x) { int maxThreads = XmlRpc.getMaxThreads(); - if (workers < maxThreads) + if (nbrWorkers < maxThreads) { - workers += 1; - if (workers >= maxThreads * .95) + nbrWorkers += 1; + if (nbrWorkers >= maxThreads * .95) { System.out.println("95% of XML-RPC server threads in use"); } - return new Worker(); + return new XmlRpcWorker(handlerMapping); } throw new RuntimeException("System overload"); } - } - - /** - * Find the handler and its method name for a given method. - * - * @param methodName The name of the XML-RPC method to find a - * handler for (this is <i>not</i> the Java method name). - * @return A handler object and method name. - */ - protected Object getHandler(String methodName) - throws Exception - { - Object handler = null; - String handlerName = null; - int dot = methodName.lastIndexOf('.'); - if (dot > -1) - { - // The last portion of the XML-RPC method name is the Java - // method name. - handlerName = methodName.substring(0, dot); - handler = handlers.get(handlerName); - } - - if (handler == null) - { - handler = handlers.get("$default"); - - if (handler == null) - { - if (dot > -1) - { - throw new Exception("RPC handler object \"" - + handlerName + "\" not found and no " - + "default handler registered"); - } - else - { - throw new Exception("RPC handler object not found for \"" - + methodName - + "\": No default handler registered"); - } - } - } - - return handler; - } - - /** - * Invokes the specified method on the provided handler. - * - * @param methodName The name of the XML-RPC method to invoke - * (this is <i>not</i> the Java method name). - * @throws AuthenticationFailed - */ - protected Object invokeHandler(Object handler, String methodName, - Vector request, String user, - String password) - throws Exception - { - if (handler instanceof AuthenticatedXmlRpcHandler) - { - return ((AuthenticatedXmlRpcHandler) handler) - .execute(methodName, request, user, password); - } - else - { - return ((XmlRpcHandler) handler).execute(methodName, request); - } - } - - /** - * Performs streaming, parsing, and handler execution. - * Implementation is not thread-safe. - */ - class Worker extends XmlRpc - { - private Vector inParams; - private ByteArrayOutputStream buffer; - private XmlWriter writer; - - /** - * Creates a new instance. - */ - protected Worker() - { - inParams = new Vector(); - buffer = new ByteArrayOutputStream(); - } - - /** - * Given a request for the server, generates a response. - * - * @throws AuthenticationFailed - */ - public byte[] execute(InputStream is, String user, String password) - { - try - { - // Do the work - return executeInternal(is, user, password); - } - finally - { - // Release most of our resources - buffer.reset(); - inParams.removeAllElements(); - } - } - - /** - * - * @param is - * @param user - * @param password - * @return - * @throws AuthenticationFailed - */ - private byte[] executeInternal(InputStream is, String user, - String password) - { - byte[] result = null; - long now = 0; - - if (XmlRpc.debug) - { - now = System.currentTimeMillis(); - } - try - { - parse(is); - if (XmlRpc.debug) - { - System.out.println("XML-RPC method name: " + methodName); - System.out.println("inparams: " + inParams); - } - // check for errors from the XML parser - if (errorLevel > NONE) - { - throw new Exception(errorMsg); - } - - Object handler = getHandler(methodName); - Object outParam = invokeHandler(handler, methodName, inParams, - user, password); - - if (XmlRpc.debug) - { - System.out.println("outparam = " + outParam); - } - - writer = new XmlWriter(buffer, encoding); - writeResponse(outParam, writer); - writer.flush(); - result = buffer.toByteArray(); - } - catch (AuthenticationFailed alertCaller) - { - throw alertCaller; - } - catch(Exception x) - { - if (XmlRpc.debug) - { - x.printStackTrace(); - } - // Ensure that if there is anything in the buffer, it - // is cleared before continuing with the writing of exceptions. - // It is possible that something is in the buffer - // if there were an exception during the writeResponse() - // call above. - buffer.reset(); - - writer = null; - try - { - writer = new XmlWriter(buffer, encoding); - } - catch(UnsupportedEncodingException encx) - { - System.err.println("XmlRpcServer attempted to use " - + "unsupported encoding: " + encx); - // NOTE: If we weren't already using the default - // encoding, we could try it here. - } - catch(IOException iox) - { - System.err.println("XmlRpcServer experienced I/O error " - + "writing error response: " + iox); - } - - String message = x.toString(); - // Retrieve XmlRpcException error code(if possible). - int code = x instanceof XmlRpcException ? - ((XmlRpcException) x).code : 0; - try - { - writeError(code, message, writer); - writer.flush(); - } - catch(Exception e) - { - // Unlikely to occur, as we just sent a struct - // with an int and a string. - System.err.println("Unable to send error response to " - + "client: " + e); - } - - // If we were able to create a XmlWriter, we should - // have a response. - if (writer != null) - { - result = buffer.toByteArray(); - } - else - { - result = EMPTY_BYTE_ARRAY; - } - } - finally - { - if (writer != null) - { - try - { - writer.close(); - } - catch(IOException iox) - { - // This is non-fatal, but worth logging a - // warning for. - System.err.println("Exception closing output stream: " - + iox); - } - } - } - if (XmlRpc.debug) - { - System.out.println("Spent " + (System.currentTimeMillis() - now) - + " millis in request"); - } - return result; - } - - /** - * Called when an object to be added to the argument list has - * been parsed. - */ - void objectParsed(Object what) - { - inParams.addElement(what); - } - - /** - * Writes an XML-RPC response to the XML writer. - */ - void writeResponse(Object param, XmlWriter writer) - throws XmlRpcException, IOException - { - writer.startElement("methodResponse"); - // if (param == null) param = ""; // workaround for Frontier bug - writer.startElement("params"); - writer.startElement("param"); - writer.writeObject(param); - writer.endElement("param"); - writer.endElement("params"); - writer.endElement("methodResponse"); - } - - /** - * Writes an XML-RPC error response to the XML writer. - */ - void writeError(int code, String message, XmlWriter writer) - throws XmlRpcException, IOException - { - // System.err.println("error: "+message); - Hashtable h = new Hashtable(); - h.put("faultCode", new Integer(code)); - h.put("faultString", message); - writer.startElement("methodResponse"); - writer.startElement("fault"); - writer.writeObject(h); - writer.endElement("fault"); - writer.endElement("methodResponse"); - } - } // end of inner class Worker -} // XmlRpcServer - -/** - * Introspects handlers using Java Reflection to call methods matching - * a XML-RPC call. - */ -class Invoker implements XmlRpcHandler -{ - private Object invokeTarget; - private Class targetClass; - - public Invoker(Object target) - { - invokeTarget = target; - targetClass = (invokeTarget instanceof Class) ? (Class) invokeTarget : - invokeTarget.getClass(); - if (XmlRpc.debug) - { - System.out.println("Target object is " + targetClass); - } - } - - /** - * main method, sucht methode in object, wenn gefunden dann aufrufen. - */ - public Object execute(String methodName, Vector params) throws Exception - { - // Array mit Classtype bilden, ObjectAry mit Values bilden - Class[] argClasses = null; - Object[] argValues = null; - if (params != null) - { - argClasses = new Class[params.size()]; - argValues = new Object[params.size()]; - for (int i = 0; i < params.size(); i++) - { - argValues[i] = params.elementAt(i); - if (argValues[i] instanceof Integer) - { - argClasses[i] = Integer.TYPE; - } - else if (argValues[i] instanceof Double) - { - argClasses[i] = Double.TYPE; - } - else if (argValues[i] instanceof Boolean) - { - argClasses[i] = Boolean.TYPE; - } - else - { - argClasses[i] = argValues[i].getClass(); - } - } - } - - // Methode da ? - Method method = null; - - // The last element of the XML-RPC method name is the Java - // method name. - int dot = methodName.lastIndexOf('.'); - if (dot > -1 && dot + 1 < methodName.length()) - { - methodName = methodName.substring(dot + 1); - } - - if (XmlRpc.debug) - { - System.out.println("Searching for method: " + methodName + - " in class " + targetClass.getName()); - for (int i = 0; i < argClasses.length; i++) - { - System.out.println("Parameter " + i + ": " + argValues[i] - + " (" + argClasses[i] + ')'); - } - } - - 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() == Object.class) - { - throw new XmlRpcException(0, "Invoker can't call methods " - + "defined in java.lang.Object"); - } - - // invoke - Object returnValue = null; - try - { - returnValue = method.invoke(invokeTarget, argValues); - } - catch(IllegalAccessException iacc_e) - { - throw iacc_e; - } - catch(IllegalArgumentException iarg_e) - { - throw iarg_e; - } - catch(InvocationTargetException it_e) - { - if (XmlRpc.debug) - { - it_e.getTargetException().printStackTrace(); - } - // check whether the thrown exception is XmlRpcException - Throwable t = it_e.getTargetException(); - if (t instanceof XmlRpcException) - { - throw (XmlRpcException) t; - } - // It is some other exception - throw new Exception(t.toString()); - } - if (returnValue == null && method.getReturnType() == Void.TYPE) - { - // Not supported by the spec. - throw new IllegalArgumentException - ("void return types for handler methods not supported"); - } - return returnValue; } } 1.1 xml-rpc/src/java/org/apache/xmlrpc/DefaultHandlerMapping.java Index: DefaultHandlerMapping.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ import java.util.Hashtable; /** * Provide a default handler mapping, used by the XmlRpcServer. This * mapping supports the special handler name "$default" that will * handle otherwise unhandled requests. * * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @see org.apache.xmlrpc.XmlRpcServer * @since 1.2 */ public class DefaultHandlerMapping implements XmlRpcHandlerMapping { private Hashtable handlers; /** * Create a new mapping. */ public DefaultHandlerMapping() { handlers = new Hashtable(); } /** * Register a handler object with this name. Methods of this * objects will be callable over XML-RPC as * "handlername.methodname". For more information about XML-RPC * handlers see the <a href="../index.html#1a">main documentation * page</a>. * * @param handlername The name to identify the handler by. * @param handler The handler itself. */ public void addHandler(String handlerName, Object handler) { if (handler instanceof XmlRpcHandler || handler instanceof AuthenticatedXmlRpcHandler) { handlers.put(handlerName, handler); } else if (handler != null) { handlers.put(handlerName, new Invoker(handler)); } } /** * Remove a handler object that was previously registered with * this server. * * @param handlerName The name identifying the handler to remove. */ public void removeHandler(String handlerName) { handlers.remove(handlerName); } /** * Find the handler and its method name for a given method. * Implements the <code>XmlRpcHandlerMapping</code> interface. * * @param methodName The name of the XML-RPC method to find a * handler for (this is <i>not</i> the Java method name). * @return A handler object and method name. * @see org.apache.xmlrpc.XmlRpcHandlerMapping#getHandler(String) */ public Object getHandler(String methodName) throws Exception { Object handler = null; String handlerName = null; int dot = methodName.lastIndexOf('.'); if (dot > -1) { // The last portion of the XML-RPC method name is the Java // method name. handlerName = methodName.substring(0, dot); handler = handlers.get(handlerName); } if (handler == null) { handler = handlers.get("$default"); if (handler == null) { if (dot > -1) { throw new Exception("RPC handler object \"" + handlerName + "\" not found and no " + "default handler registered"); } else { throw new Exception("RPC handler object not found for \"" + methodName + "\": No default handler registered"); } } } return handler; } } 1.1 xml-rpc/src/java/org/apache/xmlrpc/ParseFailed.java Index: ParseFailed.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ /** * Thrown as the result of an parse failure. * * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @see org.apache.xmlrpc.XmlRpcRequestProcessor * @since 1.2 */ public class ParseFailed extends RuntimeException { protected Exception cause; public ParseFailed(String message) { super(message); this.cause = null; } public ParseFailed(Exception cause) { super(cause.getMessage()); this.cause = cause; } public Exception getCause() { return cause; } } 1.1 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcHandlerMapping.java Index: XmlRpcHandlerMapping.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ /** * Maps from a handler name to a handler object. * * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @since 1.2 */ public interface XmlRpcHandlerMapping { /** * Return the handler for the specified handler name. * * @param handlerName The name of the handler to retrieve. * @return Object The desired handler. * @throws Exception If a handler can not be found. */ public Object getHandler(String handlerName) throws Exception; } 1.1 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcRequest.java Index: XmlRpcRequest.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ import java.util.Vector; /** * Encapsulates an XML-RPC request. * * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @since 1.2 */ public class XmlRpcRequest { protected final String methodName; protected final Vector parameters; protected final String username; protected final String password; public XmlRpcRequest(String methodName, Vector parameters, String username, String password) { this.parameters = parameters; this.methodName = methodName; this.username = username; this.password = password; } public Vector getParameters() { return parameters; } public Object getParameter(int index) { return parameters.elementAt(index); } public String getMethodName() { return methodName; } public String getUsername() { return username; } public String getPassword() { return password; } } 1.1 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcRequestProcessor.java Index: XmlRpcRequestProcessor.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ import java.io.InputStream; import java.util.Vector; /** * Process an InputStream and produce and XmlRpcRequest. This is * class NOT thread safe. * * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> * @since 1.2 */ public class XmlRpcRequestProcessor extends XmlRpc { private Vector requestParams; /** * Creates a new instance. */ protected XmlRpcRequestProcessor() { requestParams = new Vector(); } /** * Process an unauthenticated request. * * @param is the stream to read the request from. * @returns XMLRpcRequest the request. * @throws ParseFailed if unable to parse the request. */ public XmlRpcRequest processRequest(InputStream is) { return processRequest(is, null, null); } /** * Process an possibly authenticated request. * * @param is the stream to read the request from. * @param user the username (may be null). * @param password the password (may be null). * @returns XMLRpcRequest the request. * @throws ParseFailed if unable to parse the request. */ public XmlRpcRequest processRequest(InputStream is, String user, String password) { long now = 0; if (XmlRpc.debug) { now = System.currentTimeMillis(); } try { try { parse(is); } catch (Exception e) { throw new ParseFailed(e); } if (XmlRpc.debug) { System.out.println("XML-RPC method name: " + methodName); System.out.println("Request parameters: " + requestParams); } // check for errors from the XML parser if (errorLevel > NONE) { throw new ParseFailed(errorMsg); } return new XmlRpcRequest(methodName, (Vector) requestParams.clone(), user, password); } finally { requestParams.removeAllElements(); if (XmlRpc.debug) { System.out.println("Spent " + (System.currentTimeMillis() - now) + " millis decoding request"); } } } /** * Called when an object to be added to the argument list has been * parsed. * * @param what The parameter parsed from the request. */ void objectParsed(Object what) { requestParams.addElement(what); } } 1.1 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcResponseProcessor.java Index: XmlRpcResponseProcessor.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.io.IOException; import java.util.Hashtable; /** * Process an Object and produce byte array that represents the specified * encoding of the output as an XML-RPC response. This is NOT thread safe. * * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> * @since 1.2 */ public class XmlRpcResponseProcessor { private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; /** * Process a successful response, and return output in the * specified encoding. * * @param responseParam The response to process. * @param encoding The output encoding. * @return byte[] The XML-RPC response. */ public byte[] processResponse(Object responseParam, String encoding) throws IOException, UnsupportedEncodingException, XmlRpcException { long now = 0; if (XmlRpc.debug) { now = System.currentTimeMillis(); } try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); XmlWriter writer = new XmlWriter(buffer, encoding); writeResponse(responseParam, writer); writer.flush(); return buffer.toByteArray(); } finally { if (XmlRpc.debug) { System.out.println("Spent " + (System.currentTimeMillis() - now) + " millis encoding response"); } } } /** * Process an exception, and return output in the specified * encoding. * * @param e The exception to process; * @param encoding The output encoding. * @return byte[] The XML-RPC response. */ public byte[] processException(Exception x, String encoding) { if (XmlRpc.debug) { x.printStackTrace(); } // Ensure that if there is anything in the buffer, it // is cleared before continuing with the writing of exceptions. // It is possible that something is in the buffer // if there were an exception during the writeResponse() // call above. ByteArrayOutputStream buffer = new ByteArrayOutputStream(); XmlWriter writer = null; try { writer = new XmlWriter(buffer, encoding); } catch (UnsupportedEncodingException encx) { System.err.println("XmlRpcServer attempted to use " + "unsupported encoding: " + encx); // NOTE: If we weren't already using the default // encoding, we could try it here. } catch (IOException iox) { System.err.println("XmlRpcServer experienced I/O error " + "writing error response: " + iox); } String message = x.toString(); // Retrieve XmlRpcException error code(if possible). int code = x instanceof XmlRpcException ? ((XmlRpcException) x).code : 0; try { writeError(code, message, writer); writer.flush(); } catch (Exception e) { // Unlikely to occur, as we just sent a struct // with an int and a string. System.err.println("Unable to send error response to " + "client: " + e); } return (writer != null ? buffer.toByteArray() : EMPTY_BYTE_ARRAY); } /** * Writes an XML-RPC response to the XML writer. */ void writeResponse(Object param, XmlWriter writer) throws XmlRpcException, IOException { writer.startElement("methodResponse"); // if (param == null) param = ""; // workaround for Frontier bug writer.startElement("params"); writer.startElement("param"); writer.writeObject(param); writer.endElement("param"); writer.endElement("params"); writer.endElement("methodResponse"); } /** * Writes an XML-RPC error response to the XML writer. */ void writeError(int code, String message, XmlWriter writer) throws XmlRpcException, IOException { // System.err.println("error: "+message); Hashtable h = new Hashtable(); h.put("faultCode", new Integer(code)); h.put("faultString", message); writer.startElement("methodResponse"); writer.startElement("fault"); writer.writeObject(h); writer.endElement("fault"); writer.endElement("methodResponse"); } } 1.1 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcWorker.java Index: XmlRpcWorker.java =================================================================== package org.apache.xmlrpc; /* * The Apache Software License, Version 1.1 * * * Copyright(c) 2002 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "XML-RPC" 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 [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * 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 * <http://www.apache.org/>. */ import java.io.InputStream; import java.io.IOException; /** * Tie together the XmlRequestProcessor and XmlResponseProcessor to handle * a request serially in a single thread. * * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> * @author <a href="mailto:[EMAIL PROTECTED]">Andrew Evers</a> * @see org.apache.xmlrpc.XmlRpcServer * @since 1.2 */ public class XmlRpcWorker { protected XmlRpcRequestProcessor requestProcessor; protected XmlRpcResponseProcessor responseProcessor; protected XmlRpcHandlerMapping handlerMapping; /** * Create a new instance that will use the specified mapping. */ public XmlRpcWorker(XmlRpcHandlerMapping handlerMapping) { requestProcessor = new XmlRpcRequestProcessor(); responseProcessor = new XmlRpcResponseProcessor(); this.handlerMapping = handlerMapping; } /** * Pass the specified request to the handler. The handler should be an * instance of {@link org.apache.xmlrpc.XmlRpcHandler} or * {@link org.apache.xmlrpc.AuthenticatedXmlRpcHandler}. * * @param handler the handler to call. * @param request the request information to use. * @return Object the result of calling the handler. * @throws ClassCastException if the handler is not of an appropriate type. * @throws NullPointerException if the handler is null. * @throws Exception if the handler throws an exception. */ protected static Object invokeHandler(Object handler, XmlRpcRequest request) throws Exception { long now = 0; try { if (XmlRpc.debug) { now = System.currentTimeMillis(); } if (handler == null) { throw new NullPointerException ("Null handler passed to XmlRpcWorker.invokeHandler"); } else if (handler instanceof XmlRpcHandler) { return ((XmlRpcHandler) handler).execute (request.getMethodName(), request.getParameters()); } else if (handler instanceof AuthenticatedXmlRpcHandler) { return ((AuthenticatedXmlRpcHandler) handler) .execute(request.getMethodName(), request.getParameters(), request.getUsername(), request.getPassword()); } else { throw new ClassCastException("Handler class " + handler.getClass().getName() + " is not a valid XML-RPC handler"); } } finally { if (XmlRpc.debug) { System.out.println("Spent " + (System.currentTimeMillis() - now) + " millis processing request"); } } } /** * Decode, process and encode the response or exception for an XML-RPC * request. * * @param is the InputStream to read the request from. * @param user the user name (may be null). * @param password the password (may be null). * @return byte[] the response. * @throws org.apache.xmlrpc.ParseFailed if the request could not be parsed. * @throws org.apache.xmlrpc.AuthenticationFailed if the handler for the * specific method required authentication and insufficient credentials were * supplied. */ public byte[] execute(InputStream is, String user, String password) { long now = 0; if (XmlRpc.debug) { now = System.currentTimeMillis(); } try { XmlRpcRequest request = requestProcessor.processRequest(is, user, password); Object handler = handlerMapping.getHandler(request. getMethodName()); Object response = invokeHandler(handler, request); return responseProcessor.processResponse (response, requestProcessor.getEncoding()); } catch (AuthenticationFailed alertCallerAuth) { throw alertCallerAuth; } catch (ParseFailed alertCallerParse) { throw alertCallerParse; } catch (Exception x) { if (XmlRpc.debug) { x.printStackTrace(); } return responseProcessor.processException (x, requestProcessor.getEncoding()); } finally { if (XmlRpc.debug) { System.out.println("Spent " + (System.currentTimeMillis() - now) + " millis in request/process/response"); } } } } 1.5 +14 -2 xml-rpc/src/java/org/apache/xmlrpc/secure/SecureWebServer.java Index: SecureWebServer.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/secure/SecureWebServer.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -u -r1.4 -r1.5 --- SecureWebServer.java 15 Aug 2002 20:31:25 -0000 1.4 +++ SecureWebServer.java 26 Aug 2002 17:41:57 -0000 1.5 @@ -68,10 +68,12 @@ import javax.net.ServerSocketFactory; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; + import org.apache.xmlrpc.AuthDemo; import org.apache.xmlrpc.Echo; import org.apache.xmlrpc.WebServer; import org.apache.xmlrpc.XmlRpc; +import org.apache.xmlrpc.XmlRpcServer; /** * A minimal web server that exclusively handles XML-RPC requests @@ -96,7 +98,7 @@ * @param int port number of secure web server. * @see #SecureWebServer(int, InetAddress) */ - public SecureWebServer (int port) + public SecureWebServer(int port) { this(port, null); } @@ -112,6 +114,16 @@ public SecureWebServer(int port, InetAddress addr) { super(port, addr); + } + + + /** + * Creates a secure web server at the specified port number and IP + * address. + */ + public SecureWebServer(int port, InetAddress addr, XmlRpcServer xmlrpc) + { + super(port, addr, xmlrpc); } /** 1.3 +2 -2 xml-rpc/src/test/org/apache/xmlrpc/XmlWriterTest.java Index: XmlWriterTest.java =================================================================== RCS file: /home/cvs/xml-rpc/src/test/org/apache/xmlrpc/XmlWriterTest.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- XmlWriterTest.java 7 Aug 2002 16:59:41 -0000 1.2 +++ XmlWriterTest.java 26 Aug 2002 17:41:57 -0000 1.3 @@ -109,7 +109,7 @@ try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - XmlWriter writer = new XmlWriter(buffer); + XmlWriter writer = new XmlWriter(buffer, XmlWriter.ISO8859_1); assertEquals(XmlRpc.encoding, writer.getEncoding()); String foobar = "foobar"; writer.writeObject(foobar);