Package org.springframework.ws.server.endpoint

Source Code of org.springframework.ws.server.endpoint.AbstractXomPayloadEndpoint$XomSourceCallback

/*
* Copyright 2005-2014 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.server.endpoint;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Locale;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import nu.xom.Attribute;
import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.NodeFactory;
import nu.xom.ParentNode;
import nu.xom.ParsingException;
import nu.xom.Serializer;
import nu.xom.ValidityException;
import nu.xom.converters.DOMConverter;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import org.springframework.core.NestedRuntimeException;
import org.springframework.xml.namespace.QNameUtils;
import org.springframework.xml.transform.TransformerObjectSupport;
import org.springframework.xml.transform.TraxUtils;

/**
* Abstract base class for endpoints that handle the message payload as XOM elements. Offers the message payload as a
* XOM {@code Element}, and allows subclasses to create a response by returning an {@code Element}.
*
* <p>An {@code AbstractXomPayloadEndpoint} only accept one payload element. Multiple payload elements are not in
* accordance with WS-I.
*
* @author Arjen Poutsma
* @see Element
* @since 1.0.0
* @deprecated as of Spring Web Services 2.0, in favor of annotated endpoints
*/
@Deprecated
@SuppressWarnings("Since15")
public abstract class AbstractXomPayloadEndpoint extends TransformerObjectSupport implements PayloadEndpoint {

    @Override
    public final Source invoke(Source request) throws Exception {
        Element requestElement = null;
        if (request != null) {
            XomSourceCallback sourceCallback = new XomSourceCallback();
            try {
                TraxUtils.doWithSource(request, sourceCallback);
            }
            catch (XomParsingException ex) {
                throw (ParsingException) ex.getCause();
            }
            requestElement = sourceCallback.element;
        }
        Element responseElement = invokeInternal(requestElement);
        return responseElement != null ? convertResponse(responseElement) : null;
    }

