--- /dev/null 2014-03-04 17:56:09.000000000 +0100 +++ new/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/LazyEnvelopeStaxReader.java 2014-03-04 17:56:09.000000000 +0100 @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.messaging.saaj.util.stax; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPException; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Node; + +import com.sun.xml.internal.messaging.saaj.soap.impl.BodyImpl; +import com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl; + +/** + * "Hybrid" reader which + * @author desagar + * + */ +public class LazyEnvelopeStaxReader extends com.sun.xml.internal.org.jvnet.staxex.util.DOMStreamReader { +// EnvelopeImpl env; + XMLStreamReader payloadReader = null; + boolean usePayloadReaderDelegate = false; + private QName bodyQName; + + public LazyEnvelopeStaxReader(EnvelopeImpl env) throws SOAPException, XMLStreamException { + super(env); +// this.env = env; + bodyQName = new QName(env.getNamespaceURI(), "Body"); + payloadReader = env.getStaxBridge().getPayloadReader(); + int eventType = getEventType(); + while (eventType != START_ELEMENT) { + eventType = nextTag(); + } + } + + public Object getProperty(String name) throws IllegalArgumentException { + if (usePayloadReaderDelegate) return payloadReader.getProperty(name); + return super.getProperty(name); + } + + public int next() throws XMLStreamException { +// boolean previouslyUsingPayloadReader = usePayloadReaderDelegate; + //call checkReaderStatus to advance to payloadReader if needed + checkReaderStatus(true); + + if (usePayloadReaderDelegate) return payloadReader.getEventType(); + + //if we just moved to payload reader, don't advance the pointer +// if (usePayloadReaderDelegate && !previouslyUsingPayloadReader) return payloadReader.getEventType(); + +// if (usePayloadReaderDelegate) return payloadReader.next(); + return getEventType(); + } + + public void require(int type, String namespaceURI, String localName) + throws XMLStreamException { + if (usePayloadReaderDelegate) payloadReader.require(type, namespaceURI, localName); + else super.require(type, namespaceURI, localName); + } + + public String getElementText() throws XMLStreamException { + if (usePayloadReaderDelegate) return payloadReader.getElementText(); + return super.getElementText(); + } + + public int nextTag() throws XMLStreamException { + if (usePayloadReaderDelegate) return payloadReader.nextTag(); + return super.nextTag(); + } + + public boolean hasNext() throws XMLStreamException { + checkReaderStatus(false); + boolean hasNext; + if (usePayloadReaderDelegate) { + hasNext = payloadReader.hasNext(); + } else { + hasNext = super.hasNext(); + } + + /*if (!hasNext && payloadReader != null) { + usePayloadReaderDelegate = true; + hasNext = payloadReader.hasNext(); + }*/ + return hasNext; + } + + private void checkReaderStatus(boolean advanceToNext) throws XMLStreamException { + //if we are using payloadReader, make sure it is not exhausted + //if it is, return to DOM based reader for remaining end elements (body and envelope) + if (usePayloadReaderDelegate) { + if (!payloadReader.hasNext()) { + usePayloadReaderDelegate = false; + } + } else if (START_ELEMENT == getEventType()) { + //if not on payload reader, check if we need to switch to payload reader + + //if the current event is the SOAP body element start, + //and the body is lazy, switch to the payload reader + if (bodyQName.equals(getName())) { + //if we are just switching to payload reader, don't advance...payload reader + //will already be on the first payload element + usePayloadReaderDelegate = true; + advanceToNext = false; + } + } + + if (advanceToNext) { + if (usePayloadReaderDelegate) { + payloadReader.next(); + } else { + super.next(); + } + } + } + + public void close() throws XMLStreamException { + if (usePayloadReaderDelegate) payloadReader.close(); + else super.close(); + } + + public String getNamespaceURI(String prefix) { + if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(prefix); + return super.getNamespaceURI(prefix); + } + + public boolean isStartElement() { + if (usePayloadReaderDelegate) return payloadReader.isStartElement(); + return super.isStartElement(); + } + + public boolean isEndElement() { + if (usePayloadReaderDelegate) return payloadReader.isEndElement(); + return super.isEndElement(); + } + + public boolean isCharacters() { + if (usePayloadReaderDelegate) return payloadReader.isCharacters(); + return super.isEndElement(); + } + + public boolean isWhiteSpace() { + if (usePayloadReaderDelegate) return payloadReader.isWhiteSpace(); + return super.isWhiteSpace(); + } + + public String getAttributeValue(String namespaceURI, String localName) { + if (usePayloadReaderDelegate) return payloadReader.getAttributeValue(namespaceURI, localName); + return super.getAttributeValue(namespaceURI, localName); + } + + public int getAttributeCount() { + if (usePayloadReaderDelegate) return payloadReader.getAttributeCount(); + return super.getAttributeCount(); + } + + public QName getAttributeName(int index) { + if (usePayloadReaderDelegate) return payloadReader.getAttributeName(index); + return super.getAttributeName(index); + } + + public String getAttributeNamespace(int index) { + if (usePayloadReaderDelegate) return payloadReader.getAttributeNamespace(index); + return super.getAttributeNamespace(index); + } + + public String getAttributeLocalName(int index) { + if (usePayloadReaderDelegate) return payloadReader.getAttributeLocalName(index); + return super.getAttributeLocalName(index); + } + + public String getAttributePrefix(int index) { + if (usePayloadReaderDelegate) return payloadReader.getAttributePrefix(index); + return super.getAttributePrefix(index); + } + + public String getAttributeType(int index) { + if (usePayloadReaderDelegate) return payloadReader.getAttributeType(index); + return super.getAttributeType(index); + } + + public String getAttributeValue(int index) { + if (usePayloadReaderDelegate) return payloadReader.getAttributeValue(index); + return super.getAttributeValue(index); + } + + public boolean isAttributeSpecified(int index) { + if (usePayloadReaderDelegate) return payloadReader.isAttributeSpecified(index); + return super.isAttributeSpecified(index); + } + + public int getNamespaceCount() { + if (usePayloadReaderDelegate) return payloadReader.getNamespaceCount(); + return super.getNamespaceCount(); + } + + public String getNamespacePrefix(int index) { + if (usePayloadReaderDelegate) return payloadReader.getNamespacePrefix(index); + return super.getNamespacePrefix(index); + } + + public String getNamespaceURI(int index) { + if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(index); + return super.getNamespaceURI(index); + } + + public NamespaceContext getNamespaceContext() { + if (usePayloadReaderDelegate) return payloadReader.getNamespaceContext(); + return super.getNamespaceContext(); + } + + public int getEventType() { + if (usePayloadReaderDelegate) return payloadReader.getEventType(); + return super.getEventType(); + } + + public String getText() { + if (usePayloadReaderDelegate) return payloadReader.getText(); + return super.getText(); + } + + public char[] getTextCharacters() { + if (usePayloadReaderDelegate) return payloadReader.getTextCharacters(); + return super.getTextCharacters(); + } + + public int getTextCharacters(int sourceStart, char[] target, + int targetStart, int length) throws XMLStreamException { + if (usePayloadReaderDelegate) return payloadReader.getTextCharacters(sourceStart, target, targetStart, + length); + return super.getTextCharacters(sourceStart, target, targetStart, length); + } + + public int getTextStart() { + if (usePayloadReaderDelegate) return payloadReader.getTextStart(); + return super.getTextStart(); + } + + public int getTextLength() { + if (usePayloadReaderDelegate) return payloadReader.getTextLength(); + return super.getTextLength(); + } + + public String getEncoding() { + if (usePayloadReaderDelegate) return payloadReader.getEncoding(); + return super.getEncoding(); + } + + public boolean hasText() { + if (usePayloadReaderDelegate) return payloadReader.hasText(); + return super.hasText(); + } + + public Location getLocation() { + if (usePayloadReaderDelegate) return payloadReader.getLocation(); + return super.getLocation(); + } + + public QName getName() { + if (usePayloadReaderDelegate) return payloadReader.getName(); + return super.getName(); + } + + public String getLocalName() { + if (usePayloadReaderDelegate) return payloadReader.getLocalName(); + return super.getLocalName(); + } + + public boolean hasName() { + if (usePayloadReaderDelegate) return payloadReader.hasName(); + return super.hasName(); + } + + public String getNamespaceURI() { + if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(); + return super.getNamespaceURI(); + } + + public String getPrefix() { + if (usePayloadReaderDelegate) return payloadReader.getPrefix(); + return super.getPrefix(); + } + + public String getVersion() { + if (usePayloadReaderDelegate) return payloadReader.getVersion(); + return super.getVersion(); + } + + public boolean isStandalone() { + if (usePayloadReaderDelegate) return payloadReader.isStandalone(); + return super.isStandalone(); + } + + public boolean standaloneSet() { + if (usePayloadReaderDelegate) return payloadReader.standaloneSet(); + return super.standaloneSet(); + } + + public String getCharacterEncodingScheme() { + if (usePayloadReaderDelegate) return payloadReader.getCharacterEncodingScheme(); + return super.getCharacterEncodingScheme(); + } + + public String getPITarget() { + if (usePayloadReaderDelegate) return payloadReader.getPITarget(); + return super.getPITarget(); + } + + public String getPIData() { + if (usePayloadReaderDelegate) return payloadReader.getPIData(); + return super.getPIData(); + } + + //make sure that message is not realized as a result of call + //to getFirstChild + protected Node getFirstChild(Node node) { + if (node instanceof BodyImpl) { + return ((BodyImpl) node).getFirstChildNoMaterialize(); + } else { + return node.getFirstChild(); + } + } + + protected Node getNextSibling(Node node) { + if (node instanceof BodyImpl) { + //body is not expected to have a next sibling - even if it does + //we would have to materialize the node to retrieve it. + //Since we don't want to materialize it right now, just return null + return null; + } + return node.getNextSibling(); + } + +}