/*
 * $RCSfile: DefaultSessionWsInvocationReceiver.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.
 */

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

import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;

import org.apache.log4j.Logger;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.client.ws.DefaultSessionWsInvocationSender;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.marshal.ws.AbstractMarshaler;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.marshal.ws.DefaultSessionMarshaler;
import org.eclipse.mddi.modelbus.adapter.infrastructure.transport.marshal.ws.SoapUtil;
import org.eclipse.mddi.modelbus.adapter.user.AdapterStub;
import org.eclipse.mddi.modelbus.adapter.user.InvalidSession;
import org.eclipse.mddi.modelbus.adapter.user.ModelingServiceError;
import org.eclipse.mddi.modelbus.adapter.user.SessionNeeded;
import org.eclipse.mddi.modelbus.adapter.user.provider.GenericSessionProvider;
import org.eclipse.mddi.modelbus.description.abstract_.Parameter;

/**
 * DefaultSessionWsInvocationReceiver parses incomming SOAP messages and
 * executes services in the session mode
 * 
 * @author Andrey Sadovykh (LIP6)
 */
public class DefaultSessionWsInvocationReceiver extends
        DefaultWsInvocationReceiver {
    private static Logger logger = Logger
            .getLogger(DefaultSessionWsInvocationReceiver.class);

    /**
     * Service call processing trigger (newSession, endSession). It is trigered
     * when the incomming call is dedicated to a modeling service.
     */
    boolean isModelingSeriviceCall = false;

    /**
     * @param adapter
     */
    public DefaultSessionWsInvocationReceiver(AdapterStub adapter) {
        super(adapter);
        marshaler = new DefaultSessionMarshaler(adapter.getProperties());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.DefaultWsInvocationReceiver#performService()
     */
    void performService() throws SessionNeeded, ModelingServiceError,
            InvalidSession {
        if (isModelingSeriviceCall) {
            GenericSessionProvider si = adapter.getToolStub()
                    .getSessionProvider();
            String serviceName = ms.getName();
            
            
            

            unmarshalledOutputs = si.executeSession(serviceName,
                    unmarshalledInputs, ((DefaultSessionMarshaler) marshaler)
                            .getSessionId());
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.DefaultWsInvocationReceiver#createResponse()
     */
    void createResponse() throws Exception {
        // because of DefaultWsInvocationReceiver implementation
        // it is applicable for service calls only
        if (isModelingSeriviceCall) {
            super.createResponse();
        }
    }

    /**
     * newSession porcesses incomming calls for newSession operation
     * 
     * @throws Exception
     * 
     */
    void newSession() throws Exception {
        GenericSessionProvider si = adapter.getToolStub()
                .getSessionProvider();
        
        String sessionId = si.newSession();
        
        logger.debug("Sender Session ID"+ sessionId);

        ((DefaultSessionMarshaler)marshaler).setSessionId(sessionId);

        SOAPBody responsebody = resMsg.getBody();
        AbstractMarshaler.setNamespaces(responsebody);
        
        SOAPElement resTopElem = responsebody.addChildElement( DefaultSessionWsInvocationSender.NEW_SESSION_TAG +"Response", "modelbus");

        marshaler.marshal((Parameter[]) null, null, resTopElem);
        logger.debug("Res:"+ responsebody);


    }

    /**
     * endSession porcesses incomming calls for endSession operation
     * 
     * @throws Exception
     * 
     */
    void endSession() throws Exception {
        SOAPBody requestbody = reqMsg.getBody();
        // the first child in the SOAP body is a input message conforming to
        // WSDL
        SOAPElement reqTopElem = SoapUtil.getFirstChild(requestbody);
        marshaler.unmarshal((Parameter[]) null, reqTopElem);

        String sessionId = ((DefaultSessionMarshaler)marshaler).getSessionId();

        GenericSessionProvider si = adapter.getToolStub()
                .getSessionProvider();

        si.endSession(sessionId);

        SOAPBody responsebody = resMsg.getBody();
        AbstractMarshaler.setNamespaces(responsebody);
        
        responsebody.addChildElement( DefaultSessionWsInvocationSender.END_SESSION_TAG +"Response", "modelbus");
    }

    /**
     * Reads the content in the HTTP request
     * 
     * @throws Exception
     * @see org.eclipse.mddi.modelbus.adapter.infrastructure.transport.server.ws.DefaultWsInvocationReceiver#readRequest()
     */
    void readRequest() throws Exception {

        SOAPBody requestbody = reqMsg.getBody();
        // the first child in the SOAP body is a input message conforming to
        // WSDL
        SOAPElement reqTopElem = SoapUtil.getFirstChild(requestbody);
        if (reqTopElem == null) {
            logger.error("SERVER: receive empty request");
            logger.debug(reqMsg);
            throw new SOAPException("Empty SOAP request");
        }

        String serviceName = reqTopElem.getLocalName();

        if (serviceName
                .equals(DefaultSessionWsInvocationSender.NEW_SESSION_TAG)) {
            newSession();
            return;
        } else if (serviceName
                .equals(DefaultSessionWsInvocationSender.END_SESSION_TAG)) {
            endSession();
            return;
        }

        isModelingSeriviceCall = true;

        super.readRequest();
    }

}