    private Source convertResponse(Element responseElement) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        Serializer serializer = createSerializer(os);
        Document document = responseElement.getDocument();
        if (document == null) {
            document = new Document(responseElement);
        }
        serializer.write(document);
        byte[] bytes = os.toByteArray();
        return new StreamSource(new ByteArrayInputStream(bytes));
    }

    /**
     * Creates a {@link Serializer} to be used for writing the response to.
     *
     * <p>Default implementation uses the UTF-8 encoding and does not set any options, but this may be changed in
     * subclasses.
     *
     * @param outputStream the output stream to serialize to
     * @return the serializer
     */
    protected Serializer createSerializer(OutputStream outputStream) {
        return new Serializer(outputStream);
    }

    /**
     * Template method. Subclasses must implement this. Offers the request payload as a XOM {@code Element}, and
     * allows subclasses to return a response {@code Element}.
     *
     * @param requestElement the contents of the SOAP message as XOM element
     * @return the response element. Can be {@code null} to specify no response.
     */
    protected abstract Element invokeInternal(Element requestElement) throws Exception;

    private static class XomSourceCallback implements TraxUtils.SourceCallback {

        private Element element;

        @Override
        public void domSource(Node node) {
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                element = DOMConverter.convert((org.w3c.dom.Element) node);
            }
            else if (node.getNodeType() == Node.DOCUMENT_NODE) {
                Document document = DOMConverter.convert((org.w3c.dom.Document) node);
                element = document.getRootElement();
            }
            else {
                throw new IllegalArgumentException("DOMSource contains neither Document nor Element");
            }
        }

        @Override
        public void saxSource(XMLReader reader, InputSource inputSource) throws IOException, SAXException {
            try {
                Builder builder = new Builder(reader);
                Document document;
                if (inputSource.getByteStream() != null) {
                    document = builder.build(inputSource.getByteStream());
                }
                else if (inputSource.getCharacterStream() != null) {
                    document = builder.build(inputSource.getCharacterStream());
                }
                else {
                    throw new IllegalArgumentException(
                            "InputSource in SAXSource contains neither byte stream nor character stream");
                }
                element = document.getRootElement();
            }
            catch (ValidityException ex) {
                throw new XomParsingException(ex);
            }
            catch (ParsingException ex) {
                throw new XomParsingException(ex);
            }
        }

        @Override
        public void staxSource(XMLEventReader eventReader) throws XMLStreamException {
            throw new IllegalArgumentException("XMLEventReader not supported");
        }

        @Override
        public void staxSource(XMLStreamReader streamReader) throws XMLStreamException {
            Document document = StaxStreamConverter.convert(streamReader);
            element = document.getRootElement();
        }

        @Override
        public void streamSource(InputStream inputStream) throws IOException {
            try {
                Builder builder = new Builder();
                Document document = builder.build(inputStream);
                element = document.getRootElement();
            }
            catch (ParsingException ex) {
                throw new XomParsingException(ex);
            }
        }

        @Override
        public void streamSource(Reader reader) throws IOException {
            try {
                Builder builder = new Builder();
                Document document = builder.build(reader);
                element = document.getRootElement();
            }
            catch (ParsingException ex) {
                throw new XomParsingException(ex);
            }
        }

        @Override
        public void source(String systemId) throws Exception {
            try {
                Builder builder = new Builder();
                Document document = builder.build(systemId);
                element = document.getRootElement();
            }
            catch (ParsingException ex) {
                throw new XomParsingException(ex);
            }
        }
    }

  @SuppressWarnings("serial")
    private static class XomParsingException extends NestedRuntimeException {

        private XomParsingException(ParsingException ex) {
            super(ex.getMessage(), ex);
        }
    }

    private static class StaxStreamConverter {

        private static Document convert(XMLStreamReader streamReader) throws XMLStreamException {
            NodeFactory nodeFactory = new NodeFactory();
            Document document = null;
            Element element = null;
            ParentNode parent = null;
            boolean documentFinished = false;
            while (streamReader.hasNext()) {
                int event = streamReader.next();
                switch (event) {
                    case XMLStreamConstants.START_DOCUMENT:
                        document = nodeFactory.startMakingDocument();
                        parent = document;
                        break;
                    case XMLStreamConstants.END_DOCUMENT:
                        nodeFactory.finishMakingDocument(document);
                        documentFinished = true;
                        break;
                    case XMLStreamConstants.START_ELEMENT:
                        if (document == null) {
                            document = nodeFactory.startMakingDocument();
                            parent = document;
                        }
                        String name = QNameUtils.toQualifiedName(streamReader.getName());
                        if (element == null) {
                            element = nodeFactory.makeRootElement(name, streamReader.getNamespaceURI());
                            document.setRootElement(element);
                        }
                        else {
                            element = nodeFactory.startMakingElement(name, streamReader.getNamespaceURI());
                            parent.appendChild(element);
                        }
                        convertNamespaces(streamReader, element);
                        convertAttributes(streamReader, nodeFactory);
                        parent = element;
                        break;
                    case XMLStreamConstants.END_ELEMENT:
                        nodeFactory.finishMakingElement(element);
                        parent = parent.getParent();
                        break;
                    case XMLStreamConstants.ATTRIBUTE:
                        convertAttributes(streamReader, nodeFactory);
                        break;
                    case XMLStreamConstants.CHARACTERS:
                        nodeFactory.makeText(streamReader.getText());
                        break;
                    case XMLStreamConstants.COMMENT:
                        nodeFactory.makeComment(streamReader.getText());
                        break;
                    default:
                        break;
                }
            }
            if (!documentFinished) {
                nodeFactory.finishMakingDocument(document);
            }
            return document;
        }

        private static void convertNamespaces(XMLStreamReader streamReader, Element element) {
            for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
                String uri = streamReader.getNamespaceURI(i);
                String prefix = streamReader.getNamespacePrefix(i);

                element.addNamespaceDeclaration(prefix, uri);
            }

        }

        private static void convertAttributes(XMLStreamReader streamReader, NodeFactory nodeFactory) {
            for (int i = 0; i < streamReader.getAttributeCount(); i++) {
                String name = QNameUtils.toQualifiedName(streamReader.getAttributeName(i));
                String uri = streamReader.getAttributeNamespace(i);
                String value = streamReader.getAttributeValue(i);
                Attribute.Type type = convertAttributeType(streamReader.getAttributeType(i));

                nodeFactory.makeAttribute(name, uri, value, type);
            }
        }

        private static Attribute.Type convertAttributeType(String type) {
            type = type.toUpperCase(Locale.ENGLISH);
            if ("CDATA".equals(type)) {
                return Attribute.Type.CDATA;
            }
            else if ("ENTITIES".equals(type)) {
                return Attribute.Type.ENTITIES;
            }
            else if ("ENTITY".equals(type)) {
                return Attribute.Type.ENTITY;
            }
            else if ("ENUMERATION".equals(type)) {
                return Attribute.Type.ENUMERATION;
            }
            else if ("ID".equals(type)) {
                return Attribute.Type.ID;
            }
            else if ("IDREF".equals(type)) {
                return Attribute.Type.IDREF;
            }
            else if ("IDREFS".equals(type)) {
                return Attribute.Type.IDREFS;
            }
            else if ("NMTOKEN".equals(type)) {
                return Attribute.Type.NMTOKEN;
            }
            else if ("NMTOKENS".equals(type)) {
                return Attribute.Type.NMTOKENS;
            }
            else if ("NOTATION".equals(type)) {
                return Attribute.Type.NOTATION;
            }
            else {
                return Attribute.Type.UNDECLARED;
            }
        }

    }
}
TOP

Related Classes of org.springframework.ws.server.endpoint.AbstractXomPayloadEndpoint$XomSourceCallback

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.