cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From asold...@apache.org
Subject git commit: [CXF-5891] Avoid building DOM document when no header is found in the message
Date Mon, 11 Aug 2014 16:24:17 GMT
Repository: cxf
Updated Branches:
  refs/heads/3.0.x-fixes 00db94d84 -> 20e852313


[CXF-5891] Avoid building DOM document when no header is found in the message


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/20e85231
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/20e85231
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/20e85231

Branch: refs/heads/3.0.x-fixes
Commit: 20e8523136c069d35de7f42cb1f1146070a9e4e5
Parents: 00db94d
Author: Alessio Soldano <asoldano@redhat.com>
Authored: Mon Aug 11 18:04:36 2014 +0200
Committer: Alessio Soldano <asoldano@redhat.com>
Committed: Mon Aug 11 18:12:09 2014 +0200

----------------------------------------------------------------------
 .../org/apache/cxf/staxutils/StaxUtils.java     | 324 +++++++++++++++++--
 .../interceptor/ReadHeadersInterceptor.java     | 226 +++++++++----
 2 files changed, 455 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/20e85231/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java b/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
index a9590fd..a752fe3 100644
--- a/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
+++ b/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
@@ -52,6 +52,7 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
 import javax.xml.stream.events.DTD;
 import javax.xml.stream.events.Namespace;
 import javax.xml.stream.events.StartDocument;
@@ -1345,45 +1346,302 @@ public final class StaxUtils {
             }
         }
     }
-    private static boolean addLocation(Document doc, Node node, 
-                                    XMLStreamReader reader,
-                                    boolean recordLoc) {
-        if (recordLoc) {
-            Location loc = reader.getLocation();
-            if (loc != null && (loc.getColumnNumber() != 0 || loc.getLineNumber()
!= 0)) {
-                try {
-                    final int charOffset = loc.getCharacterOffset();
-                    final int colNum = loc.getColumnNumber();
-                    final int linNum = loc.getLineNumber();
-                    final String pubId = loc.getPublicId() == null ? doc.getDocumentURI()
: loc.getPublicId();
-                    final String sysId = loc.getSystemId() == null ? doc.getDocumentURI()
: loc.getSystemId();
-                    Location loc2 = new Location() {
-                        public int getCharacterOffset() {
-                            return charOffset;
-                        }
-                        public int getColumnNumber() {
-                            return colNum;
-                        }
-                        public int getLineNumber() {
-                            return linNum;
-                        }
-                        public String getPublicId() {
-                            return pubId;
-                        }
-                        public String getSystemId() {
-                            return sysId;
-                        }
-                    };
-                    node.setUserData("location", loc2, LocationUserDataHandler.INSTANCE);
-                } catch (Throwable ex) {
-                    //possibly not DOM level 3, won't be able to record this then
-                    return false;
+    
+    public static class StreamToDOMContext {
+        private Stack<Node> stack = new Stack<Node>();
+        private int elementCount;
+        private boolean repairing;
+        private boolean recordLoc;
+        private boolean threshold;
+        
+        public StreamToDOMContext(boolean repairing, boolean recordLoc, boolean threshold)
{
+            this.repairing = repairing;
+            this.recordLoc = recordLoc;
+            this.threshold = threshold;
+        }
+        
+        public void setRecordLoc(boolean recordLoc) {
+            this.recordLoc = recordLoc;
+        }
+        
+        public boolean isRecordLoc() {
+            return this.recordLoc;
+        }
+        
+        public boolean isRepairing() {
+            return this.repairing;
+        }
+
+        public boolean isThreshold() {
+            return this.threshold;
+        }
+        
+        public int incrementCount() {
+            return ++elementCount;
+        }
+        
+        public int decreaseCount() {
+            return --elementCount;
+        }
+        
+        public int getCount() {
+            return elementCount;
+        }
+        
+        public Node pushToStack(Node node) {
+            return stack.push(node);
+        }
+        
+        public Node popFromStack() {
+            return stack.pop();
+        }
+        
+        public int getStackSize() {
+            return stack.size();
+        }
+        
+        public boolean isStackEmpty() {
+            return stack.isEmpty();
+        }
+    }
+    
+    public static void readDocElements(Document doc, Node parent, XMLStreamReader reader,
StreamToDOMContext context)
+        throws XMLStreamException {
+        int event = reader.getEventType();
+        while (reader.hasNext()) {
+            switch (event) {
+            case XMLStreamConstants.START_ELEMENT: {
+                context.incrementCount();
+                Element e;
+                if (!StringUtils.isEmpty(reader.getPrefix())) {
+                    e = doc.createElementNS(reader.getNamespaceURI(), 
+                                            reader.getPrefix() + ":" + reader.getLocalName());
+                } else {
+                    e = doc.createElementNS(reader.getNamespaceURI(), reader.getLocalName());
+                }
+                e = (Element)parent.appendChild(e);
+                if (context.isRecordLoc()) {
+                    context.setRecordLoc(addLocation(doc, e, reader.getLocation(), context.isRecordLoc()));
+                }
+
+                for (int ns = 0; ns < reader.getNamespaceCount(); ns++) {
+                    String uri = reader.getNamespaceURI(ns);
+                    String prefix = reader.getNamespacePrefix(ns);
+
+                    declare(e, uri, prefix);
+                }
+
+                for (int att = 0; att < reader.getAttributeCount(); att++) {
+                    String name = reader.getAttributeLocalName(att);
+                    String prefix = reader.getAttributePrefix(att);
+                    if (prefix != null && prefix.length() > 0) {
+                        name = prefix + ":" + name;
+                    }
+
+                    Attr attr = doc.createAttributeNS(reader.getAttributeNamespace(att),
name);
+                    attr.setValue(reader.getAttributeValue(att));
+                    e.setAttributeNode(attr);
+                }
+
+                if (context.isRepairing() && !isDeclared(e, reader.getNamespaceURI(),
reader.getPrefix())) {
+                    declare(e, reader.getNamespaceURI(), reader.getPrefix());
+                }
+                context.pushToStack(parent);
+                if (context.isThreshold() && innerElementLevelThreshold != -1 
+                    && context.getStackSize() >= innerElementLevelThreshold) {
+                    throw new DepthExceededStaxException("reach the innerElementLevelThreshold:"

+                                               + innerElementLevelThreshold);
+                }
+                if (context.isThreshold() && innerElementCountThreshold != -1 
+                    && context.getCount() >= innerElementCountThreshold) {
+                    throw new DepthExceededStaxException("reach the innerElementCountThreshold:"

+                                               + innerElementCountThreshold);
+                }
+                parent = e;
+                break;
+            }
+            case XMLStreamConstants.END_ELEMENT:
+                if (context.isStackEmpty()) {
+                    return;
+                }
+                parent = context.popFromStack();
+                if (parent instanceof Document) {
+                    return;
+                }
+                break;
+            case XMLStreamConstants.NAMESPACE:
+                break;
+            case XMLStreamConstants.ATTRIBUTE:
+                break;
+            case XMLStreamConstants.CHARACTERS:
+                if (parent != null) {
+                    context.setRecordLoc(addLocation(doc, 
+                                                     parent.appendChild(doc.createTextNode(reader.getText())),
+                                                     reader.getLocation(), context.isRecordLoc()));
+                }
+                break;
+            case XMLStreamConstants.COMMENT:
+                if (parent != null) {
+                    parent.appendChild(doc.createComment(reader.getText()));
                 }
+                break;
+            case XMLStreamConstants.CDATA:
+                context.setRecordLoc(addLocation(doc, 
+                                        parent.appendChild(doc.createCDATASection(reader.getText())),
+                                        reader.getLocation(), context.isRecordLoc()));
+                break;
+            case XMLStreamConstants.PROCESSING_INSTRUCTION:
+                parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(),
reader.getPIData()));
+                break;
+            case XMLStreamConstants.ENTITY_REFERENCE:
+                parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(),
reader.getPIData()));
+                break;
+            default:
+                break;
+            }
+
+            if (reader.hasNext()) {
+                event = reader.next();
+            }
+        }
+    }
+    
+    public static Node readDocElement(Document doc, Node parent, XMLEvent ev, StreamToDOMContext
context)
+        throws XMLStreamException {
+        switch (ev.getEventType()) {
+        case XMLStreamConstants.START_ELEMENT: {
+            context.incrementCount();
+            Element e;
+            StartElement startElem = ev.asStartElement();
+            QName name = startElem.getName();
+            if (!StringUtils.isEmpty(name.getPrefix())) {
+                e = doc.createElementNS(name.getNamespaceURI(), 
+                                        name.getPrefix() + ":" + name.getLocalPart());
+            } else {
+                e = doc.createElementNS(name.getNamespaceURI(), name.getLocalPart());
+            }
+            e = (Element)parent.appendChild(e);
+            if (context.isRecordLoc()) {
+                context.setRecordLoc(addLocation(doc, e, startElem.getLocation(), context.isRecordLoc()));
+            }
+
+            if (context.isRepairing() && !isDeclared(e, name.getNamespaceURI(), name.getPrefix()))
{
+                declare(e, name.getNamespaceURI(), name.getPrefix());
+            }
+            context.pushToStack(parent);
+            if (context.isThreshold() && innerElementLevelThreshold != -1 
+                && context.getStackSize() >= innerElementLevelThreshold) {
+                throw new DepthExceededStaxException("reach the innerElementLevelThreshold:"

+                                           + innerElementLevelThreshold);
+            }
+            if (context.isThreshold() && innerElementCountThreshold != -1 
+                && context.getCount() >= innerElementCountThreshold) {
+                throw new DepthExceededStaxException("reach the innerElementCountThreshold:"

+                                           + innerElementCountThreshold);
+            }
+            parent = e;
+            break;
+        }
+        case XMLStreamConstants.END_ELEMENT:
+            if (context.isStackEmpty()) {
+                return parent;
+            }
+            parent = context.popFromStack();
+            if (parent instanceof Document) {
+                return parent;
+            }
+            break;
+        case XMLStreamConstants.NAMESPACE:
+            Namespace ns = (Namespace)ev;
+            declare((Element)parent, ns.getNamespaceURI(), ns.getPrefix());
+            break;
+        case XMLStreamConstants.ATTRIBUTE:
+            Attribute at = (Attribute)ev;
+            QName qname = at.getName();
+            String attName = qname.getLocalPart();
+            String attPrefix = qname.getPrefix();
+            if (attPrefix != null && attPrefix.length() > 0) {
+                attName = attPrefix + ":" + attName;
+            }
+            Attr attr = doc.createAttributeNS(qname.getNamespaceURI(), attName);
+            attr.setValue(at.getValue());
+            ((Element)parent).setAttributeNode(attr);
+            break;
+        case XMLStreamConstants.CHARACTERS:
+            if (parent != null) {
+                Characters characters = ev.asCharacters();
+                context.setRecordLoc(addLocation(doc, 
+                                                 parent.appendChild(doc.createTextNode(characters.getData())),
+                                                 characters.getLocation(), context.isRecordLoc()));
+            }
+            break;
+        case XMLStreamConstants.COMMENT:
+            if (parent != null) {
+                parent.appendChild(doc.createComment(((javax.xml.stream.events.Comment)ev).getText()));
+            }
+            break;
+        case XMLStreamConstants.CDATA:
+            Characters characters = ev.asCharacters();
+            context.setRecordLoc(addLocation(doc, 
+                                             parent.appendChild(doc.createCDATASection(characters.getData())),
+                                             characters.getLocation(), context.isRecordLoc()));
+            break;
+        case XMLStreamConstants.PROCESSING_INSTRUCTION:
+            parent.appendChild(doc.createProcessingInstruction(((ProcessingInstruction)ev).getTarget(),
+                                                               ((ProcessingInstruction)ev).getData()));
+            break;
+        case XMLStreamConstants.ENTITY_REFERENCE:
+            javax.xml.stream.events.EntityReference er = (javax.xml.stream.events.EntityReference)ev;
+            parent.appendChild(doc.createEntityReference(er.getName()));
+            break;
+        default:
+            break;
+        }
+        return parent;
+    }
+    
+    private static boolean addLocation(Document doc, Node node, 
+                                       Location loc,
+                                       boolean recordLoc) {
+        if (recordLoc && loc != null && (loc.getColumnNumber() != 0 || loc.getLineNumber()
!= 0)) {
+            try {
+                final int charOffset = loc.getCharacterOffset();
+                final int colNum = loc.getColumnNumber();
+                final int linNum = loc.getLineNumber();
+                final String pubId = loc.getPublicId() == null ? doc.getDocumentURI() : loc.getPublicId();
+                final String sysId = loc.getSystemId() == null ? doc.getDocumentURI() : loc.getSystemId();
+                Location loc2 = new Location() {
+                    public int getCharacterOffset() {
+                        return charOffset;
+                    }
+                    public int getColumnNumber() {
+                        return colNum;
+                    }
+                    public int getLineNumber() {
+                        return linNum;
+                    }
+                    public String getPublicId() {
+                        return pubId;
+                    }
+                    public String getSystemId() {
+                        return sysId;
+                    }
+                };
+                node.setUserData("location", loc2, LocationUserDataHandler.INSTANCE);
+            } catch (Throwable ex) {
+                //possibly not DOM level 3, won't be able to record this then
+                return false;
             }
         }
         return recordLoc;
     }
     
