You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2012/07/07 13:43:43 UTC

svn commit: r1358547 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/om/impl/builder/ axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/ axiom-testsuite/src/main/java/org/apache/axiom/ts/om/...

Author: veithen
Date: Sat Jul  7 11:43:43 2012
New Revision: 1358547

URL: http://svn.apache.org/viewvc?rev=1358547&view=rev
Log:
* Consuming the reader returned by getXMLStreamReaderWithoutCaching should not built SOAPHeaderBlocks if they are not backed by OMDataSources. Modified OMNavigator to handle this case.
* Fixed the StAXBuilder#discard(OMElement) method. It didn't ajust the elementLevel correctly. Note that this issue only manifested itself after the previous issue was fixed.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/envelope/TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock.java   (with props)
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
    webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMNavigator.java
    webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java
    webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java?rev=1358547&r1=1358546&r2=1358547&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java Sat Jul  7 11:43:43 2012
@@ -41,7 +41,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 
@@ -314,27 +313,30 @@ public abstract class StAXBuilder implem
         }
         try {
 
-            // We simply cannot use the parser instance from the builder for this case
-            // it is not safe to assume that the parser inside the builder will be in
-            // sync with the parser of the element in question
-            // Note 1 - however  calling getXMLStreamReaderWithoutCaching sets off two flags
-            // the cache flag for this builder and the parserAccessed flag. These flags will be
-            // reset later in this procedure
-
-            int event =0;
-            XMLStreamReader elementParser = element.getXMLStreamReaderWithoutCaching();
-            do{
-               event = elementParser.next();
-            }while(!(event == XMLStreamConstants.END_ELEMENT &&
-                     element.getLocalName().equals(elementParser.getLocalName())));
+            // Calculate the depth of the element to be discarded. This determines how many
+            // END_ELEMENT events we need to consume.
+            int targetDepth = elementLevel;
+            if (!lastNode.isComplete()) {
+                targetDepth--;
+            }
+            OMNode current = lastNode;
+            while (current != element) {
+                OMContainer parent = current.getParent();
+                if (parent instanceof OMElement) {
+                    current = (OMElement)parent;
+                } else {
+                    throw new OMException("Called discard for an element that is not being built by this builder");
+                }
+                targetDepth--;
+            }
+            
+            while (elementLevel > targetDepth) {
+                parserNext();
+            }
 
             //at this point we are safely at the end_element event of the element we discarded
             lastNode = element.getPreviousOMSibling();
 
-            // resetting the flags - see Note 1 above
-            cache = true;
-            parserAccessed = false;
-            
             if (lastNode != null) {
                 // if the last node is not an element, we are in trouble because leaf nodes
                 // (such as text) cannot build themselves. worst the lastchild of the
@@ -361,9 +363,6 @@ public abstract class StAXBuilder implem
         } catch (Exception e) {
             throw new OMException(e);
         } 
-        // when an element is discarded the element index that was incremented
-        //at creation needs to be decremented !
-        elementLevel--;
     }
 
     /**
@@ -563,6 +562,8 @@ public abstract class StAXBuilder implem
      */
     protected abstract OMNode createOMElement() throws OMException;
 
+    abstract int parserNext() throws XMLStreamException;
+    
     /**
      * Forwards the parser one step further, if parser is not completed yet. If this is called after
      * parser is done, then throw an OMException. If the cache is set to false, then returns the

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java?rev=1358547&r1=1358546&r2=1358547&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java Sat Jul  7 11:43:43 2012
@@ -245,7 +245,6 @@ public class StAXOMBuilder extends StAXB
                
                 switch (token) {
                     case XMLStreamConstants.START_ELEMENT:
-                        elementLevel++;
                         lastNode = createNextOMElement();
                         break;
                     case XMLStreamConstants.CHARACTERS:
@@ -256,7 +255,6 @@ public class StAXOMBuilder extends StAXB
                         break;
                     case XMLStreamConstants.END_ELEMENT:
                         endElement();
-                        elementLevel--;
                         break;
                     case XMLStreamConstants.END_DOCUMENT:
                         done = true;
@@ -662,7 +660,7 @@ public class StAXOMBuilder extends StAXB
      * @return next token
      * @throws XMLStreamException
      */
