Package de.danet.an.workflow.tools.xmlrpc

Source Code of de.danet.an.workflow.tools.xmlrpc.XmlRpcTool

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2006 Danet GmbH (www.danet.de), BU BTS.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: XmlRpcTool.java 2365 2007-04-22 19:44:16Z mlipp $
*
* $Log$
* Revision 1.1  2007/04/22 16:15:13  mlipp
* New generic XMLRPC tool.
*
*/
package de.danet.an.workflow.tools.xmlrpc;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.stream.StreamSource;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.xml.sax.SAXException;

import de.danet.an.util.sax.SAXContentBuffer;
import de.danet.an.workflow.api.Activity;
import de.danet.an.workflow.api.FormalParameter;
import de.danet.an.workflow.api.SAXEventBuffer;
import de.danet.an.workflow.spis.aii.ApplicationNotStoppedException;
import de.danet.an.workflow.spis.aii.CannotExecuteException;
import de.danet.an.workflow.spis.aii.ResultProvider;
import de.danet.an.workflow.spis.aii.ToolAgent;
import de.danet.an.workflow.spis.aii.XMLArgumentTypeProvider;

/**
* This class provides a tool agent for executing XMLRPCs.
*
* @author mnl
*
*/
public class XmlRpcTool
    implements ToolAgent, ResultProvider, XMLArgumentTypeProvider {

    private static final org.apache.commons.logging.Log logger
        = org.apache.commons.logging.LogFactory.getLog(XmlRpcTool.class);
   
    private ThreadLocal result = new ThreadLocal ();
   
    // Properties
    private String timeZone = "GMT";
    private String serverUrl = null;
    private String operation = null;
   
    // Non-properties
    private SAXTransformerFactory saxTransFactCache = null;
    private SAXEventBuffer serializerTemplates = null;
    private Templates serializerTemplatesCache = null;
    private SAXEventBuffer parserTemplates = null;
    private Templates parserTemplatesCache = null;

    private XmlRpcClient client = null;
   
    private SAXTransformerFactory saxTransFact ()
        throws TransformerConfigurationException {
        synchronized (result) {
            if (saxTransFactCache == null) {
                saxTransFactCache = (SAXTransformerFactory)
                    TransformerFactory.newInstance();
            }
            return saxTransFactCache;
        }
    }

    /**
     * Get the serializer templates.
     */
    private Templates serializerTemplates() throws CannotExecuteException {
        try {
            synchronized (result) {
                if (serializerTemplatesCache == null) {
                    if (serializerTemplates != null) {
                        TemplatesHandler templHand
                            = saxTransFact().newTemplatesHandler();
                        serializerTemplates.emit(templHand);
                        // TemplatesHandler contains the xslt information
                        serializerTemplatesCache = templHand.getTemplates();
                    } else {
                        InputStream xslIn
                          = SAXContentBuffer.class.getResourceAsStream
                          ("/de/danet/an/workflow/tools/xmlrpc/serializer.xsl");
                        serializerTemplatesCache = saxTransFact()
                            .newTemplates(new StreamSource(xslIn));
                    }
                }
            }
            return serializerTemplatesCache;
        } catch (TransformerConfigurationException e) {
            String msg = "Error creating TransformerHandler: " + e.getMessage();
            logger.error(msg, e);
            throw new CannotExecuteException (msg);
        } catch (SAXException e) {
            String msg = "Error creating TransformerHandler: " + e.getMessage();
            logger.error(msg, e);
            throw new CannotExecuteException (msg);
        }
    }
   
    /**
     * Get the parser templates.
     */
    private Templates parserTemplates() throws CannotExecuteException {
        try {
            synchronized (result) {
                if (parserTemplatesCache == null) {
                    if (parserTemplates != null) {
                        TemplatesHandler templHand
                            = saxTransFact().newTemplatesHandler();
                        parserTemplates.emit(templHand);
                        // TemplatesHandler contains the xslt information
                        parserTemplatesCache = templHand.getTemplates();
                    } else {
                        InputStream xslIn
                          = SAXContentBuffer.class.getResourceAsStream
                          ("/de/danet/an/workflow/tools/xmlrpc/parser.xsl");
                        parserTemplatesCache = saxTransFact()
                            .newTemplates(new StreamSource(xslIn));
                    }
                }
            }
            return parserTemplatesCache;
        } catch (TransformerConfigurationException e) {
            String msg = "Error creating TransformerHandler: " + e.getMessage();
            logger.error(msg, e);
            throw new CannotExecuteException (msg);
        } catch (SAXException e) {
            String msg = "Error creating TransformerHandler: " + e.getMessage();
            logger.error(msg, e);
            throw new CannotExecuteException (msg);
        }
    }
   
    /**
     * @param timeZone The timeZone to set.
     */
    public void setTimeZone(String timeZone) {
        this.timeZone = timeZone;
    }

    /**
     * @param serverUrl The serverUrl to set.
     */
    public void setServerUrl(String serverUrl) {
        this.serverUrl = serverUrl;
    }

    /**
     * @param operation The operation to set.
     */
    public void setOperation(String operation) {
        this.operation = operation;
    }

    /**
     * Set the serializer templates. These templates are used to
     * transform arbitrary XML to XMLRPC struct arguments.
     *
     * @param serializerTemplates the XSL definition
     */
    public void setSerializerTemplates(SAXEventBuffer xsl) {
        serializerTemplates = (SAXEventBuffer)xsl;
    }

    /**
     * Set parser templates. These templates are used to transform
     * struct XMLRPC results to arbitrary XML.
     *
     * @param serializerTemplates the XSL definition
     */
    public void setParserTemplates(SAXEventBuffer xsl) {
        serializerTemplates = (SAXEventBuffer)xsl;
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    public void invoke(Activity activity, FormalParameter[] formalParameters,
            Map actualParameters) throws RemoteException,
            CannotExecuteException {
        try {
            if (client == null) {
                client = new XmlRpcClient();
                XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
                if (serverUrl != null) {
                    config.setServerURL(new URL(serverUrl));
                }
                config.setTimeZone (TimeZone.getTimeZone(timeZone));
                client.setConfig(config);
                client.setTypeFactory
                    (new MyTypeFactory
                     (client, saxTransFact(),
                      serializerTemplates(), parserTemplates()));
            }
            int offset = 0;
            if (serverUrl == null) {
                ((XmlRpcClientConfigImpl)client.getConfig()).setServerURL
                    (new URL(retrieveServerUrl
                             (formalParameters, offset++, actualParameters)));
            }
            String operation = this.operation;
            if (operation == null) {
                operation = (String)retrieveServerUrl
                    (formalParameters, offset++, actualParameters);
            }
            String resParam = null;
            if (offset < formalParameters.length) {
                if (!formalParameters[offset].mode()
                    .equals(FormalParameter.Mode.IN)) {
                    resParam = formalParameters[offset].id();
                }
                if (formalParameters[offset].mode()
                    .equals(FormalParameter.Mode.OUT)) {
                    offset += 1;
                }
            }
            Object[] params = new Object[formalParameters.length - offset];
            for (int i = 0; i + offset < formalParameters.length; i++) {
                Object param = actualParameters
                    .get(formalParameters[i + offset].id());
                params[i] = convertParameter(param);
            }
            Object rpcResult = client.execute(operation, params);
            if (resParam != null) {
                Map res = new HashMap ();
                res.put(resParam, rpcResult);
                result.set (res);
            }
        } catch (MalformedURLException e) {
            throw new CannotExecuteException (e.getMessage(), e);
        } catch (XmlRpcException e) {
            throw new CannotExecuteException (e.getMessage(), e);
        } catch (TransformerConfigurationException e) {
            throw new CannotExecuteException (e.getMessage(), e);
        }
    }

    private Object convertParameter(Object param)
        throws CannotExecuteException {
        if (param instanceof Long) {
            if (((Long)param).longValue() > Integer.MAX_VALUE) {
                throw new CannotExecuteException
                    ("Illegal Argument",
                     new NumberFormatException
                     ("XMLRPC can handle only handle 4 byte integers"));
            }
            param = new Integer (((Long)param).intValue());
        }
        return param;
    }

    private String retrieveServerUrl
        (FormalParameter[] formalParameters, int offset, Map actualParameters) {
        if (offset >= formalParameters.length
            || (!String.class.isAssignableFrom
                ((formalParameters[offset].getClass())))
            || (!formalParameters[offset].mode()
                .equals(FormalParameter.Mode.IN))) {
            throw new IllegalArgumentException
                ("Operation must be passed as argument "
                 + "if not configured as property.");
        }
        return (String)actualParameters
            .get(formalParameters[offset].id());
    }
   
    private String retrieveOperation
        (FormalParameter[] formalParameters, int offset, Map actualParameters) {
        if (offset >= formalParameters.length
            || (!String.class.isAssignableFrom
                ((formalParameters[offset].getClass())))
            || (!formalParameters[offset].mode()
                .equals(FormalParameter.Mode.IN))) {
        throw new IllegalArgumentException
            ("ServerUrl must be passed as first argument "
             + "if not configured as property.");
        }
        return (String)actualParameters
            .get(formalParameters[offset].id());
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    public Object result() {
        Object res = result.get();
        result.set(null);
        return res;
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    public void terminate(Activity activity)
            throws ApplicationNotStoppedException, RemoteException {
        throw new ApplicationNotStoppedException ("Cannot interrupt call.");
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    public int requestedXMLArgumentType() {
        return XMLArgumentTypeProvider.XML_AS_SAX;
    }

}
TOP

Related Classes of de.danet.an.workflow.tools.xmlrpc.XmlRpcTool

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.