package org.inb.biomoby.service;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Provider;
import org.inb.biomoby.client.MobyDispatch;
import org.inb.biomoby.shared.message.MobyContent;
import org.inb.biomoby.shared.message.MobyException;
import org.inb.biomoby.shared.message.MobyMessage;

/**
 * @author Dmitry Repchevsky
 */

public abstract class MobyProvider implements Provider<SOAPMessage>
{
    public SOAPMessage invoke(SOAPMessage message)
    {
        MobyMessage response;
        try
        {
            MobyMessage request = MobyDispatch.unmarshal(message);
            
            response = call(request);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            
            MobyContent content = new MobyContent();
            response = new MobyMessage(content);
            
            MobyException exception = new MobyException();
            exception.setSeverity(MobyException.SEVERITY.error);
            exception.setExceptionMessage(ex.getMessage());
                    
            content.addException(exception);
        }

        SOAPMessage soapMessage;

        try
        {
            soapMessage = MobyDispatch.marshal("ResponseMessage", response);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            
            try
            {
                MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
                soapMessage = mf.createMessage();

                soapMessage.getSOAPBody().addFault(soapMessage.getSOAPPart().getEnvelope().createName("INTERNAL_MOBY_API_ERROR"), ex.getMessage());
            }
            catch (Exception e)
            { // Achtung!!!
                e.printStackTrace();
                soapMessage = null;
            }
        }
        
        // TODO return fault message
        return soapMessage;
    }

    public abstract MobyMessage call(MobyMessage message) throws Exception;
}