-    private int parserNext() throws XMLStreamException {
+    int parserNext() throws XMLStreamException {
         if (lookAheadToken >= 0) {
             int token = lookAheadToken;
             lookAheadToken = -1; // Reset
@@ -677,12 +675,27 @@ public class StAXOMBuilder extends StAXB
                     throw (RuntimeException)parserException;
                 }
             }
+            int event;
             try {
-                return parser.next();
+                event = parser.next();
             } catch (XMLStreamException ex) {
                 parserException = ex;
                 throw ex;
             }
+            switch (event) {
+                case XMLStreamConstants.START_ELEMENT:
+                    elementLevel++;
+                    break;
+                case XMLStreamConstants.END_ELEMENT:
+                    elementLevel--;
+                    break;
+                case XMLStreamConstants.END_DOCUMENT:
+                    if (elementLevel != 0) {
+                        throw new OMException("Unexpected END_DOCUMENT event");
+                    }
+                    break;
+            }
+            return event;
         }
     }
     

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMNavigator.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMNavigator.java?rev=1358547&r1=1358546&r2=1358547&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMNavigator.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMNavigator.java Sat Jul  7 11:43:43 2012
@@ -172,29 +172,31 @@ public class OMNavigator {
      */
     private boolean isLeaf(OMSerializable n) {
         if (n instanceof OMContainer) {
-            if (this.isDataSourceALeaf && (n instanceof OMSourcedElement) && n != root) {
-                OMDataSource ds = null;
-                try {
-                    ds = ((OMSourcedElement) n).getDataSource();
-                } catch (UnsupportedOperationException e) {
-                    ; // Operation unsupported for some implementations
-                }
-                if (ds != null) {
-                    return true;
-                }
-            }
-            return false;
+            return this.isDataSourceALeaf && isOMSourcedElement(n) && n != root;
         } else {
             return true;
         }
     }
 
+    private boolean isOMSourcedElement(OMSerializable node) {
+        if (node instanceof OMSourcedElement) {
+            try {
+                return ((OMSourcedElement)node).getDataSource() != null;
+            } catch (UnsupportedOperationException e) {
+                // Operation unsupported for some implementations
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+    
     /**
      * @param node
      * @return first child or null
      */
     private OMNode _getFirstChild(OMContainer node) {
-        if (node instanceof OMSourcedElement) {
+        if (isOMSourcedElement(node)) {
             OMNode first = node.getFirstOMChild();
             OMNode sibling = first;
             while (sibling != null) {
@@ -211,7 +213,7 @@ public class OMNavigator {
      * @return next sibling or null
      */
     private OMNode getNextSibling(OMNode node) {
-        if (node instanceof OMSourcedElement) {
+        if (isOMSourcedElement(node)) {
             return node.getNextOMSibling();
         } else {
             return ((OMNodeEx) node).getNextOMSiblingIfAvailable();

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java?rev=1358547&r1=1358546&r2=1358547&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java Sat Jul  7 11:43:43 2012
@@ -42,7 +42,7 @@ public class TestDiscardPartiallyBuilt e
     protected void runTest() throws Throwable {
         OMFactory factory = metaFactory.getOMFactory();
         OMElement root = OMXMLBuilderFactory.createOMBuilder(factory, new StringReader(
-                "<root><element><a><b>text</b></a><c/></element><sibling/></root>")).getDocumentElement();;
+                "<root><element><a><b>text</b></a><c/></element><sibling/></root>")).getDocumentElement();
         OMElement element = root.getFirstElement();
         
         // Navigate to the text node so that the element is partially built
@@ -52,5 +52,9 @@ public class TestDiscardPartiallyBuilt e
         
         element.discard();
         XMLAssert.assertXMLEqual("<root><sibling/></root>", root.toString());
+        
+        // Force the builder to complete the document. If the discard method didn't adjust the
+        // element depth correctly, then an exception will occur here
+        assertNull(root.getNextOMSibling());
     }
 }

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java?rev=1358547&r1=1358546&r2=1358547&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java Sat Jul  7 11:43:43 2012
@@ -120,6 +120,7 @@ public class SOAPTestSuiteBuilder extend
             addTest(new org.apache.axiom.ts.soap.envelope.TestGetSOAPBodyFirstElementLocalNameAndNS(metaFactory, spec, qname));
             addTest(new org.apache.axiom.ts.soap.envelope.TestGetSOAPBodyFirstElementLocalNameAndNSWithParser(metaFactory, spec, qname));
         }
+        addTest(new org.apache.axiom.ts.soap.envelope.TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock(metaFactory, spec));
         addTest(new org.apache.axiom.ts.soap.envelope.TestHasFault(metaFactory, spec));
         addTest(new org.apache.axiom.ts.soap.envelope.TestHasFaultWithParser(metaFactory, spec));
         addTest(new org.apache.axiom.ts.soap.envelope.TestHasFaultWithParserOptimized(metaFactory, spec));

Added: webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/envelope/TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/envelope/TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock.java?rev=1358547&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/envelope/TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/envelope/TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock.java Sat Jul  7 11:43:43 2012
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.soap.envelope;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.om.OMSourcedElement;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPHeaderBlock;
+import org.apache.axiom.ts.soap.SOAPSpec;
+import org.apache.axiom.ts.soap.SOAPTestCase;
+
+/**
+ * Tests the behavior of {@link OMContainer#getXMLStreamReaderWithoutCaching()} on a
+ * {@link SOAPEnvelope} with a partially built {@link SOAPHeaderBlock}. A {@link SOAPHeaderBlock} is
+ * an {@link OMSourcedElement}, but if it is not linked to a {@link OMDataSource} then it should
+ * behave like a plain {@link OMElement}. For {@link OMContainer#getXMLStreamReaderWithoutCaching()}
+ * this means that consuming the reader should not build the {@link SOAPHeaderBlock}.
+ */
+public class TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock extends SOAPTestCase {
+    public TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock(OMMetaFactory metaFactory, SOAPSpec spec) {
+        super(metaFactory, spec);
+    }
+
+    protected void runTest() throws Throwable {
+        SOAPEnvelope envelope = getTestMessage(SOAP_MESSAGE);
+        SOAPHeaderBlock headerBlock = (SOAPHeaderBlock)envelope.getHeader().getFirstChildWithName(
+                new QName("http://schemas.xmlsoap.org/ws/2004/03/addressing", "From"));
+        headerBlock.getFirstElement().getFirstOMChild();
+        assertFalse(headerBlock.isComplete());
+        XMLStreamReader reader = envelope.getXMLStreamReaderWithoutCaching();
+        while (reader.hasNext()) {
+            reader.next();
+        }
+        assertFalse(headerBlock.isComplete());
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/envelope/TestGetXMLStreamReaderWithoutCachingWithPartiallyBuiltHeaderBlock.java
------------------------------------------------------------------------------
    svn:eol-style = native