/*
 * $RCSfile: SimpleModelBusServer.java,v $
 * $Date: 2006/01/26 14:48:59 $
 * $Revision: 1.1.2.2 $
 * $Author: andreys $
 */

/*
 * Copyright (c) 2002-2003 IST-2004-2006-511731 ModelWare - ModelBus.
 * All rights reserved.
 *
 * This software is published under the terms of the ModelBus Software License
 * 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.
 * A copy of ModelBus Software License is provided with this distribution in
 * doc/LICENSE.txt file.
 */

/*
 * SimpleModelBusServer.java 
 * 
 * @author Prawee Sriplakich (LIP6)
 * @version $Revision: 1.1.2.2 $ $Date: 2006/01/26 14:48:59 $
 */
package org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.axis;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;

import org.apache.axis.AxisEngine;
import org.apache.axis.AxisFault;
import org.apache.axis.ConfigurationException;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.Handler;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.encoding.TypeMappingRegistry;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.server.AxisServer;
import org.apache.axis.transport.http.SimpleAxisServer;
import org.apache.log4j.Logger;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.marshal.ws.SoapUtil;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.AbstractServer;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.EndPointManager;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.ServerManager;

public class SimpleModelBusServer extends SimpleAxisServer implements
        AbstractServer {

    private static Logger logger = Logger.getLogger(SimpleModelBusServer.class);


    EngineConfigurationImpl config = new EngineConfigurationImpl();

    EndPointManager endPointManager;

    AxisServer internalAxisServer;

    int port;

    String context = ServerManager.DEFAULT_CONTEXT;

    public SimpleModelBusServer(int port) throws Exception {
        this.port = port;
        this.setMyConfig(config);
        internalAxisServer = new MBAxisServer(config);
        ServerSocket socket = null;
        try {
            socket = new ServerSocket(port);
            setServerSocket(socket);
            start();
        } catch (IOException e) {
            if (socket != null) {
                socket.close();
            }
            throw e;
        }
    }

    /**
     * 
     * Implementation of the operation of AbstractServer
     * 
     * @throws Exception
     * 
     */
    public void setEndPointManager(EndPointManager endPointManager)  {
        this.endPointManager = endPointManager;
    }

    /**
     * Overide the axis method
     */
    public synchronized AxisServer getAxisServer() {
        return internalAxisServer;
    }

    /**
     * This is a server that dispatches service invocation to ModelBus
     * 
     * 
     * @author P. Sriplakich
     * 
     */
    class MBAxisServer extends AxisServer {
        /**
         * 
         */
        private static final long serialVersionUID = 2422416854888267679L;

        MBAxisServer(EngineConfiguration config) {
            super(config);
        }

        public void invoke(MessageContext msgContext) throws AxisFault {

            String urlPath = (String) msgContext.getProperty("path");
            logger.debug("Invoking URL path = " + urlPath);

            String relativePath = "";
            if (urlPath.startsWith(context + "/")) {
                relativePath = urlPath.replaceFirst(context + "/", "");
            }
            logger.debug("relative path = " + relativePath);

            if(endPointManager==null) {
                logger.debug("no EndPointManager");
                return;
            }            
            try {
                Message req = msgContext.getRequestMessage();

                Message resp = (Message) SoapUtil.messageFactory
                        .createMessage();

                endPointManager.execute(relativePath, req.getSOAPEnvelope(),
                        resp.getSOAPEnvelope());

                msgContext.setResponseMessage(resp);

            } catch (SOAPException e) {
                e.printStackTrace();
            }

        }
    }

    class EngineConfigurationImpl implements EngineConfiguration {

        Hashtable globalOptions = new Hashtable();

        List deployedServices = new Vector();

        private Logger logger = Logger.getLogger(EngineConfigurationImpl.class);

        public void configureEngine(AxisEngine engine)
                throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("configureEngine()");
        }

        public void writeEngineConfig(AxisEngine engine)
                throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("writeEngineConfig()");
        }

        public Handler getHandler(QName qname) throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getHandler()");
            return null;
        }

        public SOAPService getService(QName qname)
                throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getService()");
            return null;
        }

        public SOAPService getServiceByNamespaceURI(String namespace)
                throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getServiceByNamespaceURI()");
            return null;
        }

        public Handler getTransport(QName qname) throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getTransport()");
            return null;
        }

        public TypeMappingRegistry getTypeMappingRegistry()
                throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getTypeMappingRegistry()");
            return null;
        }

        public Handler getGlobalRequest() throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getGlobalRequest()");
            return null;
        }

        public Handler getGlobalResponse() throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getGlobalResponse()");
            return null;
        }

        public Hashtable getGlobalOptions() throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getGlobalOptions()");
            return globalOptions;
        }

        public Iterator getDeployedServices() throws ConfigurationException {
            // TODO Auto-generated method stub
            logger.debug("getDeployedServices()");
            // new Exception().printStackTrace();
            return deployedServices.iterator();
        }

        public List getRoles() {
            // TODO Auto-generated method stub
            logger.debug("getRoles()");
            return new Vector();
        }

    }

    public int getPort() {
        return port;
    }

    public String getContext() {
        return context;
    }

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

}
