All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.topia.service.servers.XMLRPCServer Maven / Gradle / Ivy

There is a newer version: 2.3.1
Show newest version
/* *##% 
 * ToPIA :: SOA
 * Copyright (C) 2004 - 2009 CodeLutin
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * ##%*/

package org.nuiton.topia.service.servers;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcHandler;
import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.server.XmlRpcHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.webserver.WebServer;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.service.TopiaApplicationService;
import org.nuiton.topia.service.TopiaServiceServerAbstract;

/**
 * XMLRPCServer.
 * 
 * @author chatellier
 * @version $Revision: 1732 $
 * 
 * Last update : $Date: 2009-12-20 17:29:38 +0100 (dim. 20 déc. 2009) $ By : $Author: tchemit $
 */
public class XMLRPCServer extends TopiaServiceServerAbstract implements
        XmlRpcHandler, XmlRpcHandlerMapping {

    /** Logger (common logging) */
    private static final Log logger = LogFactory.getLog(XMLRPCServer.class);

    /** Le server Web */
    private WebServer webServer;

    /** Port */
    public static final int DEFAUTL_PORT = 9090;

    /** Server already launched */
    protected boolean alreadyLaunched = false;

    /**
     * Constructeur.
     * 
     * Initialise le serveur.
     * 
     * @param port port de lancement du serveur
     */
    public XMLRPCServer(int port) {
        webServer = new WebServer(port);
        XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();

        xmlRpcServer.setHandlerMapping(this);
    }

    /**
     * Constructeur.
     */
    public XMLRPCServer() {
        this(DEFAUTL_PORT);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.nuiton.topia.service.TopiaServiceServer#addService(java.lang.Class)
     */
    public void addService(Class clazz) {
        // dans ce cas, rien
    }

    /**
     * lance le serveur
     */
    public void launch() {
        if (!alreadyLaunched) {
            try {
                webServer.start();
                logger.info("XML-RPC server running...");
            } catch (IOException e) {
                logger.debug("I/O erreur while launching xml-rpc web serveur",
                        e);
            }
            alreadyLaunched = true;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.xmlrpc.server.XmlRpcHandlerMapping#getHandler(java.lang.String)
     */
    public XmlRpcHandler getHandler(String className) throws XmlRpcException {
        logger.debug("Request handler for " + className);
        return this;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.xmlrpc.XmlRpcHandler#execute(org.apache.xmlrpc.XmlRpcRequest)
     */
    public Object execute(XmlRpcRequest xmlrequest) throws XmlRpcException {
        Object result = null;

        // conversion des arguments
        Object[] args = new Object[xmlrequest.getParameterCount()];
        Class[] argsTypes = new Class[xmlrequest.getParameterCount()];
        for (int i = 0; i < xmlrequest.getParameterCount(); ++i) {
            args[i] = xmlrequest.getParameter(i);
            argsTypes[i] = xmlrequest.getParameter(i).getClass();
        }

        // conversion class, methode
        String call = xmlrequest.getMethodName();
        String className = call.substring(0, call.lastIndexOf("."));
        String methodName = call.substring(call.lastIndexOf(".") + 1);

        logger.debug("Receiving request : " + className + "." + methodName
                + "(" + Arrays.toString(args) + ")");

        Class clazz;
        try {
            clazz = Class.forName(className);
            // get method that matches best via commons beanutils
            Method method = MethodUtils.getAccessibleMethod(clazz, methodName,
                    argsTypes);
            result = super.invoke(method, args);
        } catch (ClassNotFoundException e) {
            logger.debug("Class " + className + " not found !", e);
        }

        // construit et retourne des maps pour les objets complexes qui ne sont
        // pas supportés par XML-RPC
        if (result instanceof List) {
            result = listToMap((List) result);
        } else if (result instanceof TopiaEntity) {
            result = entityToMap((TopiaEntity) result);
        } else if (result instanceof Long) {
            result = Long.toString((Long) result);
        }

        return result;
    }

    /**
     * Construit et retourne une map de "maps entité", clé : TopiaId de
     * l'entité, valeur : Map de l'entité
     * 
     * @see #entityToMap(org.nuiton.topia.persistence.TopiaEntity) 
     * @param 
     *            la classe étendant TopiaEntity
     * @param list
     *            la liste de TopiaEntity
     * @return une map contenant les maps clé : TopiaId de l'entité, valeur :
     *         Map des champs de l'entité
     */
    private  Map listToMap(List list) {
        // construire la map contenant les entités
        // cle TopiaId, valeur :Map des attributs de l'entité
        Map> resultMap = new HashMap>();
        for (E entity : list) {
            // ajouter la map de l'entité
            Map entityMap = entityToMap(entity);
            resultMap.put(entity.getTopiaId(), entityMap);
        }
        return resultMap;
    }

    /**
     * Construit et retourne une map pour l'entité, clé : nom du champ, valeur :
     * contenu du champ (si c'est une entité, on met le TopiaId de celle ci, si
     * c'est une liste d'entités, on met un tableau de TopiaId)
     * 
     * @param 
     *            la classe étendant TopiaEntity
     * @param entity
     *            l'entité
     * @return une map
     */
    private  Map entityToMap(E entity) {
        Map entityMap = new HashMap();
        // invoquer tous les getters pour construire la map de l'entite
        for (Method m : entity.getClass().getMethods()) {
            if (m.getName().startsWith("get")) {
                logger.info("* method " + m);
                String attributeName = m.getName().replace("get", "");
                try {
                    Object o = m.invoke(entity);
                    if (o instanceof String && !o.equals("")) {
                        // nom de l'attribut : valeur
                        entityMap.put(attributeName, o);

                    } else if (o instanceof Date && o != null) {
                        // nom de l'attribut : date
                        entityMap.put(attributeName, o.toString());

                    } else if (o instanceof TopiaEntity && o != null) {
                        // nom de l'attribut : TopiaId
                        entityMap.put(attributeName, ((TopiaEntity) o)
                                .getTopiaId());

                    } else if (o instanceof Collection && o != null
                            && ((Collection) o).size() > 0) {
                        String composite[] = new String[((Collection) o).size()];
                        int index = 0;
                        for (Object obj : (Collection) o) {
                            composite[index++] = ((TopiaEntity) obj)
                                    .getTopiaId();
                        }
                        // nom de l'attribut : tableau de TopiaId
                        entityMap.put(attributeName, composite);
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        return entityMap;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy