Package org.springframework.ws.soap.stroap

Source Code of org.springframework.ws.soap.stroap.StroapElement$StroapElementEventReader

/*
* 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.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Source;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.StaxUtils;
import org.springframework.ws.soap.SoapElement;
import org.springframework.ws.soap.SoapVersion;
import org.springframework.xml.stream.AbstractXMLEventReader;

/**
* @author Arjen Poutsma
*/
abstract class StroapElement implements SoapElement {

    protected static final String DEFAULT_PREFIX = "SOAP-ENV";

    private final StroapMessageFactory messageFactory;

    private StartElement startElement;

    private EndElement endElement;

    protected StroapElement(QName name, StroapMessageFactory messageFactory) {
        this(createStartElement(name, messageFactory), messageFactory);
    }

    private static StartElement createStartElement(QName name, StroapMessageFactory messageFactory) {
        if (!StringUtils.hasLength(name.getPrefix())) {
            name = new QName(name.getNamespaceURI(), name.getLocalPart(), DEFAULT_PREFIX);
        }
        return messageFactory.getEventFactory().createStartElement(name, null, null);
    }

    protected StroapElement(StartElement startElement, StroapMessageFactory messageFactory) {
        Assert.notNull(startElement, "'startElement' must not be null");
        Assert.notNull(messageFactory, "'messageFactory' must not be null");
        this.messageFactory = messageFactory;
        this.startElement = startElement;
        this.endElement = getEventFactory().createEndElement(startElement.getName(), startElement.getNamespaces());
    }

    public final Source getSource() {
        return StaxUtils.createCustomStaxSource(getEventReader(true));
    }

    protected XMLEventReader getEventReader(boolean documentEvents) {
        return new StroapElementEventReader(documentEvents);
    }

    public void writeTo(XMLEventWriter eventWriter) throws XMLStreamException {
        eventWriter.add(getEventReader(false));
    }

    protected StroapMessageFactory getMessageFactory() {
        return messageFactory;
    }

    protected final XMLEventFactory getEventFactory() {
        return getMessageFactory().getEventFactory();
    }

    protected SoapVersion getSoapVersion() {
        return getMessageFactory().getSoapVersion();
    }

    public final QName getName() {
        return getStartElement().getName();
    }

    protected abstract XMLEventReader getChildEventReader();

    public final Iterator<QName> getAllAttributes() {
        List<QName> result = new LinkedList<QName>();
        for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) {
            Attribute attribute = (Attribute) iterator.next();
            result.add(attribute.getName());
        }
        return result.iterator();
    }

    public final String getAttributeValue(QName name) {
        Attribute attribute = getStartElement().getAttributeByName(name);
        return attribute != null ? attribute.getValue() : null;
    }

    public final void removeAttribute(QName name) {
        List<Attribute> newAttributes = new LinkedList<Attribute>();
        for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) {
            Attribute attribute = (Attribute) iterator.next();
            if (!name.equals(attribute.getName())) {
                newAttributes.add(attribute);
            }
        }
        StartElement oldStartElement = getStartElement();
        this.startElement = getEventFactory().createStartElement(oldStartElement.getName(), newAttributes.iterator(),
                oldStartElement.getNamespaces());
    }

    public final void addAttribute(QName name, String value) {
        List<Attribute> newAttributes = new LinkedList<Attribute>();
        for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) {
            Attribute attribute = (Attribute) iterator.next();
            newAttributes.add(attribute);
        }
        Attribute newAttribute = getEventFactory().createAttribute(name, value);
        newAttributes.add(newAttribute);
        StartElement oldStartElement = getStartElement();
        this.startElement = getEventFactory().createStartElement(oldStartElement.getName(), newAttributes.iterator(),
                oldStartElement.getNamespaces());
    }

    public final void addNamespaceDeclaration(String prefix, String namespaceUri) {
        List<Namespace> newNamespaces = new LinkedList<Namespace>();
        for (Iterator iterator = getStartElement().getNamespaces(); iterator.hasNext();) {
            Namespace namespace = (Namespace) iterator.next();
            newNamespaces.add(namespace);
        }
        Namespace newNamespace;
        if (StringUtils.hasLength(prefix)) {
            newNamespace = getEventFactory().createNamespace(prefix, namespaceUri);
        }
        else {
            newNamespace = getEventFactory().createNamespace(namespaceUri);
        }
        newNamespaces.add(newNamespace);
        StartElement oldStartElement = getStartElement();
        this.startElement = getEventFactory()
                .createStartElement(oldStartElement.getName(), oldStartElement.getAttributes(),
                        newNamespaces.iterator());
    }

    protected final StartElement getStartElement() {
        return startElement;
    }

    protected final EndElement getEndElement() {
        return endElement;
    }

    private enum EVENT_READER_STATE {

        START_DOCUMENT,
        START_ELEMENT,
        CHILDREN,
        END_ELEMENT,
        END_DOCUMENT,
        DONE
    }

    private class StroapElementEventReader extends AbstractXMLEventReader {

        private EVENT_READER_STATE state;

        private boolean documentEvents;

        private final XMLEventReader childEventReader;

        private StroapElementEventReader(boolean documentEvents) {
            this.documentEvents = documentEvents;
            state = documentEvents ? EVENT_READER_STATE.START_DOCUMENT : EVENT_READER_STATE.START_ELEMENT;
            this.childEventReader = getChildEventReader();
        }

        public boolean hasNext() {
            if (documentEvents && state == EVENT_READER_STATE.DONE) {
                return false;
            }
            else if (!documentEvents && state == EVENT_READER_STATE.END_DOCUMENT) {
                return false;
            }
            else {
                return true;
            }
        }

        public XMLEvent nextEvent() throws XMLStreamException {
            switch (state) {
                case START_DOCUMENT:
                    state = EVENT_READER_STATE.START_ELEMENT;
                    return getEventFactory().createStartDocument();
                case START_ELEMENT:
                    state = EVENT_READER_STATE.CHILDREN;
                    return getStartElement();
                case CHILDREN:
                    if (!childEventReader.hasNext()) {
                        state = EVENT_READER_STATE.END_ELEMENT;
                        return nextEvent();
                    }
                    return childEventReader.nextEvent();
                case END_ELEMENT:
                    state = EVENT_READER_STATE.END_DOCUMENT;
                    return getEndElement();
                case END_DOCUMENT:
                    state = EVENT_READER_STATE.DONE;
                    return getEventFactory().createEndDocument();
                case DONE:
                    throw new NoSuchElementException();
                default:
                    throw new IllegalStateException();
            }
        }

        public XMLEvent peek() throws XMLStreamException {
            switch (state) {
                case START_DOCUMENT:
                    return getEventFactory().createStartDocument();
                case START_ELEMENT:
                    return getStartElement();
                case CHILDREN:
                    XMLEvent event = childEventReader.peek();
                    if (event == null) {
                        state = EVENT_READER_STATE.END_ELEMENT;
                        event = getEndElement();
                    }
                    return event;
                case END_ELEMENT:
                    return getEndElement();
                case END_DOCUMENT:
                    return getEventFactory().createEndDocument();
                case DONE:
                    return null;
                default:
                    throw new IllegalStateException();
            }

        }
    }
}
TOP

Related Classes of org.springframework.ws.soap.stroap.StroapElement$StroapElementEventReader

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.