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

org.nuiton.topia.service.TopiaServiceProvider 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;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.service.servers.RMIServer;
import org.nuiton.topia.service.servers.SOAPServer;
import org.nuiton.topia.service.servers.XMLRPCServer;

/**
 * TopiaServiceProvider.java
 * 
 * @author chatellier
 * @version $Revision: 1715 $
 * 
 * Last update : $Date: 2009-12-15 01:26:16 +0100 (mar. 15 déc. 2009) $ By : $Author: tchemit $
 */
public class TopiaServiceProvider {

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

    /**
     * Map de correspondance interface -> instance
     */
    private Map, TopiaApplicationService> mapInstanceForClass;

    /**
     * Map de corresponcance class servant a creer une instance pour une
     * interface (pour chaque requete)
     */
    private Map, Class> mapClassForClass;

    /**
     * Sert a savoir si des servers ont deja ete lance ou pas.
     */
    private Map mapDispatcherForProtocole;

    /**
     * Map between port and protocol
     */
    protected Map mapPortForProtocol;

    /**
     * Constructeur
     */
    public TopiaServiceProvider() {
        // instancaition des maps
        mapInstanceForClass = new HashMap, TopiaApplicationService>();
        mapClassForClass = new HashMap, Class>();
        mapDispatcherForProtocole = new HashMap();
        mapPortForProtocol = new HashMap();
    }

    /**
     * Add a protocol port
     * 
     * @param pr protocol
     * @param port port
     */
    public void setProtocolPort(Protocol pr, Integer port) {
        mapPortForProtocol.put(pr, port);
    }

    /**
     * 
     * @param interfaze
     * @param clazz
     * @param protocole
     */
    public void addServiceClass(
            Class interfaze,
            Class clazz, Protocol protocole) {
        TopiaServiceServer server = initDispatcher(protocole);
        if (server != null) {
            server.addService(interfaze);
            mapClassForClass.put(interfaze, clazz);
            launchDispatcher(protocole);
        }
    }

    /**
     * 
     * @param interfaze
     * @param instance
     * @param protocole
     */
    public void addServiceInstance(
            Class interfaze,
            TopiaApplicationService instance, Protocol protocole) {
        TopiaServiceServer server = initDispatcher(protocole);
        if (server != null) {
            server.addService(interfaze);
            mapInstanceForClass.put(interfaze, instance);
            launchDispatcher(protocole);
        }

    }

    /**
     * 
     * @param protocole
     */
    private TopiaServiceServer initDispatcher(Protocol protocole) {

        TopiaServiceServer server = mapDispatcherForProtocole.get(protocole);

        // si un serveur n'est pas deja creer pour ce protocole
        if (server == null) {

            switch (protocole) {
            case XML_RPC:
                if (mapPortForProtocol.get(Protocol.XML_RPC) != null) {
                    server = new XMLRPCServer(mapPortForProtocol
                            .get(Protocol.XML_RPC));
                } else {
                    server = new XMLRPCServer();
                }
                break;
            case RMI:
                try {
                    if (mapPortForProtocol.get(Protocol.RMI) != null) {
                        server = new RMIServer(mapPortForProtocol
                                .get(Protocol.RMI));
                    } else {
                        server = new RMIServer();
                    }
                } catch (RemoteException e) {
                    logger.debug("Can't start RMIServer.", e);
                }
                break;
            case SOAP:
                if (mapPortForProtocol.get(Protocol.SOAP) != null) {
                    server = new SOAPServer(mapPortForProtocol
                            .get(Protocol.SOAP));
                } else {
                    server = new SOAPServer();
                }
                break;
            default:
                logger.debug("Unsupported protocole");
                break;
            }

            // ajoute a la liste
            mapDispatcherForProtocole.put(protocole, server);
            // renseigne le dispatcher
            server.setTopiaServiceProvider(this);
        }

        return server;
    }

    /**
     * 
     * @param protocole
     */
    private void launchDispatcher(Protocol protocole) {
        TopiaServiceServer server = mapDispatcherForProtocole.get(protocole);

        /*switch (protocole) {
        case XML_RPC:
        	// le lance
        	server.launch();
        	break;
        case RMI:
        	server.launch();
        	break;
        case SOAP:
        	server.launch();
        	break;
        default:
        	logger.debug("Unsupported protocole");
        	break;
        }*/
        server.launch();
    }

    /**
     * Effectue l'appel reel suivant comment a ete fournit le service, classe ou
     * instance.
     * 
     * @param args
     *            les arguments
     * @param method
     *            la methode
     * @return le resultat de l'appel de la methode
     */
    public Object execute(Method method, Object[] args) {
        // log
        logger.debug("Request service : "
                + method.getDeclaringClass().getName() + "." + method.getName()
                + "(" + Arrays.toString(args) + ")");

        Object result = null;

        // la classe du service
        Class clazz = null;
        try {
            clazz = method.getDeclaringClass();

            // le service
            TopiaApplicationService tasService = null;

            // recherche du service dans la map class -> class
            if (mapClassForClass.get(clazz) != null) {
                tasService = mapClassForClass.get(clazz).newInstance();
            }
            // sinon dans la map clazz -> instance
            else if (mapInstanceForClass.get(clazz) != null) {
                tasService = mapInstanceForClass.get(clazz);
            } else
                logger.warn("No service set for class " + clazz.getName());

            // Appel via commons beanutils
            result = MethodUtils.invokeMethod(tasService, method.getName(),
                    args);

        } catch (InstantiationException e) {
            logger.debug("Can't instanciate class", e);
        } catch (IllegalAccessException e) {
            logger.debug("Can't access class", e);
        } catch (SecurityException e) {
            logger.debug("Can't call method '" + clazz.getName()
                    + "' in class '" + clazz.getName()
                    + "' (SecurityException)", e);
        } catch (NoSuchMethodException e) {
            logger.debug("No method '" + clazz.getName() + "' found in class '"
                    + clazz.getName() + "'", e);
        } catch (IllegalArgumentException e) {
            logger.debug("Can't call method '" + clazz.getName()
                    + "' in class '" + clazz.getName() + "' (security)", e);
        } catch (InvocationTargetException e) {
            logger.debug("Can't call method '" + clazz.getName()
                    + "' in class '" + clazz.getName()
                    + "' (InvocationTargetException)", e);
        }

        return result;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy