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 2013/01/14 21:48:47 UTC

svn commit: r1433119 - /webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java

Author: veithen
Date: Mon Jan 14 20:48:47 2013
New Revision: 1433119

URL: http://svn.apache.org/viewvc?rev=1433119&view=rev
Log:
Completely eliminated lookahead. SwitchingWrapper now simply points to the current node (corresponding to the current event) and the next node is only calculated when XMLStreamReader#next() is called (and no longer in advance). The algorithm is now as simple as one would expect: we traverse the tree in document order and if caching is disabled and we get past the last node created by the builder we switch to pull through mode.

Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.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/SwitchingWrapper.java?rev=1433119&r1=1433118&r2=1433119&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java Mon Jan 14 20:48:47 2013
@@ -69,8 +69,10 @@ class SwitchingWrapper extends AbstractX
     
     private static final Log log = LogFactory.getLog(SwitchingWrapper.class);
     
-    /** Field node */
-    private OMSerializable _node;
+    /**
+     * The current node, corresponding to the current event.
+     */
+    private OMSerializable node;
 
     /**
      * If the current node is an {@link OMContainer}, then this flag indicates whether the current
@@ -82,14 +84,6 @@ class SwitchingWrapper extends AbstractX
      */
     private boolean visited;
 
-    /** Field next */
-    private OMSerializable _next;
-
-    /** Field backtracked */
-    private boolean _backtracked;
-
-    // flags that tell the status of the navigator
-
     /**
      * Indicates if an OMSourcedElement with an OMDataSource should
      * be considered as an interior node or a leaf node.
@@ -157,9 +151,6 @@ class SwitchingWrapper extends AbstractX
      */
     private final boolean preserveNamespaceContext;
     
-    /** Field lastNode */
-    private OMSerializable lastNode = null;
-
     /** Track depth to ensure we stop generating events when we are done with the root node. */
     int depth = 0;
 
@@ -183,19 +174,16 @@ class SwitchingWrapper extends AbstractX
     public SwitchingWrapper(OMXMLParserWrapper builder, OMContainer startNode,
                             boolean cache, boolean preserveNamespaceContext) {
 
-        _next = startNode;
-        _backtracked = false;
         this.builder = builder;
         this.rootNode = startNode;
         this.cache = cache;
         this.preserveNamespaceContext = preserveNamespaceContext;
 
+        // If the start node is a document it become the current node. If the start node
+        // is an element, then there is no current node, because there is no node
+        // corresponding to the current event (START_DOCUMENT).
         if (startNode instanceof OMDocument) {
-            // Bootstrap the navigator: is written in such a way that it first
-            // returns the starting node at the first call to it.
-            // If the start node is an OMElement, then this will occur that the
-            // first call to next().
-            lastNode = getNext();
+            node = startNode;
         }
         currentEvent = START_DOCUMENT;
     }
@@ -210,7 +198,7 @@ class SwitchingWrapper extends AbstractX
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                return ((OMElement)lastNode).getPrefix();
+                return ((OMElement)node).getPrefix();
             } else {
                 throw new IllegalStateException();
             }
@@ -227,7 +215,7 @@ class SwitchingWrapper extends AbstractX
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                return ((OMElement)lastNode).getNamespaceURI();
+                return ((OMElement)node).getNamespaceURI();
             } else {
                 throw new IllegalStateException();
             }
@@ -258,9 +246,9 @@ class SwitchingWrapper extends AbstractX
             switch (currentEvent) {
                 case START_ELEMENT:
                 case END_ELEMENT:
-                    return ((OMElement)lastNode).getLocalName();
+                    return ((OMElement)node).getLocalName();
                 case ENTITY_REFERENCE:
-                    return ((OMEntityReference)lastNode).getName();
+                    return ((OMEntityReference)node).getName();
                 default:
                     throw new IllegalStateException();
             }
@@ -277,7 +265,7 @@ class SwitchingWrapper extends AbstractX
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                return ((OMElement)lastNode).getQName();
+                return ((OMElement)node).getQName();
             } else {
                 throw new IllegalStateException();
             }
@@ -362,11 +350,11 @@ class SwitchingWrapper extends AbstractX
             // and the other ones in getTextFromNode().
             switch (currentEvent) {
                 case DTD:
-                    String internalSubset = ((OMDocType)lastNode).getInternalSubset();
+                    String internalSubset = ((OMDocType)node).getInternalSubset();
                     // Woodstox returns the empty string if there is no internal subset
                     return internalSubset != null ? internalSubset : "";
                 case ENTITY_REFERENCE:
-                    return ((OMEntityReference)lastNode).getReplacementText();
+                    return ((OMEntityReference)node).getReplacementText();
                 default:
                     return getTextFromNode();
             }
@@ -385,9 +373,9 @@ class SwitchingWrapper extends AbstractX
             case CHARACTERS:
             case CDATA:
             case SPACE:
-                return ((OMText)lastNode).getText();
+                return ((OMText)node).getText();
             case COMMENT:
-                return ((OMComment)lastNode).getValue();
+                return ((OMComment)node).getValue();
             default:
                 throw new IllegalStateException();
         }
@@ -401,7 +389,7 @@ class SwitchingWrapper extends AbstractX
                 case CHARACTERS:
                 case CDATA:
                 case SPACE:
-                    OMText text = (OMText)lastNode;
+                    OMText text = (OMText)node;
                     if (text.isCharacters()) {
                         writer.write(text.getTextCharacters());
                     } else {
@@ -410,7 +398,7 @@ class SwitchingWrapper extends AbstractX
                     }
                     break;
                 case COMMENT:
-                    writer.write(((OMComment)lastNode).getValue());
+                    writer.write(((OMComment)node).getValue());
                     break;
                 default:
                     throw new IllegalStateException();
@@ -431,7 +419,7 @@ class SwitchingWrapper extends AbstractX
     private void loadAttributes() {
         if (attributeCount == -1) {
             attributeCount = 0;
-            for (Iterator it = ((OMElement)lastNode).getAllAttributes(); it.hasNext(); ) {
+            for (Iterator it = ((OMElement)node).getAllAttributes(); it.hasNext(); ) {
                 OMAttribute attr = (OMAttribute)it.next();
                 if (attributeCount == attributes.length) {
                     OMAttribute[] newAttributes = new OMAttribute[attributes.length*2];
@@ -452,11 +440,11 @@ class SwitchingWrapper extends AbstractX
     private void loadNamespaces() {
         if (namespaceCount == -1) {
             namespaceCount = 0;
-            for (Iterator it = ((OMElement)lastNode).getAllDeclaredNamespaces(); it.hasNext(); ) {
+            for (Iterator it = ((OMElement)node).getAllDeclaredNamespaces(); it.hasNext(); ) {
                 addNamespace((OMNamespace)it.next());
             }
-            if (preserveNamespaceContext && lastNode == rootNode) {
-                OMElement element = (OMElement)lastNode;
+            if (preserveNamespaceContext && node == rootNode) {
+                OMElement element = (OMElement)node;
                 while (true) {
                     OMContainer container = element.getParent();
                     if (container instanceof OMElement) {
@@ -730,7 +718,7 @@ class SwitchingWrapper extends AbstractX
         } else {
             if (isStartElement()) {
                 QName qname = new QName(s, s1);
-                OMAttribute attrib = ((OMElement) lastNode).getAttribute(qname);
+                OMAttribute attrib = ((OMElement) node).getAttribute(qname);
                 if (attrib != null) {
                     returnString = attrib.getAttributeValue();
                 }
@@ -813,9 +801,9 @@ class SwitchingWrapper extends AbstractX
         } else {
             if (isStartElement() || isEndElement()) {
 
-                if (lastNode instanceof OMElement) {
+                if (node instanceof OMElement) {
                     OMNamespace namespaceURI =
-                            ((OMElement) lastNode).findNamespaceURI(prefix);
+                            ((OMElement) node).findNamespaceURI(prefix);
                     return namespaceURI != null ? namespaceURI.getNamespaceURI() : null;
                 }
             }
@@ -877,47 +865,36 @@ class SwitchingWrapper extends AbstractX
         }
     }
 
-    /**
-     * Get the next information item.
-     * 
-     * @return the next information item in the sequence of preorder traversal. Note however that a
-     *         container (document or element) is treated slightly differently. Once the container
-     *         is passed it returns the same item in the next encounter as well.
-     */
-    private OMSerializable getNext() {
-        _node = _next;
-        visited = _backtracked;
-        _backtracked = false;
-        updateNextNode();
-        return _node;
-    }
-    
     /** Private method to encapsulate the searching logic. */
-    private void updateNextNode() {
-        if (!isLeaf(_node) && !visited) {
-            OMNode firstChild = _getFirstChild((OMContainer) _node);
+    private void nextNode() {
+        if (node == null) {
+            // We get here if rootNode is an element and the current event is START_DOCUMENT
+            node = rootNode;
+        } else if (!isLeaf(node) && !visited) {
+            OMNode firstChild = _getFirstChild((OMContainer) node);
             if (firstChild != null) {
-                _next = firstChild;
-            } else if (_node.isComplete()) {
-                _next = _node;
-                _backtracked = true;
+                node = firstChild;
+                visited = false;
+            } else if (node.isComplete()) {
+                visited = true;
             } else {
-                _next = null;
+                node = null;
             }
         } else {
-            if (_node instanceof OMDocument) {
-                _next = null;
+            if (node instanceof OMDocument) {
+                node = null;
             } else {
-                OMNode nextNode = (OMNode)_node;
+                OMNode nextNode = (OMNode)node;
                 OMContainer parent = nextNode.getParent();
                 OMNode nextSibling = getNextSibling(nextNode);
                 if (nextSibling != null) {
-                    _next = nextSibling;
+                    node = nextSibling;
+                    visited = false;
                 } else if ((parent != null) && parent.isComplete()) {
-                    _next = parent;
-                    _backtracked = true;
+                    node = parent;
+                    visited = true;
                 } else {
-                    _next = null;
+                    node = null;
                 }
             }
         }
@@ -981,15 +958,6 @@ class SwitchingWrapper extends AbstractX
     }
 
     /**
-     * Returns the navigable status.
-     *
-     * @return Returns boolean.
-     */
-    private boolean isNavigable() {
-        return _next != null;
-    }
-
-    /**
      * Method next.
      *
      * @return Returns int.
@@ -1004,9 +972,9 @@ class SwitchingWrapper extends AbstractX
                 currentEvent = END_DOCUMENT;
                 break;
             case NAVIGABLE:
-                if (isNavigable()) {
-                    lastNode = getNext();
-                    currentEvent = generateEvents(lastNode);
+                nextNode();
+                if (node != null) {
+                    currentEvent = generateEvents(node);
                     attributeCount = -1;
                     namespaceCount = -1;
                 } else {
@@ -1081,7 +1049,7 @@ class SwitchingWrapper extends AbstractX
             depth--;
         }
         if (state == NAVIGABLE) {
-            if (rootNode == lastNode && visited) {
+            if (rootNode == node && visited) {
                 if (currentEvent == END_DOCUMENT) {
                     state = DOCUMENT_COMPLETE;
                 } else {
@@ -1111,7 +1079,7 @@ class SwitchingWrapper extends AbstractX
             return currentEvent == END_DOCUMENT ? new MapBasedNamespaceContext(Collections.EMPTY_MAP) : parser.getNamespaceContext();
         } else {
             return new MapBasedNamespaceContext(
-                    currentEvent == END_DOCUMENT ? Collections.EMPTY_MAP : getAllNamespaces(lastNode));
+                    currentEvent == END_DOCUMENT ? Collections.EMPTY_MAP : getAllNamespaces(node));
         }
     }
 
@@ -1125,8 +1093,8 @@ class SwitchingWrapper extends AbstractX
             return parser.getEncoding();
         } else {
             if (currentEvent == START_DOCUMENT) {
-                if (lastNode instanceof OMDocument) {
-                    return ((OMDocument)lastNode).getCharsetEncoding();
+                if (node instanceof OMDocument) {
+                    return ((OMDocument)node).getCharsetEncoding();
                 } else {
                     return null;
                 }
@@ -1173,8 +1141,8 @@ class SwitchingWrapper extends AbstractX
             return parser.getCharacterEncodingScheme();
         } else {
             if (currentEvent == START_DOCUMENT) {
-                if (lastNode instanceof OMDocument) {
-                    return ((OMDocument)lastNode).getXMLEncoding();
+                if (node instanceof OMDocument) {
+                    return ((OMDocument)node).getXMLEncoding();
                 } else {
                     return null;
                 }
@@ -1194,7 +1162,7 @@ class SwitchingWrapper extends AbstractX
             return parser.getPITarget();
         } else {
             if (currentEvent == PROCESSING_INSTRUCTION) {
-                return ((OMProcessingInstruction)lastNode).getTarget();
+                return ((OMProcessingInstruction)node).getTarget();
             } else {
                 throw new IllegalStateException();
             }
@@ -1211,7 +1179,7 @@ class SwitchingWrapper extends AbstractX
             return parser.getPIData();
         } else {
             if (currentEvent == PROCESSING_INSTRUCTION) {
-                return ((OMProcessingInstruction)lastNode).getValue();
+                return ((OMProcessingInstruction)node).getValue();
             } else {
                 throw new IllegalStateException();
             }
@@ -1234,8 +1202,8 @@ class SwitchingWrapper extends AbstractX
                 return false;
             }
         } else {
-            if (lastNode instanceof OMText) {
-                return ((OMText)lastNode).isBinary();
+            if (node instanceof OMText) {
+                return ((OMText)node).isBinary();
             } else {
                 return false;
             }
@@ -1250,8 +1218,8 @@ class SwitchingWrapper extends AbstractX
                 throw new IllegalStateException();
             }
         } else {
-            if (lastNode instanceof OMText) {
-                return ((OMText)lastNode).isOptimized();
+            if (node instanceof OMText) {
+                return ((OMText)node).isOptimized();
             } else {
                 throw new IllegalStateException();
             }
@@ -1266,7 +1234,7 @@ class SwitchingWrapper extends AbstractX
                 throw new IllegalStateException();
             }
         } else {
-            if (lastNode instanceof OMText) {
+            if (node instanceof OMText) {
                 // TODO: we should support deferred building of the DataHandler
                 return false;
             } else {
@@ -1283,8 +1251,8 @@ class SwitchingWrapper extends AbstractX
                 throw new IllegalStateException();
             }
         } else {
-            if (lastNode instanceof OMText) {
-                return ((OMText)lastNode).getContentID();
+            if (node instanceof OMText) {
+                return ((OMText)node).getContentID();
             } else {
                 throw new IllegalStateException();
             }
@@ -1299,8 +1267,8 @@ class SwitchingWrapper extends AbstractX
                 throw new IllegalStateException();
             }
         } else {
-            if (lastNode instanceof OMText) {
-                return (DataHandler)((OMText)lastNode).getDataHandler();
+            if (node instanceof OMText) {
+                return (DataHandler)((OMText)node).getDataHandler();
             } else {
                 throw new IllegalStateException();
             }
@@ -1440,10 +1408,10 @@ class SwitchingWrapper extends AbstractX
             return null;
         }
         OMDataSource ds = null;
-        if (lastNode != null &&
-            lastNode instanceof OMSourcedElement) {
+        if (node != null &&
+            node instanceof OMSourcedElement) {
             try {
-                ds = ((OMSourcedElement) lastNode).getDataSource();
+                ds = ((OMSourcedElement) node).getDataSource();
             } catch (UnsupportedOperationException e) {
                 // Some implementations throw an UnsupportedOperationException.
                 ds =null;