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/08 21:42:26 UTC

svn commit: r1358823 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/om/impl/builder/ axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/ axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ axio...

Author: veithen
Date: Sun Jul  8 19:42:26 2012
New Revision: 1358823

URL: http://svn.apache.org/viewvc?rev=1358823&view=rev
Log:
Simplified the builder code. The builder doesn't need to keep track of the last node created, but only of the container (document or element) that is being built. Using the latter approach has several advantages:
* It greatly simplifies the builder code.
* The builder can handle documents and elements in a uniform way.
* A node can be safely detached without the next sibling being created.

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-api/src/main/java/org/apache/axiom/soap/impl/builder/StAXSOAPModelBuilder.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NodeImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.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=1358823&r1=1358822&r2=1358823&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 Sun Jul  8 19:42:26 2012
@@ -33,8 +33,6 @@ import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.OMContainerEx;
-import org.apache.axiom.om.impl.OMElementEx;
-import org.apache.axiom.om.impl.OMNodeEx;
 import org.apache.axiom.om.impl.util.OMSerializerUtil;
 import org.apache.axiom.om.util.StAXUtils;
 import org.apache.axiom.util.stax.XMLStreamReaderUtils;
@@ -65,7 +63,7 @@ public abstract class StAXBuilder implem
     protected OMFactoryEx omfactory;
 
     /** Field lastNode */
-    protected OMNode lastNode;
+    protected OMContainerEx target;
 
     // returns the state of completion
 
@@ -234,32 +232,13 @@ public abstract class StAXBuilder implem
     }
 
     /**
-     * Method createOMText.
-     *
-     * @return Returns OMNode.
-     * @throws OMException
-     */
-    protected OMNode createOMText(int textType) throws OMException {
-        OMNode node;
-        if (lastNode == null) {
-            return null;
-        } else if (!lastNode.isComplete()) {
-            node = createOMText((OMElement) lastNode, textType);
-        } else {
-            node = createOMText(lastNode.getParent(), textType);
-        }
-        return node;
-    }
-
-    /**
      * This method will check whether the text can be optimizable using IS_BINARY flag. If that is
      * set then we try to get the data handler.
      *
-     * @param omContainer
      * @param textType
      * @return omNode
      */
-    private OMNode createOMText(OMContainer omContainer, int textType) {
+    protected OMNode createOMText(int textType) {
         if (dataHandlerReader != null && dataHandlerReader.isBinary()) {
             Object dataHandlerObject;
             if (dataHandlerReader.isDeferred()) {
@@ -271,7 +250,7 @@ public abstract class StAXBuilder implem
                     throw new OMException(ex);
                 }
             }
-            OMText text = omfactory.createOMText(omContainer, dataHandlerObject, dataHandlerReader.isOptimized(), true);
+            OMText text = omfactory.createOMText(target, dataHandlerObject, dataHandlerReader.isOptimized(), true);
             String contentID = dataHandlerReader.getContentID();
             if (contentID != null) {
                 text.setContentID(contentID);
@@ -287,21 +266,11 @@ public abstract class StAXBuilder implem
                 parserException = ex;
                 throw ex;
             }
-            return omfactory.createOMText(omContainer, text, textType, true);
+            return omfactory.createOMText(target, text, textType, true);
         }
     }
 
     /**
-     * Method reset.
-     *
-     * @param node
-     * @throws OMException
-     */
-    public void reset(OMNode node) throws OMException {
-        lastNode = null;
-    }
-
-    /**
      * Method discard.
      *
      * @param element
@@ -316,19 +285,15 @@ public abstract class StAXBuilder implem
 
             // 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;
+            int targetDepth = elementLevel-1;
+            OMContainerEx current = target;
             while (current != element) {
-                OMContainer parent = current.getParent();
-                if (parent instanceof OMElement) {
-                    current = (OMElement)parent;
+                if (current instanceof OMElement) {
+                    targetDepth--;
+                    current = (OMContainerEx)((OMElement)current).getParent();
                 } else {
                     throw new OMException("Called discard for an element that is not being built by this builder");
                 }
-                targetDepth--;
             }
             
             while (elementLevel > targetDepth) {
@@ -336,45 +301,17 @@ public abstract class StAXBuilder implem
             }
 
             // Mark nodes as discarded
-            current = lastNode;
+            current = target;
             while (true) {
-                if (!current.isComplete()) {
-                    ((OMContainerEx)current).discarded();
-                }
+                current.discarded();
                 if (current == element) {
                     break;
                 }
-                current = (OMElement)current.getParent();
-            }
-            
-            //at this point we are safely at the end_element event of the element we discarded
-            lastNode = element.getPreviousOMSibling();
-
-            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
-                // currentparent is still the removed node! we have to correct it
-                OMContainerEx ex = ((OMContainerEx) lastNode.getParent());
-                ex.setLastChild(lastNode);
-                 if (!(lastNode instanceof OMContainerEx)){
-                     ex.buildNext();
-                 }else{
-                    ((OMNodeEx) lastNode).setNextOMSibling(null); 
-                 }
-
-            } else {
-                OMContainer parent = element.getParent();
-                if (parent == null) {
-                    throw new OMException();
-                } else {
-                    ((OMContainerEx) parent).setFirstChild(null);
-                    lastNode = parent instanceof OMDocument ? null : (OMNode)parent;
-                }
+                current = (OMContainerEx)((OMElement)current).getParent();
             }
             
-            ((OMElementEx)element).setParent(null);
-            ((OMElementEx)element).setPreviousOMSibling(null);
-            ((OMElementEx)element).setNextOMSibling(null);
+            target = (OMContainerEx)element.getParent();
+            element.detach();
         } catch (XMLStreamException e) {
             throw new OMException(e);
         } 
@@ -671,10 +608,6 @@ public abstract class StAXBuilder implem
         return document.getCharsetEncoding();
     }
 
-    public OMNode getLastNode() {
-        return this.lastNode;
-    }
-
     public void close() {
         try {
             if (!isClosed()) {

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=1358823&r1=1358822&r2=1358823&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 Sun Jul  8 19:42:26 2012
@@ -20,14 +20,12 @@
 package org.apache.axiom.om.impl.builder;
 
 import org.apache.axiom.om.OMAbstractFactory;
-import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDocument;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMHierarchyException;
 import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.impl.OMContainerEx;
 import org.apache.axiom.om.impl.OMElementEx;
 import org.apache.axiom.om.impl.OMNodeEx;
@@ -45,7 +43,6 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
 
-
 /**
  * StAX based builder that produces a pure XML infoset compliant object model.
  * <p>
@@ -103,6 +100,7 @@ public class StAXOMBuilder extends StAXB
     public StAXOMBuilder(OMFactory ombuilderFactory, XMLStreamReader parser) {
         super(ombuilderFactory, parser);
         document = createDocument();
+        target = (OMContainerEx)document;
     }
 
     /**
@@ -123,7 +121,7 @@ public class StAXOMBuilder extends StAXB
         namespaceURIInterning = false;
         lookAheadToken = -1;
         document = createDocument();
-        lastNode = element;
+        target = (OMContainerEx)element;
         populateOMElement(element);
     }
     
@@ -159,6 +157,7 @@ public class StAXOMBuilder extends StAXB
         lookAheadToken = -1;
         omfactory = (OMFactoryEx)OMAbstractFactory.getOMFactory();
         document = createDocument();
+        target = (OMContainerEx)document;
     }
 
     /**
@@ -244,14 +243,20 @@ public class StAXOMBuilder extends StAXB
                 }
                
                 switch (token) {
-                    case XMLStreamConstants.START_ELEMENT:
-                        lastNode = createNextOMElement();
+                    case XMLStreamConstants.START_ELEMENT: {
+                        OMNode node = createNextOMElement();
+                        // If the node was created by a custom builder, then it will be complete;
+                        // in this case, the target doesn't change
+                        if (!node.isComplete()) {
+                            target = (OMContainerEx)node;
+                        }
                         break;
+                    }
                     case XMLStreamConstants.CHARACTERS:
-                        lastNode = createOMText(XMLStreamConstants.CHARACTERS);
+                        createOMText(XMLStreamConstants.CHARACTERS);
                         break;
                     case XMLStreamConstants.CDATA:
-                        lastNode = createOMText(XMLStreamConstants.CDATA);
+                        createOMText(XMLStreamConstants.CDATA);
                         break;
                     case XMLStreamConstants.END_ELEMENT:
                         endElement();
@@ -262,8 +267,8 @@ public class StAXOMBuilder extends StAXB
                         break;
                     case XMLStreamConstants.SPACE:
                         try {
-                            lastNode = createOMText(XMLStreamConstants.SPACE);
-                            if (lastNode == null) {
+                            OMNode node = createOMText(XMLStreamConstants.SPACE);
+                            if (node == null) {
                                 continue;
                             }
                         } catch (OMHierarchyException ex) {
@@ -274,16 +279,16 @@ public class StAXOMBuilder extends StAXB
                         }
                         break;
                     case XMLStreamConstants.COMMENT:
-                        lastNode = createComment();
+                        createComment();
                         break;
                     case XMLStreamConstants.DTD:
                         createDTD();
                         break;
                     case XMLStreamConstants.PROCESSING_INSTRUCTION:
-                        lastNode = createPI();
+                        createPI();
                         break;
                     case XMLStreamConstants.ENTITY_REFERENCE:
-                        lastNode = createOMText(XMLStreamConstants.ENTITY_REFERENCE);
+                        createOMText(XMLStreamConstants.ENTITY_REFERENCE);
                         break;
                     default :
                         throw new OMException();
@@ -329,16 +334,6 @@ public class StAXOMBuilder extends StAXB
             log.debug("Invoking CustomBuilder, " + customBuilder.toString() + 
                       ", to the OMNode for {" + namespace + "}" + localPart);
         }
-        OMContainer parent = null;
-        if (lastNode != null) {
-            if (lastNode.isComplete()) {
-                parent = lastNode.getParent();
-            } else {
-                parent = (OMContainer)lastNode;
-            }
-        } else {
-            parent = document;
-        }
         
         // TODO: dirty hack part 1
         // The custom builder will use addNode to insert the new node into the tree. However,
@@ -346,12 +341,12 @@ public class StAXOMBuilder extends StAXB
         // build the parent node. We temporarily set complete to true to avoid this.
         // There is really an incompatibility between the contract of addNode and the
         // custom builder API. This should be fixed in Axiom 1.3.
-        ((OMContainerEx)parent).setComplete(true);
+        target.setComplete(true);
         
-        OMNode node = customBuilder.create(namespace, localPart, parent, parser, factory);
+        OMNode node = customBuilder.create(namespace, localPart, target, parser, factory);
         
         // TODO: dirty hack part 2
-        ((OMContainerEx)parent).setComplete(false);
+        target.setComplete(false);
         
         if (log.isDebugEnabled()) {
             if (node != null) {
@@ -454,19 +449,7 @@ public class StAXOMBuilder extends StAXB
      * @throws OMException
      */
     protected OMNode createOMElement() throws OMException {
-        OMElement node;
-        String elementName = parser.getLocalName();
-        if (lastNode == null) {
-            node = omfactory.createOMElement(elementName, document, this);
-        } else if (lastNode.isComplete()) {
-            node = omfactory.createOMElement(elementName, lastNode.getParent(),
-                                             this);
-        } else {
-            OMContainerEx e = (OMContainerEx) lastNode;
-            node = omfactory.createOMElement(elementName, (OMElement) lastNode,
-                                             this);
-            e.setFirstChild(node);
-        }
+        OMElement node = omfactory.createOMElement(parser.getLocalName(), target, this);
         populateOMElement(node);
         return node;
     }
@@ -478,15 +461,7 @@ public class StAXOMBuilder extends StAXB
      * @throws OMException
      */
     protected OMNode createComment() throws OMException {
-        OMNode node;
-        if (lastNode == null) {
-            node = omfactory.createOMComment(document, parser.getText(), true);
-        } else if (lastNode.isComplete()) {
-            node = omfactory.createOMComment(lastNode.getParent(), parser.getText(), true);
-        } else {
-            node = omfactory.createOMComment((OMElement) lastNode, parser.getText(), true);
-        }
-        return node;
+        return omfactory.createOMComment(target, parser.getText(), true);
     }
 
     /**
@@ -499,9 +474,7 @@ public class StAXOMBuilder extends StAXB
         if (!parser.hasText()) {
             return null;
         }
-        String dtdText = getDTDText();
-        lastNode = omfactory.createOMDocType(document, dtdText, true);
-        return lastNode;
+        return omfactory.createOMDocType(target, getDTDText(), true);
     }
     
     /**
@@ -543,32 +516,12 @@ public class StAXOMBuilder extends StAXB
      * @throws OMException
      */
     protected OMNode createPI() throws OMException {
-        OMNode node;
-        String target = parser.getPITarget();
-        String data = parser.getPIData();
-        if (lastNode == null) {
-            node = omfactory.createOMProcessingInstruction(document, target, data, true);
-        } else if (lastNode.isComplete()) {
-            node = omfactory.createOMProcessingInstruction(lastNode.getParent(), target, data, true);
-        } else if (lastNode instanceof OMText) {
-            node = omfactory.createOMProcessingInstruction(lastNode.getParent(), target, data, true);
-        } else {
-            node = omfactory.createOMProcessingInstruction((OMContainer) lastNode, target, data, true);
-        }
-        return node;
+        return omfactory.createOMProcessingInstruction(target, parser.getPITarget(), parser.getPIData(), true);
     }
 
     protected void endElement() {
-        if (lastNode.isComplete()) {
-            OMNodeEx parent = (OMNodeEx) lastNode.getParent();
-            parent.setComplete(true);
-            lastNode = parent;
-        } else {
-            OMNodeEx e = (OMNodeEx) lastNode;
-            e.setComplete(true);
-        }
-
-        //return lastNode;
+        target.setComplete(true);
+        target = (OMContainerEx)((OMElement)target).getParent();
     }
 
     public OMElement getDocumentElement() {

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/StAXSOAPModelBuilder.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/StAXSOAPModelBuilder.java?rev=1358823&r1=1358822&r2=1358823&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/StAXSOAPModelBuilder.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/StAXSOAPModelBuilder.java Sun Jul  8 19:42:26 2012
@@ -20,15 +20,12 @@
 package org.apache.axiom.soap.impl.builder;
 
 import org.apache.axiom.om.OMAbstractFactory;
-import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDocument;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMMetaFactory;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.impl.OMContainerEx;
-import org.apache.axiom.om.impl.OMNodeEx;
 import org.apache.axiom.om.impl.builder.CustomBuilder;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.axiom.soap.SOAP11Constants;
@@ -207,11 +204,7 @@ public class StAXSOAPModelBuilder extend
         if (elementLevel == 3 && 
             customBuilderForPayload != null) {
             
-            OMNode parent = lastNode;
-            if (parent != null && parent.isComplete()) {
-                parent = (OMNode) lastNode.getParent();
-            }
-            if (parent instanceof SOAPBody) {
+            if (target instanceof SOAPBody) {
                 newElement = createWithCustomBuilder(customBuilderForPayload,  soapFactory);
             }
         } 
@@ -242,28 +235,11 @@ public class StAXSOAPModelBuilder extend
         
         OMElement node;
         String elementName = parser.getLocalName();
-        if (lastNode == null) {
+        if (target instanceof OMDocument) {
             node = constructNode(null, elementName, true);
             setSOAPEnvelope(node);
-        } else if (lastNode.isComplete()) {
-            OMContainer parent = lastNode.getParent();
-            if (parent == document) {
-                // If we get here, this means that we found the SOAP envelope, but that it was
-                // preceded by a comment node. Since constructNode will create a new document
-                // based on the SOAP version of the envelope, we simply discard the last node 
-                // and do as if we just encountered the first node in the document.
-                lastNode = null;
-                node = constructNode(null, elementName, true);
-                setSOAPEnvelope(node);
-            } else {
-                node = constructNode((OMElement)parent,
-                                     elementName,
-                                     false);
-            }
         } else {
-            OMContainerEx e = (OMContainerEx) lastNode;
-            node = constructNode((OMElement) lastNode, elementName, false);
-            e.setFirstChild(node);
+            node = constructNode((OMElement)target, elementName, false);
         }
 
         if (log.isDebugEnabled()) {
@@ -437,17 +413,6 @@ public class StAXSOAPModelBuilder extend
         return envelope.getVersion().getReceiverFaultCode().getLocalPart();
     }
 
-    public void endElement() {
-        if (lastNode.isComplete()) {
-            OMElement parent = (OMElement) lastNode.getParent();
-            ((OMNodeEx) parent).setComplete(true);
-            lastNode = parent;
-        } else {
-            OMNode e = lastNode;
-            ((OMNodeEx) e).setComplete(true);
-        }
-    }
-
     /** Method createDTD. Overriding the default behaviour as a SOAPMessage should not have a DTD. */
     protected OMNode createDTD() throws OMException {
         throw new OMException("SOAP message MUST NOT contain a Document Type Declaration(DTD)");

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java?rev=1358823&r1=1358822&r2=1358823&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java Sun Jul  8 19:42:26 2012
@@ -1359,22 +1359,11 @@ public class ElementImpl extends ParentN
         state = DISCARDED;
     }
 
-    public OMNode detach() throws OMException {
-        if (isComplete() && !getParent().isComplete() && getNextOMSiblingIfAvailable() == null) {
-            // Special case: the node is complete, but the next node has not yet been created.
-            // In this case we want to detach the node without creating the next node because
-            // the builder may already have been closed (there is code in Axis2 that calls
-            // detach in that situation). We use discard for this: in this state, discard
-            // actually won't discard anything, but it will update the lastNode attribute
-            // of the builder.
-            getBuilder().discard(this);
-        } else {
-            if (state == INCOMPLETE) {
-                build();
-            }
-            super.detach();
+    OMNode detach(boolean useDomSemantics) {
+        if (state == INCOMPLETE) {
+            build();
         }
-        return this;
+        return super.detach(useDomSemantics);
     }
 
     public final void build() {

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NodeImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NodeImpl.java?rev=1358823&r1=1358822&r2=1358823&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NodeImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/NodeImpl.java Sun Jul  8 19:42:26 2012
@@ -607,10 +607,6 @@ public abstract class NodeImpl implement
         if (parentNode == null) {
             throw new OMException("Parent level elements cannot be detached");
         } else {
-            if (!isComplete()) {
-                build();
-            }
-            getNextSibling(); // Make sure that nextSibling is set correctly
             NodeImpl previousSibling = internalGetPreviousSibling();
             NodeImpl nextSibling = internalGetNextSibling();
             if (previousSibling == null) { // This is the first child
@@ -622,9 +618,6 @@ public abstract class NodeImpl implement
                 }
             } else {
                 previousSibling.setNextOMSibling((OMNode)nextSibling);
-                if (nextSibling == null) {
-                    previousSibling.parentNode().setComplete(true);
-                }
             }
             if (nextSibling != null) {
                 nextSibling.setPreviousOMSibling((OMNode)previousSibling);

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java?rev=1358823&r1=1358822&r2=1358823&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java Sun Jul  8 19:42:26 2012
@@ -670,20 +670,10 @@ public class OMElementImpl extends OMNod
      * @throws OMException
      */
     public OMNode detach() throws OMException {
-        if (isComplete() && !parent.isComplete() && getNextOMSiblingIfAvailable() == null) {
-            // Special case: the node is complete, but the next node has not yet been created.
-            // In this case we want to detach the node without creating the next node because
-            // the builder may already have been closed (there is code in Axis2 that calls
-            // detach in that situation). We use discard for this: in this state, discard
-            // actually won't discard anything, but it will update the lastNode attribute
-            // of the builder.
-            getBuilder().discard(this);
-        } else {
-            if (state == INCOMPLETE) {
-                build();
-            }
-            super.detach();
+        if (state == INCOMPLETE) {
+            build();
         }
+        super.detach();
         return this;
     }
 

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java?rev=1358823&r1=1358822&r2=1358823&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java Sun Jul  8 19:42:26 2012
@@ -134,7 +134,10 @@ public abstract class OMNodeImpl extends
             throw new OMException(
                     "Nodes that don't have a parent can not be detached");
         }
-        OMNodeImpl nextSibling = (OMNodeImpl) getNextOMSibling();
+        // Note that we don't need to force creation of the next sibling because the
+        // builder will always add new nodes to the end of list of children of the
+        // document or element being built.
+        OMNodeImpl nextSibling = (OMNodeImpl) getNextOMSiblingIfAvailable();
         if (previousSibling == null) {
             parent.setFirstChild(nextSibling);
         } else {