package example.common.handler;

import java.io.StringWriter;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import example.common.exception.SystemException;

public class SoapMessageDumpHandler implements SOAPHandler<SOAPMessageContext> {

    static Logger logger = LoggerFactory.getLogger(SoapMessageDumpHandler.class);

    public Set<QName> getHeaders() {
        return null;
    }

    public boolean handleMessage(SOAPMessageContext context) {
        if (logger.isDebugEnabled()) {
            SOAPMessage message = context.getMessage();
            SOAPPart part = message.getSOAPPart();
            logger.debug("message:\n" + format(part));
        }
        return true;
    }

    public boolean handleFault(SOAPMessageContext context) {
        if (logger.isWarnEnabled()) {
            SOAPMessage message = context.getMessage();
            SOAPPart part = message.getSOAPPart();
            logger.warn("message:\n" + format(part));
        }
        return true;
    }

    String format(Document document) {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            StringWriter sw = new StringWriter();
            transformer.transform(new DOMSource(document), new StreamResult(sw));
            return sw.toString();
        } catch (TransformerException e) {
            throw new SystemException(e);
        }
    }

    public void close(MessageContext context) {
    }

}
