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

org.n52.svalbard.decode.Soap11Decoder Maven / Gradle / Ivy

There is a newer version: 10.1.1
Show newest version
/*
 * Copyright 2015-2020 52°North Initiative for Geospatial Open Source
 * Software GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.n52.svalbard.decode;

import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.n52.shetland.ogc.ows.service.OwsServiceCommunicationObject;
import org.n52.shetland.ogc.ows.service.OwsServiceRequest;
import org.n52.shetland.ogc.ows.service.OwsServiceResponse;
import org.n52.shetland.ogc.swe.SweConstants;
import org.n52.shetland.w3c.soap.AbstractSoap;
import org.n52.shetland.w3c.soap.SoapConstants;
import org.n52.shetland.w3c.soap.SoapFault;
import org.n52.shetland.w3c.soap.SoapHeader;
import org.n52.shetland.w3c.soap.SoapRequest;
import org.n52.shetland.w3c.soap.SoapResponse;
import org.n52.svalbard.decode.exception.DecodingException;
import org.n52.svalbard.decode.exception.UnsupportedDecoderInputException;
import org.n52.svalbard.util.XmlHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlsoap.schemas.soap.envelope.Body;
import org.xmlsoap.schemas.soap.envelope.EnvelopeDocument;
import org.xmlsoap.schemas.soap.envelope.Header;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;

/**
 * @author Christian Autermann
 * @since 1.0.0
 */
public class Soap11Decoder extends AbstractSoapDecoder {
    private static final Logger LOGGER = LoggerFactory.getLogger(Soap11Decoder.class);
    private static final String SOAP_ACTION = "SOAPAction:";
    private static final QName QN_CLIENT = new QName(SoapConstants.NS_SOAP_11, "Client");

    public Soap11Decoder() {
        super(SoapConstants.NS_SOAP_11);
        LOGGER.debug("Decoder for the following keys initialized successfully: {}!", Joiner.on(", ").join(getKeys()));
    }

    /**
     * Parses SOAP 1.1 Envelope to a SOS internal SOAP request.
     *
     * @param doc Request as xml representation
     *
     * @return SOS internal SOAP request
     *
     * @throws DecodingException if an error occurs.
     */
    @Override
    protected AbstractSoap createEnvelope(XmlObject doc) throws DecodingException {
        AbstractSoap soap = null;
        String soapAction = "";
        if (doc instanceof EnvelopeDocument) {
            EnvelopeDocument envDoc = (EnvelopeDocument) doc;
            OwsServiceCommunicationObject bodyContent = getBodyContent(envDoc);
            soap = bodyContent instanceof OwsServiceRequest
                    ? new SoapRequest(SoapConstants.NS_SOAP_11, SoapConstants.SOAP_1_1_VERSION)
                            .setBodyContent((OwsServiceRequest) bodyContent)
                    : new SoapResponse(SoapConstants.NS_SOAP_11, SoapConstants.SOAP_1_1_VERSION)
                            .setBodyContent((OwsServiceResponse) bodyContent);

            // FIXME well... soapAction is always "" at this point
            // if SOAPAction is not spec conform, create SOAPFault
            if (soap instanceof SoapRequest && (soapAction.isEmpty() || !soapAction.startsWith(SOAP_ACTION))) {
                SoapFault fault = new SoapFault();
                fault.setFaultCode(QN_CLIENT);
                fault.setFaultReason("The SOAPAction parameter in the HTTP-Header is missing or not valid!");
                fault.setLocale(Locale.ENGLISH);
                ((SoapRequest) soap).setSoapFault(fault);
            } else {
                soap.setAction(checkSoapAction(soapAction, soap.getSoapHeader()));
            }
            if (envDoc.getEnvelope()
                    .isSetHeader()) {
                soap.setSoapHeader(getSoapHeader(envDoc.getEnvelope()
                        .getHeader()));
            }
            soap.setAction(checkSoapAction(soapAction, soap.getSoapHeader()));
        } else {
            throw new UnsupportedDecoderInputException(this, doc);
        }
        return soap;
    }

    @Override
    protected SoapRequest createFault(DecodingException de) {
        SoapFault fault = new SoapFault();
        fault.setFaultCode(QN_CLIENT);
        fault.setLocale(Locale.ENGLISH);
        fault.setFaultReason(getFaultReasons(de));
        SoapRequest r = new SoapRequest(SoapConstants.NS_SOAP_11, SoapConstants.SOAP_1_1_VERSION);
        r.setSoapFault(fault);
        return r;
    }

    private OwsServiceCommunicationObject getBodyContent(EnvelopeDocument doc) throws DecodingException {
        Body body = doc.getEnvelope().getBody();
        try {
            Node domNode = body.getDomNode();
            if (domNode.hasChildNodes()) {
                NodeList childNodes = domNode.getChildNodes();
                for (int i = 0; i < childNodes.getLength(); i++) {
                    Node node = childNodes.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        XmlObject content = XmlObject.Factory.parse(node);
                        // fix problem with invalid prefix in xsi:type value for
                        // om:result, e.g. OM_SWEArrayObservation or
                        // gml:ReferenceType
                        Map namespaces = XmlHelper.getNamespaces(doc.getEnvelope());
                        fixNamespaceForXsiType(content, namespaces);
                        XmlHelper.fixNamespaceForXsiType(content, SweConstants.QN_DATA_ARRAY_PROPERTY_TYPE_SWE_200);
                        return decodeXmlElement(content);
                    }
                }
            }
            return decodeXmlElement(body);
        } catch (XmlException xmle) {
            throw new DecodingException("Error while parsing SOAP body element!", xmle);
        }
    }

    protected List getSoapHeader(Header header) {
        List soapHeaders = Lists.newArrayList();
        XmlCursor cursor = null;
        try {
            cursor = header.newCursor();
            if (cursor.toFirstChild()) {
                do {
                    Object object = decodeXmlElement(XmlObject.Factory.parse(cursor.xmlText(getXmlOptions())));
                    if (object instanceof SoapHeader) {
                        soapHeaders.add((SoapHeader) object);
                    } else if (object instanceof List) {
                        for (Object o : (List) object) {
                            if (o instanceof SoapHeader) {
                                soapHeaders.add((SoapHeader) o);
                            }
                        }
                    }
                } while (cursor.toNextSibling());
            }
        } catch (DecodingException | XmlException e) {
            LOGGER.debug("Requested SoapHeader element is not supported", e);
        } finally {
            if (cursor != null) {
                cursor.dispose();
            }
        }
        return soapHeaders;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy