Package org.apache.turbine.services.xmlrpc

Source Code of org.apache.turbine.services.xmlrpc.TurbineXmlRpcService

package org.apache.turbine.services.xmlrpc;

/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following 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 "Apache" and "Apache Software Foundation" and
*    "Apache Turbine" 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",
*    "Apache Turbine", 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 helma.xmlrpc.WebServer;
import helma.xmlrpc.XmlRpc;
import helma.xmlrpc.XmlRpcClient;
import helma.xmlrpc.XmlRpcException;
import helma.xmlrpc.XmlRpcServer;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.util.Iterator;
import java.util.Vector;
import javax.servlet.ServletConfig;
import org.apache.turbine.services.BaseInitable;
import org.apache.turbine.services.BaseService;
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.ServiceBroker;
import org.apache.turbine.services.TurbineBaseService;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.resources.ResourceService;
import org.apache.turbine.services.xmlrpc.util.FileTransfer;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.TurbineException;

/**
* This is a service which will make an xml-rpc call to a remote
* server.
*
* Here's an example of how it would be done:
* <blockquote><code><pre>
* XmlRpcService xs =
*   (XmlRpcService)TurbineServices.getInstance()
*   .getService(XmlRpcService.XMLRPC_SERVICE_NAME);
* Vector vec = new Vector();
* vec.addElement(new Integer(5));
* URL url = new URL("http://betty.userland.com/RPC2");
* String name = (String)xs.executeRpc(url, "examples.getStateName", vec);
* </pre></code></blockquote>
*
* @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a>
* @author <a href="mailto:magnus@handtolvur.is">Magn�s ��r Torfason</a>
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
* @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
* @version $Id$
*/
public class TurbineXmlRpcService
    extends TurbineBaseService
    implements XmlRpcService
{
    /** The standalone xmlrpc server. */
    private WebServer webserver = null;

    /** The encapsulated xmlrpc server. */
    private XmlRpcServer server = null;

    /** The xmlrpc client. */
    private XmlRpcClient client = null;

    /** The port to listen on. */
    private int port = 0;

    /**
     * This function initializes the XmlRpcService.
     */
    public void init(ServletConfig config) throws InitializationException
    {
        try
        {
            ResourceService resources =
                ((TurbineServices)TurbineServices.getInstance()).
                getResources(getName());

            server = new XmlRpcServer();

            // Set the port for the service
            port = resources.getInt("port", 0);

            if(port != 0)
            {
                webserver = new WebServer(port);
            }

            // Set the XML driver to the correct SAX parser class
            String saxParserClass = resources.getString("parser",
                "org.apache.xerces.parsers.SAXParser");

            XmlRpc.setDriver ( saxParserClass );

            // Check if there are any handlers to register at startup
            Iterator keys = resources.getKeys("handler");
            while ( keys.hasNext() )
            {
                String handler = (String)keys.next();
                String handlerName = handler.substring(handler.indexOf(".")+1);
                String handlerClass = resources.getString(handler);
                registerHandler(handlerName, handlerClass);
            }

            /*
             * Turn on paranoia for the webserver if requested.
             */
            boolean stateOfParanoia = resources.getBoolean("paranoid", false);

            if (stateOfParanoia)
            {
                webserver.setParanoid(stateOfParanoia);
                Log.info(XmlRpcService.SERVICE_NAME +
                         ": Operating in a state of paranoia");

                /*
                 * Only set the accept/deny client lists if we
                 * are in a state of paranoia as they will just
                 * be ignored so there's no point in setting them.
                 */

                /*
                 * Set the list of clients that can connect
                 * to the xmlrpc server. The accepted client list
                 * will only be consulted if we are paranoid.
                 */
                Vector acceptedClients = resources.getVector("acceptClient");

                for (int i = 0; i < acceptedClients.size(); i++)
                {
                    String acceptClient = (String) acceptedClients.get(i);

                    if (acceptClient != null && ! acceptClient.equals(""))
                    {
                        webserver.acceptClient(acceptClient);
                        Log.info(XmlRpcService.SERVICE_NAME +
                                 ": Accepting client -> " + acceptClient);
                    }
                }

                /*
                 * Set the list of clients that can connect
                 * to the xmlrpc server. The denied client list
                 * will only be consulted if we are paranoid.
                 */
                Vector deniedClients = resources.getVector("denyClient");

                for (int i = 0; i < deniedClients.size(); i++)
                {
                    String denyClient = (String) deniedClients.get(i);

                    if (denyClient != null && ! denyClient.equals(""))
                    {
                        webserver.denyClient(denyClient);
                        Log.info(XmlRpcService.SERVICE_NAME +
                                 ": Denying client -> " + denyClient);
                    }
                }
            }
        }
        catch (Exception e)
        {
            throw new InitializationException
                ("XMLRPCService failed to initialize", e);
        }

        setInit(true);
    }

    /**
     * Register an Object as a default handler for the service.
     *
     * @param handler The handler to use.
     * @exception XmlRpcException.
     * @exception IOException.
     */
    public void registerHandler(Object handler)
        throws XmlRpcException,
        IOException
    {
        registerHandler("$default", handler);
    }

    /**
     * Register an Object as a handler for the service.
     *
     * @param handlerName The name the handler is registered under.
     * @param handler The handler to use.
     * @exception XmlRpcException.
     * @exception IOException.
     */
    public void registerHandler(String handlerName,
                                Object handler)
        throws XmlRpcException,
        IOException
    {
        if(webserver != null)
        {
            webserver.addHandler(handlerName, handler);
        }

        server.addHandler(handlerName, handler);
    }

    /**
     * A helper method that tries to initialize a handler and register it.
     * The purpose is to check for all the exceptions that may occur in
     * dynamic class loading and throw an InitializationException on
     * error.
     *
     * @param handlerName The name the handler is registered under.
     * @param handlerClass The name of the class to use as a handler.
     * @exception TurbineException Couldn't instantiate handler.
     */
    public void registerHandler(String handlerName, String handlerClass)
        throws TurbineException
    {
        try
        {
            Object handler = Class.forName(handlerClass).newInstance();

            if(webserver != null)
            {
                webserver.addHandler(handlerName,handler);
            }

            server.addHandler(handlerName,handler);
        }
        // those two errors must be passed to the VM
        catch( ThreadDeath t )
        {
            throw t;
        }
        catch( OutOfMemoryError t )
        {
            throw t;
        }

        catch( Throwable t )
        {
            throw new TurbineException
                ("Failed to instantiate " + handlerClass, t);
        }
    }

    /**
     * Unregister a handler.
     *
     * @param handlerName The name of the handler to unregister.
     */
    public void unregisterHandler(String handlerName)
    {
        if(webserver != null)
        {
            webserver.removeHandler(handlerName);
        }

        server.removeHandler(handlerName);
    }

    /**
     * Handle an XML-RPC request using the encapsulated server.
     *
     * You can use this method to handle a request from within
     * a Turbine screen.
     *
     * @param is the stream to read request data from.
     * @return the response body that needs to be sent to the client.
     */
    public byte[] handleRequest(InputStream is)
    {
        return server.execute(is);
    }

    /**
     * Handle an XML-RPC request using the encapsulated server with user
     * authentication.
     *
     * You can use this method to handle a request from within
     * a Turbine screen.
     *
     * <p> Note that the handlers need to implement AuthenticatedXmlRpcHandler
     * interface to access the authentication infomration.
     *
     * @param is the stream to read request data from.
     * @param user the user that is making the request.
     * @param password the password given by user.
     * @return the response body that needs to be sent to the client.
     */
    public byte[] handleRequest(InputStream is, String user, String password)
    {
        return server.execute(is, user, password);
    }

    /**
     * Client's interface to XML-RPC.
     *
     * The return type is Object which you'll need to cast to
     * whatever you are expecting.
     *
     * @param url A URL.
     * @param methodName A String with the method name.
     * @param params A Vector with the parameters.
     * @return An Object.
     * @exception XmlRpcException.
     * @exception IOException.
     */
    public Object executeRpc(URL url,
                             String methodName,
                             Vector params)
        throws TurbineException
    {
        try
        {
            XmlRpcClient client = new XmlRpcClient ( url );
            return client.execute(methodName, params);
        }
        catch (Exception e)
        {
            throw new TurbineException("XML-RPC call failed", e);
        }
    }

    /**
     * Method to allow a client to send a file to a server.
     *
     * @param serverURL
     * @param sourceLocationProperty
     * @param sourceFileName
     * @param destinationLocationProperty
     * @param destinationFileName
     */
    public void send(String serverURL,
                     String sourceLocationProperty,
                     String sourceFileName,
                     String destinationLocationProperty,
                     String destinationFileName)
                     throws Exception
    {
        FileTransfer.send(serverURL,
                          sourceLocationProperty,
                          sourceFileName,
                          destinationLocationProperty,
                          destinationFileName);
    }

    /**
     * Method to allow a client to get a file to a server.
     *
     * @param serverURL
     * @param sourceLocationProperty
     * @param sourceFileName
     * @param destinationLocationProperty
     * @param destinationFileName
     */
    public void get(String serverURL,
                    String sourceLocationProperty,
                    String sourceFileName,
                    String destinationLocationProperty,
                    String destinationFileName)
                    throws Exception
    {
        FileTransfer.get(serverURL,
                         sourceLocationProperty,
                         sourceFileName,
                         destinationLocationProperty,
                         destinationFileName);
    }

    /**
     * Method to allow a client to remove a file from
     * the server
     *
     * @param serverURL
     * @param sourceLocationProperty
     * @param sourceFileName
     */
    public void remove(String serverURL,
                       String sourceLocationProperty,
                       String sourceFileName)
                       throws Exception
    {
        FileTransfer.remove(serverURL,
                            sourceLocationProperty,
                            sourceFileName);
    }

    /**
     * Switch client filtering on/off.
     *
     * @param state Whether to filter clients.
     *
     * @see #acceptClient(java.lang.String)
     * @see #denyClient(java.lang.String)
     */
    public void setParanoid(boolean state)
    {
        webserver.setParanoid(state);
    }

    /**
     * Add an IP address to the list of accepted clients. The parameter can
     * contain '*' as wildcard character, e.g. "192.168.*.*". You must
     * call setParanoid(true) in order for this to have
     * any effect.
     *
     * @param address The address to add to the list.
     *
     * @see #denyClient(java.lang.String)
     * @see #setParanoid(boolean)
     */
    public void acceptClient(String address)
    {
        webserver.acceptClient(address);
    }

    /**
     * Add an IP address to the list of denied clients. The parameter can
     * contain '*' as wildcard character, e.g. "192.168.*.*". You must call
     * setParanoid(true) in order for this to have any effect.
     *
     * @param address The address to add to the list.
     *
     * @see #acceptClient(java.lang.String)
     * @see #setParanoid(boolean)
     */
    public void denyClient(String address)
    {
        webserver.denyClient(address);
    }

    /**
     * Shuts down this service, stopping running threads.
     */
    public void shutdown()
    {
        // Stop the XML RPC server.  helma.xmlrpc.WebServer blocks in a call to
        // ServerSocket.accept() until a socket connection is made.
        webserver.shutdown();
        try
        {
            Socket interrupt = new Socket(InetAddress.getLocalHost(), port);
            interrupt.close();
        }
        catch (Exception ignored)
        {
            // Remotely possible we're leaving an open listener socket around.
        }

        setInit(false);
    }
}
TOP

Related Classes of org.apache.turbine.services.xmlrpc.TurbineXmlRpcService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.