+    private static boolean addLocation(Document doc, Node node, 
+                                    XMLStreamReader reader,
+                                    boolean recordLoc) {
+        return addLocation(doc, node, reader.getLocation(), recordLoc);
+    }
+    
     private static class LocationUserDataHandler implements UserDataHandler {
         public static final LocationUserDataHandler INSTANCE = new LocationUserDataHandler();
         

http://git-wip-us.apache.org/repos/asf/cxf/blob/20e85231/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
index 478e2b0..5472d9a 100644
--- a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
+++ b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
@@ -20,20 +20,22 @@
 package org.apache.cxf.binding.soap.interceptor;
 
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Logger;
 
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventFactory;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.events.XMLEvent;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
-//import org.w3c.dom.NodeList;
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.annotations.SchemaValidation.SchemaValidationType;
@@ -56,6 +58,7 @@ import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.phase.Phase;
 import org.apache.cxf.staxutils.PartialXMLStreamReader;
 import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.staxutils.StaxUtils.StreamToDOMContext;
 import org.apache.cxf.staxutils.W3CDOMStreamWriter;
 
 
@@ -179,75 +182,72 @@ public class ReadHeadersInterceptor extends AbstractSoapInterceptor
{
                     doc = (Document)nd;
                     StaxUtils.readDocElements(doc, doc, filteredReader, false, false);
                 } else {
-                    doc = StaxUtils.read(filteredReader);
-                    message.setContent(Node.class, doc);
+                    HeadersProcessor processor = new HeadersProcessor(soapVersion);
+                    doc = processor.process(filteredReader);
+                    if (doc != null) {
+                        message.setContent(Node.class, doc);
+                    }
                 }
 
                 // Find header
-                // TODO - we could stream read the "known" headers and just DOM read the

-                // unknown ones
-                Element element = doc.getDocumentElement();
-                QName header = soapVersion.getHeader();                
-                List<Element> elemList = 
-                    DOMUtils.findAllElementsByTagNameNS(element, 
-                                                        header.getNamespaceURI(), 
-                                                        header.getLocalPart());
-                for (Element elem : elemList) {
-                    Element hel = DOMUtils.getFirstElement(elem);
-                    while (hel != null) {
-                        // Need to add any attributes that are present on the parent element
-                        // which otherwise would be lost.
-                        if (elem.hasAttributes()) {
-                            NamedNodeMap nnp = elem.getAttributes();
-                            for (int ct = 0; ct < nnp.getLength(); ct++) {
-                                Node attr = nnp.item(ct);
-                                Node headerAttrNode = hel.hasAttributes() 
-                                        ?  hel.getAttributes().getNamedItemNS(
-                                                        attr.getNamespaceURI(), attr.getLocalName())

-                                        : null;
-                                
-                                if (headerAttrNode == null) {
-                                    Attr attribute = hel.getOwnerDocument().createAttributeNS(
-                                            attr.getNamespaceURI(), 
-                                            attr.getNodeName());
-                                    attribute.setNodeValue(attr.getNodeValue());
-                                    hel.setAttributeNodeNS(attribute);
+                if (doc != null) {
+                    Element element = doc.getDocumentElement();
+                    QName header = soapVersion.getHeader();
+                    List<Element> elemList = DOMUtils.findAllElementsByTagNameNS(element,
+                                                                                 header.getNamespaceURI(),
+                                                                                 header.getLocalPart());
+                    for (Element elem : elemList) {
+                        Element hel = DOMUtils.getFirstElement(elem);
+                        while (hel != null) {
+                            // Need to add any attributes that are present on the parent
element
+                            // which otherwise would be lost.
+                            if (elem.hasAttributes()) {
+                                NamedNodeMap nnp = elem.getAttributes();
+                                for (int ct = 0; ct < nnp.getLength(); ct++) {
+                                    Node attr = nnp.item(ct);
+                                    Node headerAttrNode = hel.hasAttributes() ? hel.getAttributes()
+                                        .getNamedItemNS(attr.getNamespaceURI(), attr.getLocalName())
: null;
+
+                                    if (headerAttrNode == null) {
+                                        Attr attribute = hel.getOwnerDocument()
+                                            .createAttributeNS(attr.getNamespaceURI(), attr.getNodeName());
+                                        attribute.setNodeValue(attr.getNodeValue());
+                                        hel.setAttributeNodeNS(attribute);
+                                    }
                                 }
                             }
-                        }
-                        
-                        HeaderProcessor p = bus == null ? null : bus.getExtension(HeaderManager.class)
-                            .getHeaderProcessor(hel.getNamespaceURI());
 
-                        Object obj;
-                        DataBinding dataBinding = null;
-                        if (p == null || p.getDataBinding() == null) {
-                            obj = hel;
-                        } else {
-                            dataBinding = p.getDataBinding();
-                            obj = dataBinding.createReader(Node.class).read(hel);
-                        }
-                        //TODO - add the interceptors
-                        
-                        SoapHeader shead = new SoapHeader(new QName(hel.getNamespaceURI(),
-                                                                    hel.getLocalName()),
-                                                           obj,
-                                                           dataBinding);
-                        String mu = hel.getAttributeNS(soapVersion.getNamespace(),
-                                                      soapVersion.getAttrNameMustUnderstand());
-                        String act = hel.getAttributeNS(soapVersion.getNamespace(),
-                                                        soapVersion.getAttrNameRole());
+                            HeaderProcessor p = bus == null ? null : bus.getExtension(HeaderManager.class)
+                                .getHeaderProcessor(hel.getNamespaceURI());
+
+                            Object obj;
+                            DataBinding dataBinding = null;
+                            if (p == null || p.getDataBinding() == null) {
+                                obj = hel;
+                            } else {
+                                dataBinding = p.getDataBinding();
+                                obj = dataBinding.createReader(Node.class).read(hel);
+                            }
+                            // TODO - add the interceptors
+
+                            SoapHeader shead = new SoapHeader(new QName(hel.getNamespaceURI(),
+                                                                        hel.getLocalName()),
obj, dataBinding);
+                            String mu = hel.getAttributeNS(soapVersion.getNamespace(),
+                                                           soapVersion.getAttrNameMustUnderstand());
+                            String act = hel.getAttributeNS(soapVersion.getNamespace(),
+                                                            soapVersion.getAttrNameRole());
+
+                            if (!StringUtils.isEmpty(act)) {
+                                shead.setActor(act);
+                            }
+                            shead.setMustUnderstand(Boolean.valueOf(mu) || "1".equals(mu));
+                            // mark header as inbound header.(for distinguishing between
the direction to
+                            // avoid piggybacking of headers from request->server->response.
+                            shead.setDirection(SoapHeader.Direction.DIRECTION_IN);
+                            message.getHeaders().add(shead);
 
-                        if (!StringUtils.isEmpty(act)) {
-                            shead.setActor(act);
+                            hel = DOMUtils.getNextElement(hel);
                         }
-                        shead.setMustUnderstand(Boolean.valueOf(mu) || "1".equals(mu));
-                        //mark header as inbound header.(for distinguishing between the 
direction to 
-                        //avoid piggybacking of headers from request->server->response.
-                        shead.setDirection(SoapHeader.Direction.DIRECTION_IN);
-                        message.getHeaders().add(shead);
-                        
-                        hel = DOMUtils.getNextElement(hel);
                     }
                 }
 
@@ -269,4 +269,106 @@ public class ReadHeadersInterceptor extends AbstractSoapInterceptor
{
             }
         }
     }
+
+    /**
+     * A convenient class for parsing the message header stream into a DOM document;
+     * the document is created only if a SOAP Header is actually found, keeping the
+     * memory usage as low as possible (there's no reason for building the DOM doc
+     * here if there's actually no header in the message, but we need to figure that
+     * out while parsing the stream).
+     */
+    private static class HeadersProcessor {
+        private static final XMLEventFactory FACTORY = XMLEventFactory.newFactory();
+        private final QName soapVersionHeader;
+        private final List<XMLEvent> events = new ArrayList<XMLEvent>(8);
+        private StreamToDOMContext context;
+        private Document doc;
+        private Node parent;
+
+        public HeadersProcessor(SoapVersion version) {
+            this.soapVersionHeader = version.getHeader();
+        }
+
+        public Document process(XMLStreamReader reader) throws XMLStreamException {
+            // number of elements read in
+            int read = 0;
+            int event = reader.getEventType();
+            while (reader.hasNext()) {
+                switch (event) {
+                case XMLStreamConstants.START_ELEMENT:
+                    read++;
+                    addEvent(FACTORY.createStartElement(new QName(reader.getNamespaceURI(),
reader
+                                                            .getLocalName(), reader.getPrefix()),
null, null));
+                    for (int i = 0; i < reader.getNamespaceCount(); i++) {
+                        addEvent(FACTORY.createNamespace(reader.getNamespacePrefix(i),
+                                                         reader.getNamespaceURI(i)));
+                    }
+                    for (int i = 0; i < reader.getAttributeCount(); i++) {
+                        addEvent(FACTORY.createAttribute(reader.getAttributePrefix(i),
+                                                         reader.getAttributeNamespace(i),
+                                                         reader.getAttributeLocalName(i),
+                                                         reader.getAttributeValue(i)));
+                    }
+                    if (doc != null) {
+                        //go on parsing the stream directly till the end and stop generating
events
+                        StaxUtils.readDocElements(doc, parent, reader, context);
+                    }
+                    break;
+                case XMLStreamConstants.END_ELEMENT:
+                    if (read > 0) {
+                        addEvent(FACTORY.createEndElement(new QName(reader.getNamespaceURI(),
reader
+                                                              .getLocalName(), reader.getPrefix()),
null));
+                    }
+                    read--;
+                    break;
+                case XMLStreamConstants.CHARACTERS:
+                    String s = reader.getText();
+                    if (s != null) {
+                        addEvent(FACTORY.createCharacters(s));
+                    }
+                    break;
+                case XMLStreamConstants.COMMENT:
+                    addEvent(FACTORY.createComment(reader.getText()));
+                    break;
+                case XMLStreamConstants.CDATA:
+                    addEvent(FACTORY.createCData(reader.getText()));
+                    break;
+                case XMLStreamConstants.START_DOCUMENT:
+                case XMLStreamConstants.END_DOCUMENT:
+                case XMLStreamConstants.ATTRIBUTE:
+                case XMLStreamConstants.NAMESPACE:
+                    break;
+                default:
+                    break;
+                }
+                event = reader.next();
+            }
+
+            return doc;
+        }
+
+        private void addEvent(XMLEvent event) {
+            if (event.isStartElement()) {
+                QName qName = event.asStartElement().getName();
+                if (soapVersionHeader.getLocalPart().equals(qName.getLocalPart())
+                    && soapVersionHeader.getNamespaceURI().equals(qName.getNamespaceURI()))
{
+                    // process all events recorded so far
+                    context = new StreamToDOMContext(true, false, false);
+                    doc = DOMUtils.createDocument();
+                    parent = doc;
+                    try {
+                        for (XMLEvent ev : events) {
+                            parent = StaxUtils.readDocElement(doc, parent, ev, context);
+                        }
+                    } catch (XMLStreamException e) {
+                        throw new Fault(e);
+                    }
+                } else {
+                    events.add(event);
+                }
+            } else {
+                events.add(event);
+            }
+        }
+    }
 }


Mime
View raw message