/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Darren Marvin
//      Created date:           2002/10/19
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.gemss.transportmessaging.proxies.axis;

import java.util.*;
import java.util.logging.*;
import javax.xml.soap.*;
import org.apache.axis.*;
import org.apache.axis.handlers.*;
import uk.ac.soton.itinnovation.gemss.transportmessaging.*;


public class GEMSSResponseHandler extends BasicHandler {
    private static WebServiceInvocationEnforcer wEnforcer = null;
    private static Logger mLogger = Logger.getLogger("uk.ac.soton.itinnovation.gemss.transportmessaging.proxies.axis.GEMSSRequestHandler");
    public void invoke(MessageContext msgContext) throws AxisFault {
        try {


            String transportConfigDir = (String) getOption("gemss.transport.messaging.config.dir");
            String securityConfigDir = (String) getOption("gemss.security.context.config.dir");
            String wsdlURI = (String) getOption("gemss.transport.messaging.wsdl.uri");
            String endpoint = (String) getOption("gemss.transport.messaging.service.endpoint");
            String portType = (String) getOption("gemss.transport.messaging.service.porttype");
            String binding = (String) getOption("gemss.transport.messaging.service.binding");
            if(transportConfigDir==null)
                throw new TransportMessagingException("Invalid transport configuration directory supplied");
            if(securityConfigDir==null)
                throw new TransportMessagingException("Invalid security configuration directory supplied");
            if(wsdlURI == null)
                throw new TransportMessagingException("Invalid 'gemss.transport.messaging.wsdl.uri' value in configuration 'service-config.wsdd'");
            if(endpoint == null)
                throw new TransportMessagingException("Invalid 'gemss.transport.messaging.service.endpoint' value in configuration 'service-config.wsdd'");
            if(portType == null)
                throw new TransportMessagingException("Invalid 'gemss.transport.messaging.service.porttype' value in configuration 'service-config.wsdd'");
            if(binding == null)
                throw new TransportMessagingException("Invalid 'gemss.transport.messaging.service.binding' value in configuration 'service-config.wsdd'");

            AxisSecureSOAPEnvelope secureEnv = new AxisSecureSOAPEnvelope(transportConfigDir,securityConfigDir,wsdlURI,endpoint,portType,binding);
            org.apache.axis.Message outMsg = msgContext.getResponseMessage();
            //force serialization now so that the attachments are available
            ((org.apache.axis.SOAPPart) outMsg.getSOAPPart()).getAsBytes();
            outMsg.saveChanges();

            //pull off the attachments
            List attachments = new ArrayList();
            Collection attCollection = outMsg.getAttachmentsImpl().getAttachments();
            Iterator attIterator = attCollection.iterator();
            while(attIterator.hasNext()) {
                AttachmentPart aP = (AttachmentPart) attIterator.next();
                attachments.add(aP);

            }

            secureEnv.encode(outMsg,msgContext,false);

            //else let it pass
            //Axis documentation is totally unclear that the following call is possible
            //but it works

            Message newMsg = new Message(secureEnv);
            //add previous attachments

            Iterator iterator = attachments.iterator();
            while (iterator.hasNext())
            {
                AttachmentPart aP = (AttachmentPart) iterator.next();
                newMsg.addAttachmentPart(aP);
            }
            newMsg.saveChanges();
            newMsg.setMessageContext(msgContext);
            msgContext.setResponseMessage(newMsg);

        } catch(TransportMessagingException ex) {
             mLogger.log(Level.SEVERE,"Failed to sign outgoing message",ex);
             AxisFault wrapperFault = new AxisFault();
             wrapperFault.setFaultCode(uk.ac.soton.itinnovation.gemss.transportmessaging.Constants.TRANSPORT_MESSAGING_ID);
             //Seems to be some sort of bug in handling fault details in Axis
             //wrapperFault.addFaultDetailString(ex.getSystemMessage());
             wrapperFault.setFaultString(ex.getUserMessage());
             throw wrapperFault;
        }
        catch (Exception e) {
            mLogger.log(Level.SEVERE,"Unexplained failure",e);
            if (e instanceof AxisFault)
                throw (AxisFault) e;
            else
                throw new AxisFault(e.getMessage());
        }
    }

    public void undo(MessageContext msgContext) {}

}
