xml-rpc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject cvs commit: xml-rpc/src/test/org/apache/xmlrpc XmlWriterTest.java
Date Mon, 26 Aug 2002 17:41:57 GMT
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 <aevers@redwood.nl>:
  
  + 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:adam@megacz.com">Adam Megacz</a>
  + * @author <a href="mailto:andrew@kungfoocoder.org">Andrew Evers</a>
  + * @author <a href="mailto:dlr@finemaltcoding.com">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:hannes@apache.org">Hannes Wallnoefer</a>
    * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:dlr@finemaltcoding.com">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:hannes@apache.org">Hannes Wallnoefer</a>
    * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  - * @version $Id$
  + * @author <a href="mailto:andrew@kungfoocoder.org">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 apache@apache.org.
   *
   * 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:hannes@apache.org">Hannes Wallnoefer</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:andrew@kungfoocoder.org">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 apache@apache.org.
   *
   * 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:andrew@kungfoocoder.org">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 apache@apache.org.
   *
   * 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:andrew@kungfoocoder.org">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 apache@apache.org.
   *
   * 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:andrew@kungfoocoder.org">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 apache@apache.org.
   *
   * 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:andrew@kungfoocoder.org">Andrew Evers</a>
   * @author <a href="mailto:hannes@apache.org">Hannes Wallnoefer</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">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 apache@apache.org.
   *
   * 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:andrew@kungfoocoder.org">Andrew Evers</a>
   * @author <a href="mailto:hannes@apache.org">Hannes Wallnoefer</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">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 apache@apache.org.
   *
   * 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:hannes@apache.org">Hannes Wallnoefer</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:andrew@kungfoocoder.org">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);
  
  
  

Mime
View raw message