All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.factoryfx.soap.SoapHandler Maven / Gradle / Ivy

package io.github.factoryfx.soap;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.DOMSource;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import jakarta.servlet.Servlet;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.xml.soap.MessageFactory;
import jakarta.xml.soap.MimeHeader;
import jakarta.xml.soap.MimeHeaders;
import jakarta.xml.soap.SOAPConstants;
import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPMessage;
import jakarta.xml.soap.SOAPPart;

public class SoapHandler implements Servlet {
    //If not setting the system property javax.xml.soap.MessageFactory to
    //com.sun.xml.internal.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl
    //there will be useless log warnings for each MessageFactory.newInstance call.
    //Therefore we only do it once to avoid those annoying logs
    private final MessageFactory SOAP11FACTORY;
    private final MessageFactory SOAP12FACTORY;

    private final WebServiceRequestDispatcher dispatcher;
    private final SOAPMessageUtil soapMessageUtil;

    public SoapHandler(WebServiceRequestDispatcher dispatcher, SOAPMessageUtil soapXmlParser) {
        this.dispatcher = dispatcher;
        this.soapMessageUtil = soapXmlParser;
        try {
            this.SOAP11FACTORY = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
            this.SOAP12FACTORY = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws IOException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        try {
            MessageFactory messageFactory;
            boolean soap12 = false;
            String header = request.getHeader("Content-Type");
            if (header != null && header.contains(SOAPConstants.SOAP_1_1_CONTENT_TYPE)) {
                messageFactory = SOAP11FACTORY;
            } else {
                //"application/soap+xml"
                messageFactory = SOAP12FACTORY;
                soap12 = true;
            }

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            dbFactory.setNamespaceAware(true);
            DocumentBuilder builder = dbFactory.newDocumentBuilder();
            Document document = builder.parse(request.getInputStream());

            trimWhitespace(document);

            DOMSource domSource = new DOMSource(document);
            SOAPMessage message = messageFactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            soapPart.setContent(domSource);
            message.saveChanges();

            WebServiceCallResult callResult = dispatcher.execute(message, soapMessageUtil.parseRequest(message), request, response);
            SOAPMessage responseMessage;
            if (callResult.result != null) {
                responseMessage = soapMessageUtil.wrapResponse(callResult.result, messageFactory);
            } else if (callResult.fault != null) {
                responseMessage = soapMessageUtil.wrapFault(callResult.createFaultDetail(), callResult.fault.getMessage(), messageFactory, soap12);
            } else {
                responseMessage = messageFactory.createMessage();
            }

            if (responseMessage.saveRequired()) {
                responseMessage.saveChanges();
            }
            response.setStatus(HttpServletResponse.SC_OK);
            putHeaders(responseMessage.getMimeHeaders(), response);

            OutputStream os = response.getOutputStream();
            responseMessage.writeTo(os);
            os.flush();

        } catch (SOAPException | ParserConfigurationException | SAXException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public String getServletInfo() {
        return "SOAP Handler";
    }

    @Override
    public void destroy() {
    }

    private void putHeaders(MimeHeaders headers, HttpServletResponse res) {

        Iterator it = headers.getAllHeaders();
        while (it.hasNext()) {
            MimeHeader header = it.next();

            String[] values = headers.getHeader(header.getName());
            if (values.length == 1) { res.setHeader(header.getName(), header.getValue()); } else {
                StringBuilder concat = new StringBuilder();
                int i = 0;
                while (i < values.length) {
                    if (i != 0) {
                        concat.append(',');
                    }
                    concat.append(values[i++]);
                }
                res.setHeader(header.getName(), concat.toString());
            }
        }
    }

    ServletConfig config;

    @Override
    public void init(ServletConfig config) {
        this.config = config;
    }

    @Override
    public ServletConfig getServletConfig() {
        return config;
    }

    private static void trimWhitespace(Node node) {
        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); ++i) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.TEXT_NODE) {
                child.setTextContent(child.getTextContent().trim());
            }
            trimWhitespace(child);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy