Package org.springframework.ws.soap.stroap

Source Code of org.springframework.ws.soap.stroap.StroapMessage$NoStartEndDocumentWriter

/*
* Copyright 2005-2010 the original author or authors.
*
* 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.springframework.ws.soap.stroap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.activation.DataHandler;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndDocument;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;

import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.ws.mime.Attachment;
import org.springframework.ws.mime.AttachmentException;
import org.springframework.ws.soap.AbstractSoapMessage;
import org.springframework.ws.soap.SoapEnvelope;
import org.springframework.ws.soap.SoapEnvelopeException;
import org.springframework.ws.soap.SoapVersion;
import org.springframework.ws.soap.support.SoapUtils;
import org.springframework.ws.stream.StreamingPayload;
import org.springframework.ws.stream.StreamingWebServiceMessage;
import org.springframework.ws.transport.TransportConstants;
import org.springframework.ws.transport.TransportInputStream;
import org.springframework.ws.transport.TransportOutputStream;
import org.springframework.xml.stream.AbstractXMLEventWriter;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.SAXException;

/**
* @author Arjen Poutsma
*/
public class StroapMessage extends AbstractSoapMessage implements StreamingWebServiceMessage {

    private final MultiValueMap<String, String> mimeHeaders = new LinkedMultiValueMap<String, String>();

    private StroapEnvelope envelope;

    private final StroapMessageFactory messageFactory;

    private final StartDocument startDocument;

    private final EndDocument endDocument;

    public StroapMessage(StroapMessageFactory messageFactory) {
        this(null, null, messageFactory);
    }

    public StroapMessage(MultiValueMap<String, String> mimeHeaders,
                         StroapEnvelope envelope,
                         StroapMessageFactory messageFactory) {
        Assert.notNull(messageFactory, "'messageFactory' must not be null");
        this.messageFactory = messageFactory;
        if (mimeHeaders != null) {
            this.mimeHeaders.putAll(mimeHeaders);
        }
        this.envelope = envelope != null ? envelope : new StroapEnvelope(messageFactory);
        if (!this.mimeHeaders.containsKey(TransportConstants.HEADER_CONTENT_TYPE)) {
            this.mimeHeaders
                    .set(TransportConstants.HEADER_CONTENT_TYPE, messageFactory.getSoapVersion().getContentType());
        }
        if (!this.mimeHeaders.containsKey(TransportConstants.HEADER_ACCEPT)) {
            this.mimeHeaders.set(TransportConstants.HEADER_ACCEPT, messageFactory.getSoapVersion().getContentType());
        }
        this.startDocument = messageFactory.getEventFactory().createStartDocument();
        this.endDocument = messageFactory.getEventFactory().createEndDocument();
    }

    static StroapMessage build(InputStream inputStream, StroapMessageFactory messageFactory)
            throws XMLStreamException, IOException {
        MultiValueMap<String, String> mimeHeaders = parseMimeHeaders(inputStream);
        XMLEventReader eventReader = messageFactory.getInputFactory().createXMLEventReader(inputStream);
        StroapEnvelope envelope = StroapEnvelope.build(eventReader, messageFactory);
        return new StroapMessage(mimeHeaders, envelope, messageFactory);
    }

    private static MultiValueMap<String, String> parseMimeHeaders(InputStream inputStream) throws IOException {
        MultiValueMap<String, String> mimeHeaders = new LinkedMultiValueMap<String, String>();
        if (inputStream instanceof TransportInputStream) {
            TransportInputStream transportInputStream = (TransportInputStream) inputStream;
            for (Iterator<String> headerNames = transportInputStream.getHeaderNames(); headerNames.hasNext();) {
                String headerName = headerNames.next();
                for (Iterator<String> headerValues = transportInputStream.getHeaders(headerName);
                     headerValues.hasNext();) {
                    String headerValue = headerValues.next();
                    StringTokenizer tokenizer = new StringTokenizer(headerValue, ",");
                    while (tokenizer.hasMoreTokens()) {
                        mimeHeaders.add(headerName, tokenizer.nextToken().trim());
                    }
                }
            }
        }
        return mimeHeaders;
    }

    public SoapEnvelope getEnvelope() throws SoapEnvelopeException {
        return envelope;
    }

    public void setStreamingPayload(StreamingPayload payload) {
        StroapBody soapBody = (StroapBody) getSoapBody();
        soapBody.setStreamingPayload(payload);
    }

    public String getSoapAction() {
        String soapAction = mimeHeaders.getFirst(TransportConstants.HEADER_SOAP_ACTION);
        return StringUtils.hasLength(soapAction) ? soapAction : TransportConstants.EMPTY_SOAP_ACTION;
    }

    public void setSoapAction(String soapAction) {
        soapAction = SoapUtils.escapeAction(soapAction);
        mimeHeaders.set(TransportConstants.HEADER_SOAP_ACTION, soapAction);
    }

    @Override
    public SoapVersion getVersion() {
        return messageFactory.getSoapVersion();
    }

    public Document getDocument() {
        try {
            DocumentBuilder documentBuilder = messageFactory.getDocumentBuilderFactory().newDocumentBuilder();
            try {
                Document result = documentBuilder.newDocument();
                DOMResult domResult = new DOMResult(result);
                XMLEventWriter eventWriter = messageFactory.getOutputFactory().createXMLEventWriter(domResult);
                eventWriter.add(startDocument);
                envelope.writeTo(new NoStartEndDocumentWriter(eventWriter));
                eventWriter.add(endDocument);
                eventWriter.flush();
                return result;
            }
            catch (XMLStreamException ignored) {
                // ignored
            }
            catch (UnsupportedOperationException ignored) {
                // ignored
            }

            // XMLOutputFactory does not support DOMResults, so let's do it the hard way
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            writeTo(bos);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            return documentBuilder.parse(bis);
        }
        catch (ParserConfigurationException ex) {
            throw new StroapMessageException("Could not create DocumentBuilderFactory", ex);
        }
        catch (SAXException ex) {
            throw new StroapMessageException("Could not save message as Document", ex);
        }
        catch (IOException ex) {
            throw new StroapMessageException("Could not save message as Document", ex);
        }
    }

    public void setDocument(Document document) {
        try {
            try {
                DOMSource domSource = new DOMSource(document);
                XMLEventReader eventReader = messageFactory.getInputFactory().createXMLEventReader(domSource);
                this.envelope = StroapEnvelope.build(eventReader, messageFactory);
                return;
            }
            catch (XMLStreamException ignored) {
                // ignored
            }
            catch (UnsupportedOperationException ignored) {
                // ignored
            }
            // XMLInputFactory does not support DOMSources, so let's do it the hard way
            DOMImplementation implementation = document.getImplementation();
            Assert.isInstanceOf(DOMImplementationLS.class, implementation);

            DOMImplementationLS loadSaveImplementation = (DOMImplementationLS) implementation;
            LSOutput output = loadSaveImplementation.createLSOutput();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            output.setByteStream(bos);

            LSSerializer serializer = loadSaveImplementation.createLSSerializer();
            serializer.write(document, output);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            XMLEventReader eventReader = messageFactory.getInputFactory().createXMLEventReader(bis);
            this.envelope = StroapEnvelope.build(eventReader, messageFactory);
        }
        catch (XMLStreamException ex) {
            throw new StroapMessageException("Could not read Document", ex);
        }
    }

    public void writeTo(OutputStream outputStream) throws IOException {
        if (outputStream instanceof TransportOutputStream) {
            TransportOutputStream tos = (TransportOutputStream) outputStream;
            for (Map.Entry<String, List<String>> entry : mimeHeaders.entrySet()) {
                String name = entry.getKey();
                for (String value : entry.getValue()) {
                    tos.addHeader(name, value);
                }
            }
        }
        try {
            XMLEventWriter eventWriter = messageFactory.getOutputFactory().createXMLEventWriter(outputStream);
            eventWriter.add(startDocument);
            envelope.writeTo(new NoStartEndDocumentWriter(eventWriter));
            eventWriter.add(endDocument);
            eventWriter.flush();
        }
        catch (XMLStreamException ex) {
            throw new StroapMessageException("Could not write message to OutputStream: " + ex.getMessage(), ex);
        }
    }

    public boolean isXopPackage() {
        return false;
    }

    public boolean convertToXopPackage() {
        return false;
    }

    public Attachment getAttachment(String contentId) throws AttachmentException {
        throw new UnsupportedOperationException();
    }

    public Iterator<Attachment> getAttachments() throws AttachmentException {
        return Collections.<Attachment>emptyList().iterator();
    }

    public Attachment addAttachment(String contentId, DataHandler dataHandler) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("StroapMessage");
        StroapBody body = (StroapBody) envelope.getBody();
        if (body != null) {
            builder.append(' ');
            builder.append(body.getPayloadName());
        }
        return builder.toString();
    }

    private static class NoStartEndDocumentWriter extends AbstractXMLEventWriter {

        private final XMLEventWriter delegate;

        private NoStartEndDocumentWriter(XMLEventWriter delegate) {
            this.delegate = delegate;
        }

        public void add(XMLEvent event) throws XMLStreamException {
            if (!event.isStartDocument() && !event.isEndDocument()) {
                delegate.add(event);
            }
        }
    }

}
TOP

Related Classes of org.springframework.ws.soap.stroap.StroapMessage$NoStartEndDocumentWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.