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 20:24:12 UTC

svn commit: r1358610 [7/10] - in /webservices/axiom/branches/AXIOM-201: ./ modules/axiom-api/ modules/axiom-api/src/main/java/org/apache/axiom/attachments/ modules/axiom-api/src/main/java/org/apache/axiom/locator/ modules/axiom-api/src/main/java/org/ap...

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMAttributeImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMAttributeImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMAttributeImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMAttributeImpl.java Sat Jul  7 18:24:00 2012
@@ -29,13 +29,10 @@ import javax.xml.namespace.QName;
 
 /** Class OMAttributeImpl */
 public class OMAttributeImpl implements OMAttribute {
-    /** Field localName */
     private String localName;
 
-    /** Field value */
     private String value;
 
-    /** Field type */
     private String type;
 
     /**
@@ -124,11 +121,6 @@ public class OMAttributeImpl implements 
         this.qName = null;
     }
 
-    /**
-     * Method getAttributeValue.
-     *
-     * @return Returns value.
-     */
     public String getAttributeValue() {
         return value;
     }
@@ -142,13 +134,8 @@ public class OMAttributeImpl implements 
         this.value = value;
     }
 
-    /**
-     * Method getAttributeType.
-     *
-     * @return Returns type.
-     */
     public String getAttributeType() {
-    	return type;
+        return type;
     }
 
     /**
@@ -203,10 +190,6 @@ public class OMAttributeImpl implements 
         return this.factory;
     }
 
-    /**
-     * Returns the owner element of this attribute
-     * @return OMElement - the owner element
-     */
     public OMElement getOwner() {
         return owner;
     }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMCommentImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMCommentImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMCommentImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMCommentImpl.java Sat Jul  7 18:24:00 2012
@@ -19,16 +19,16 @@
 
 package org.apache.axiom.om.impl.llom;
 
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMComment;
 import org.apache.axiom.om.OMContainer;
-import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNode;
 
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
-public class OMCommentImpl extends OMNodeImpl implements OMComment {
+public class OMCommentImpl extends OMLeafNode implements OMComment {
     protected String value;
 
     /**
@@ -38,19 +38,13 @@ public class OMCommentImpl extends OMNod
      * @param contentText
      */
     public OMCommentImpl(OMContainer parentNode, String contentText,
-                         OMFactory factory) {
-        super(parentNode, factory, true);
+                         OMFactory factory, boolean fromBuilder) {
+        super(parentNode, factory, fromBuilder);
         this.value = contentText;
-        nodeType = OMNode.COMMENT_NODE;
     }
 
-    /**
-     * Constructor OMCommentImpl.
-     *
-     * @param parentNode
-     */
-    public OMCommentImpl(OMContainer parentNode, OMFactory factory) {
-        this(parentNode, null, factory);
+    public final int getType() {
+        return OMNode.COMMENT_NODE;
     }
 
     public void internalSerialize(XMLStreamWriter writer, boolean cache) throws XMLStreamException {
@@ -75,14 +69,7 @@ public class OMCommentImpl extends OMNod
         this.value = text;
     }
 
-    /**
-     * Discards this node.
-     *
-     * @throws OMException
-     */
-    public void discard() throws OMException {
-        if (done) {
-            this.detach();
-        } 
+    OMNode clone(OMCloneOptions options, OMContainer targetParent) {
+        return factory.createOMComment(targetParent, value);
     }
 }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocTypeImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocTypeImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocTypeImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocTypeImpl.java Sat Jul  7 18:24:00 2012
@@ -19,16 +19,16 @@
 
 package org.apache.axiom.om.impl.llom;
 
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDocType;
-import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNode;
 
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
-public class OMDocTypeImpl extends OMNodeImpl implements OMDocType {
+public class OMDocTypeImpl extends OMLeafNode implements OMDocType {
     protected String value;
 
     /**
@@ -38,19 +38,13 @@ public class OMDocTypeImpl extends OMNod
      * @param contentText
      */
     public OMDocTypeImpl(OMContainer parentNode, String contentText,
-                         OMFactory factory) {
-        super(parentNode, factory, true);
+                         OMFactory factory, boolean fromBuilder) {
+        super(parentNode, factory, fromBuilder);
         this.value = contentText;
-        nodeType = OMNode.DTD_NODE;
     }
 
-    /**
-     * Constructor OMDocTypeImpl.
-     *
-     * @param parentNode
-     */
-    public OMDocTypeImpl(OMContainer parentNode, OMFactory factory) {
-        this(parentNode, null, factory);
+    public final int getType() {
+        return OMNode.DTD_NODE;
     }
 
     public void internalSerialize(XMLStreamWriter writer, boolean cache) throws XMLStreamException {
@@ -75,14 +69,7 @@ public class OMDocTypeImpl extends OMNod
         this.value = text;
     }
 
-    /**
-     * Discards this node.
-     *
-     * @throws OMException
-     */
-    public void discard() throws OMException {
-        if (done) {
-            this.detach();
-        } 
+    OMNode clone(OMCloneOptions options, OMContainer targetParent) {
+        return factory.createOMDocType(targetParent, value);
     }
 }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java Sat Jul  7 18:24:00 2012
@@ -24,12 +24,10 @@ import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.OMXMLStreamReaderConfiguration;
 import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
 import org.apache.axiom.om.impl.OMContainerEx;
-import org.apache.axiom.om.impl.OMNodeEx;
 import org.apache.axiom.om.impl.common.OMChildrenLocalNameIterator;
 import org.apache.axiom.om.impl.common.OMChildrenNamespaceIterator;
 import org.apache.axiom.om.impl.common.OMChildrenQNameIterator;
@@ -49,6 +47,10 @@ import java.util.Iterator;
 
 /** Class OMDocumentImpl */
 public class OMDocumentImpl extends OMSerializableImpl implements OMDocument, OMContainerEx {
+    protected OMXMLParserWrapper builder;
+
+    protected boolean done;
+
     /** Field firstChild */
     protected OMNode firstChild;
 
@@ -106,16 +108,12 @@ public class OMDocumentImpl extends OMSe
     }
 
     public OMElement getOMDocumentElement() {
-        return getOMDocumentElement(true);
-    }
-
-    private OMElement getOMDocumentElement(boolean build) {
-        OMNode child = build ? getFirstOMChild() : getFirstOMChildIfAvailable();
+        OMNode child = getFirstOMChild();
         while (child != null) {
             if (child instanceof OMElement) {
                 return (OMElement)child;
             }
-            child = build ? child.getNextOMSibling() : ((OMNodeEx)child).getNextOMSiblingIfAvailable();
+            child = child.getNextOMSibling();
         }
         return null;
     }
@@ -138,6 +136,10 @@ public class OMDocumentImpl extends OMSe
         }
     }
 
+    public boolean isComplete() {
+        return done;
+    }
+
     /**
      * Method setComplete.
      *
@@ -147,52 +149,15 @@ public class OMDocumentImpl extends OMSe
         this.done = state;
     }
 
-    /** Forces the parser to proceed, if parser has not yet finished with the XML input. */
-    public void buildNext() {
-        if (builder != null && !builder.isCompleted()) {
-            builder.next();
-        }
-    }
-
-    /**
-     * Adds child to the element. One can decide whether to append the child or to add to the front
-     * of the children list.
-     *
-     * @param child
-     */
     public void addChild(OMNode child) {
-        if (child instanceof OMElement) {
-            if (getOMDocumentElement(false) == null) {
-                addChild((OMNodeImpl) child);
-            } else {
-                throw new OMException("Document element already exists");
-            }
-        } else {
-            addChild((OMNodeImpl) child);
-        }
+        addChild(child, false);
     }
 
-    /**
-     * Method addChild.
-     *
-     * @param child
-     */
-    private void addChild(OMNodeImpl child) {
-        if (firstChild == null) {
-            firstChild = child;
-            child.setPreviousOMSibling(null);
-        } else {
-            child.setPreviousOMSibling(lastChild);
-            ((OMNodeEx) lastChild).setNextOMSibling(child);
-        }
-        child.setNextOMSibling(null);
-        child.setParent(this);
-        lastChild = child;
-
-        if (!child.isComplete() && 
-            !(child instanceof OMSourcedElement)) {
-            this.setComplete(false);
+    public void addChild(OMNode omNode, boolean fromBuilder) {
+        if (!fromBuilder && omNode instanceof OMElement && getOMDocumentElement() != null) {
+            throw new OMException("Document element already exists");
         }
+        OMContainerHelper.addChild(this, omNode, fromBuilder);
     }
 
     /**
@@ -248,6 +213,10 @@ public class OMDocumentImpl extends OMSe
         return firstChild;
     }
 
+    public OMNode getLastKnownOMChild() {
+        return lastChild;
+    }
+
     /**
      * Method getFirstChildWithName.
      *

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java Sat Jul  7 18:24:00 2012
@@ -20,6 +20,7 @@
 package org.apache.axiom.om.impl.llom;
 
 import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMConstants;
 import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMElement;
@@ -27,13 +28,11 @@ import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.OMXMLStreamReaderConfiguration;
 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.builder.StAXOMBuilder;
 import org.apache.axiom.om.impl.common.NamespaceIterator;
 import org.apache.axiom.om.impl.common.OMChildElementIterator;
 import org.apache.axiom.om.impl.common.OMChildrenLegacyQNameIterator;
@@ -45,7 +44,6 @@ import org.apache.axiom.om.impl.common.O
 import org.apache.axiom.om.impl.common.OMElementImplUtil;
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
 import org.apache.axiom.om.impl.jaxp.OMSource;
-import org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory;
 import org.apache.axiom.om.impl.traverse.OMChildrenIterator;
 import org.apache.axiom.om.impl.util.EmptyIterator;
 import org.apache.axiom.om.impl.util.OMSerializerUtil;
@@ -55,7 +53,6 @@ import org.apache.commons.logging.LogFac
 
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
@@ -75,6 +72,10 @@ public class OMElementImpl extends OMNod
 
     private static final Log log = LogFactory.getLog(OMElementImpl.class);
     
+    protected OMXMLParserWrapper builder;
+
+    protected boolean done;
+
     /**
      * The namespace of this element. Possible values:
      * <ul>
@@ -107,45 +108,19 @@ public class OMElementImpl extends OMNod
     private int lineNumber;
     private static final EmptyIterator EMPTY_ITERATOR = new EmptyIterator();
 
-    /**
-     * Constructor OMElementImpl. A null namespace indicates that the default namespace in scope is
-     * used
-     */
-    public OMElementImpl(String localName, OMNamespace ns, OMContainer parent,
-                         OMXMLParserWrapper builder, OMFactory factory) {
-        super(parent, factory, false);
-        this.localName = localName;
-        if (ns != null) {
-            setNamespace(ns);
-        }
-        this.builder = builder;
-        firstChild = null;
-    }
-
-
-    /** Constructor OMElementImpl. */
-    public OMElementImpl(String localName, OMNamespace ns, OMFactory factory) {
-        this(localName, ns, null, factory);
-    }
-
-    /**
-     * This is the basic constructor for OMElement. All the other constructors depends on this.
-     *
-     * @param localName - this MUST always be not null
-     * @param ns        - can be null
-     * @param parent    - this should be an OMContainer
-     * @param factory   - factory that created this OMElement
-     *                  <p/>
-     *                  A null namespace indicates that the default namespace in scope is used
-     */
-    public OMElementImpl(String localName, OMNamespace ns, OMContainer parent,
-                         OMFactory factory) {
-        super(parent, factory, true);
+    public OMElementImpl(OMContainer parent, String localName, OMNamespace ns, OMXMLParserWrapper builder,
+                    OMFactory factory, boolean generateNSDecl) {
+        super(factory);
         if (localName == null || localName.trim().length() == 0) {
             throw new OMException("localname can not be null or empty");
         }
         this.localName = localName;
-        setNamespace(ns);
+        this.builder = builder;
+        this.done = builder == null;
+        if (parent != null) {
+            ((OMContainerEx)parent).addChild(this, builder != null);
+        }
+        this.ns = generateNSDecl ? handleNamespace(ns) : ns;
     }
 
     /**
@@ -156,10 +131,24 @@ public class OMElementImpl extends OMNod
      */
     public OMElementImpl(QName qname, OMContainer parent, OMFactory factory)
             throws OMException {
-        super(parent, factory, true);
+        super(factory);
+        done = true;
+        if (parent != null) {
+            parent.addChild(this);
+        }
         localName = qname.getLocalPart();
         this.ns = handleNamespace(qname);
     }
+    
+    /**
+     * Constructor reserved for use by {@link OMSourcedElementImpl}.
+     * 
+     * @param factory
+     */
+    OMElementImpl(OMFactory factory) {
+        super(factory);
+        done = true;
+    }
 
     /** Method handleNamespace. */
     OMNamespace handleNamespace(QName qname) {
@@ -204,7 +193,7 @@ public class OMElementImpl extends OMNod
             return null;
         } else {
             OMNamespace namespace = findNamespace(namespaceURI, prefix);
-            if (namespace == null) {
+            if (namespace == null || (prefix != null && !namespace.getPrefix().equals(prefix))) {
                 namespace = declareNamespace(ns);
             }
             return namespace;
@@ -228,18 +217,13 @@ public class OMElementImpl extends OMNod
         }
     }
 
-    /**
-     * Adds child to the element. One can decide whether to append the child or to add to the front
-     * of the children list.
-     */
-    public void addChild(OMNode child) {
-        if (child.getOMFactory() instanceof OMLinkedListImplFactory) {
-            addChild((OMNodeImpl) child);
-        } else {
-            addChild(importNode(child));
-        }
+    public void addChild(OMNode omNode) {
+        addChild(omNode, false);
     }
 
+    public void addChild(OMNode omNode, boolean fromBuilder) {
+        OMContainerHelper.addChild(this, omNode, fromBuilder);
+    }
 
     /**
      * Searches for children with a given QName and returns an iterator to traverse through the
@@ -304,66 +288,6 @@ public class OMElementImpl extends OMNod
 
     }
 
-    /** Method addChild. */
-    private void addChild(OMNodeImpl child) {
-        if (child.parent == this && child == lastChild && done) {
-            // The child is already the last node. 
-            // We don't need to detach and re-add it.
-        } else {
-            // Normal Case
-            
-            if (child.parent != null) {
-                child.detach();
-            }
-            
-            child.parent = this;
-
-            if (firstChild == null) {
-                firstChild = child;
-                child.previousSibling = null;
-            } else {
-                child.previousSibling = (OMNodeImpl) lastChild;
-                ((OMNodeImpl) lastChild).nextSibling = child;
-            }
-
-            child.nextSibling = null;
-            lastChild = child;
-        }
-
-        // For a normal OMNode, the incomplete status is
-        // propogated up the tree.  
-        // However, a OMSourcedElement is self-contained 
-        // (it has an independent parser source).
-        // So only propogate the incomplete setting if this
-        // is a normal OMNode
-        if (!child.isComplete() && 
-            !(child instanceof OMSourcedElement)) {
-            this.setComplete(false);
-        }
-
-    }
-
-    /**
-     * Gets the next sibling. This can be an OMAttribute or OMText or OMELement for others.
-     *
-     * @throws OMException
-     */
-    public OMNode getNextOMSibling() throws OMException {
-        while (!done && builder != null ) {
-            if (builder.isCompleted()) {
-                log.debug("Builder is complete.  Setting OMElement to complete.");
-                setComplete(true);
-            } else {
-                int token = builder.next();
-                if (token == XMLStreamConstants.END_DOCUMENT) {
-                    throw new OMException(
-                    "Parser has already reached end of the document. No siblings found");
-                }
-            }
-        }
-        return super.getNextOMSibling();
-    }
-
     /**
      * Returns a collection of this element. Children can be of types OMElement, OMText.
      *
@@ -424,12 +348,16 @@ public class OMElementImpl extends OMNod
     }
 
     public OMNamespace addNamespaceDeclaration(String uri, String prefix) {
+        OMNamespace ns = new OMNamespaceImpl(uri, prefix);
+        addNamespaceDeclaration(ns);
+        return ns;
+    }
+    
+    void addNamespaceDeclaration(OMNamespace ns) {
         if (namespaces == null) {
             this.namespaces = new HashMap(5);
         }
-        OMNamespace ns = new OMNamespaceImpl(uri, prefix);
-        namespaces.put(prefix, ns);
-        return ns;
+        namespaces.put(ns.getPrefix(), ns);
     }
 
     /** @return Returns namespace. */
@@ -640,9 +568,6 @@ public class OMElementImpl extends OMNod
                     attr.getLocalName(), attr.getNamespace(), attr.getAttributeValue(), attr.getOMFactory());
         }
 
-        if (attributes == null) {
-            this.attributes = new LinkedHashMap(5);
-        }
         OMNamespace namespace = attr.getNamespace();
         if (namespace != null) {
             String uri = namespace.getNamespaceURI();
@@ -655,6 +580,14 @@ public class OMElementImpl extends OMNod
             }
         }
 
+        appendAttribute(attr);
+        return attr;
+    }
+    
+    void appendAttribute(OMAttribute attr) {
+        if (attributes == null) {
+            this.attributes = new LinkedHashMap(5);
+        }
         // Set the owner element of the attribute
         ((OMAttributeImpl)attr).owner = this;
         OMAttributeImpl oldAttr = (OMAttributeImpl)attributes.put(attr.getQName(), attr);
@@ -662,7 +595,6 @@ public class OMElementImpl extends OMNod
         if (oldAttr != null) {
             oldAttr.owner = null;
         }
-        return attr;
     }
 
     public void removeAttribute(OMAttribute attr) {
@@ -702,18 +634,6 @@ public class OMElementImpl extends OMNod
         return builder;
     }
 
-    /** Forces the parser to proceed, if parser has not yet finished with the XML input. */
-    public void buildNext() {
-        if (builder != null) {
-            if (!builder.isCompleted()) {
-                builder.next();
-            } else {
-                this.setComplete(true);
-                log.debug("Builder is complete.  Setting OMElement to complete.");
-            }         
-        }
-    }
-
     /**
      * Method getFirstOMChild.
      *
@@ -730,6 +650,9 @@ public class OMElementImpl extends OMNod
         return firstChild;
     }
 
+    public OMNode getLastKnownOMChild() {
+        return lastChild;
+    }
 
     /** Method setFirstChild. */
     public void setFirstChild(OMNode firstChild) {
@@ -750,14 +673,23 @@ public class OMElementImpl extends OMNod
      * @throws OMException
      */
     public OMNode detach() throws OMException {
-        if (!done) {
-            build();
+        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 (!done) {
+                build();
+            }
+            super.detach();
         }
-        super.detach();
         return this;
     }
 
-    /** Gets the type of node, as this is the super class of all the nodes. */
     public int getType() {
         return OMNode.ELEMENT_NODE;
     }
@@ -778,6 +710,23 @@ public class OMElementImpl extends OMNod
 
     }
 
+    public boolean isComplete() {
+        return done;
+    }
+
+    public void setComplete(boolean state) {
+        this.done = state;
+        if (parent != null) {
+            if (!done) {
+                parent.setComplete(false);
+            } else if (parent instanceof OMElementImpl) {
+                ((OMElementImpl) parent).notifyChildComplete();
+            } else if (parent instanceof OMDocumentImpl) {
+                ((OMDocumentImpl) parent).notifyChildComplete();
+            }
+        }
+    }
+
     public XMLStreamReader getXMLStreamReader() {
         return getXMLStreamReader(true);
     }
@@ -998,24 +947,38 @@ public class OMElementImpl extends OMNod
             log.debug(" isComplete = " + isComplete());
             log.debug("  builder = " + builder);
         }
-        // Make sure the source (this node) is completed
-        if (!isComplete()) {
-            this.build();
+        return cloneOMElement(new OMCloneOptions());
+    }
+
+    public OMElement cloneOMElement(OMCloneOptions options) {
+        return (OMElement)clone(options, null);
+    }
+
+    OMNode clone(OMCloneOptions options, OMContainer targetParent) {
+        OMElement targetElement;
+        if (options.isPreserveModel()) {
+            targetElement = createClone(options, targetParent);
+        } else {
+            targetElement = factory.createOMElement(getLocalName(), getNamespace(), targetParent);
         }
-        
-        // Now get a parser for the full tree
-        XMLStreamReader xmlStreamReader = this.getXMLStreamReader(true);
-        if (log.isDebugEnabled()) {
-            log.debug("  reader = " + xmlStreamReader);
+        for (Iterator it = getAllDeclaredNamespaces(); it.hasNext(); ) {
+            OMNamespace ns = (OMNamespace)it.next();
+            targetElement.declareNamespace(ns);
         }
-        
-        // Build the (target) clonedElement from the parser
-        OMElement clonedElement =
-                new StAXOMBuilder(xmlStreamReader).getDocumentElement();
-        clonedElement.build();
-        return clonedElement;
+        for (Iterator it = getAllAttributes(); it.hasNext(); ) {
+            OMAttribute attr = (OMAttribute)it.next();
+            targetElement.addAttribute(attr);
+        }
+        for (Iterator it = getChildren(); it.hasNext(); ) {
+            ((OMNodeImpl)it.next()).clone(options, targetElement);
+        }
+        return targetElement;
     }
 
+    protected OMElement createClone(OMCloneOptions options, OMContainer targetParent) {
+        return factory.createOMElement(getLocalName(), getNamespace(), targetParent);
+    }
+    
     public void setLineNumber(int lineNumber) {
         this.lineNumber = lineNumber;
     }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNodeImpl.java Sat Jul  7 18:24:00 2012
@@ -22,18 +22,14 @@ package org.apache.axiom.om.impl.llom;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
-import org.apache.axiom.om.OMComment;
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMContainer;
-import org.apache.axiom.om.OMDocType;
-import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.OMProcessingInstruction;
-import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.impl.OMContainerEx;
 import org.apache.axiom.om.impl.OMNodeEx;
-import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.impl.builder.OMFactoryEx;
 import org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory;
 
 /** Class OMNodeImpl */
@@ -48,9 +44,6 @@ public abstract class OMNodeImpl extends
     /** Field previousSibling */
     protected OMNodeImpl previousSibling;
 
-    /** Field nodeType */
-    protected int nodeType;
-
     /**
      * Constructor OMNodeImpl
      *
@@ -61,21 +54,6 @@ public abstract class OMNodeImpl extends
     }
 
     /**
-     * For a node to exist there must be a parent.
-     *
-     * @param parent  Parent <code>OMContainer</code> of this node
-     * @param factory The <code>OMFactory</code> that created this
-     */
-    public OMNodeImpl(OMContainer parent, OMFactory factory, boolean done) {
-        super(factory);
-        this.done = done;
-        if ((parent != null)) {
-            parent.addChild(this);
-        }
-
-    }
-
-    /**
      * Returns the immediate parent of the node. Parent is always an Element.
      *
      * @return Returns OMContainer.
@@ -117,8 +95,10 @@ public abstract class OMNodeImpl extends
      *
      */
     public OMNode getNextOMSibling() throws OMException {
-        if ((nextSibling == null) && (parent != null) && !parent.isComplete()) {
-            parent.buildNext();
+        if (nextSibling == null && parent != null && parent.getBuilder() != null) {
+            while (!parent.isComplete() && nextSibling == null) {
+                parent.buildNext();
+            }
         }
         return nextSibling;
     }
@@ -136,30 +116,12 @@ public abstract class OMNodeImpl extends
         if (node == null || node.getOMFactory() instanceof OMLinkedListImplFactory) {
             this.nextSibling = (OMNodeImpl) node;
         } else {
-            this.nextSibling = (OMNodeImpl) importNode(node);
+            this.nextSibling = (OMNodeImpl) ((OMFactoryEx)factory).importNode(node);
         }
         this.nextSibling = (OMNodeImpl) node;
     }
 
     /**
-     * Method setComplete.
-     *
-     * @param state
-     */
-    public void setComplete(boolean state) {
-        this.done = state;
-        if (parent != null) {
-            if (!done) {
-                parent.setComplete(false);
-            } else if (parent instanceof OMElementImpl) {
-                ((OMElementImpl) parent).notifyChildComplete();
-            } else if (parent instanceof OMDocumentImpl) {
-                ((OMDocumentImpl) parent).notifyChildComplete();
-            }
-        }
-    }
-
-    /**
      * Removes this information item and its children, from the model completely.
      *
      * @throws OMException
@@ -249,26 +211,6 @@ public abstract class OMNodeImpl extends
     }
 
     /**
-     * Gets the type of node, as this is the super class of all the nodes.
-     *
-     * @return Returns the type of node as indicated by {@link #setType}
-     * @see #setType
-     */
-    public int getType() {
-        return nodeType;
-    }
-
-    /**
-     * Method setType.
-     *
-     * @param nodeType
-     * @throws OMException
-     */
-    public void setType(int nodeType) throws OMException {
-        this.nodeType = nodeType;
-    }
-
-    /**
      * Gets the previous sibling.
      *
      * @return boolean
@@ -287,7 +229,7 @@ public abstract class OMNodeImpl extends
                 previousSibling.getOMFactory() instanceof OMLinkedListImplFactory) {
             this.previousSibling = (OMNodeImpl) previousSibling;
         } else {
-            this.previousSibling = (OMNodeImpl) importNode(previousSibling);
+            this.previousSibling = (OMNodeImpl) ((OMFactoryEx)factory).importNode(previousSibling);
         }
     }
 
@@ -300,65 +242,11 @@ public abstract class OMNodeImpl extends
      * to free the input stream.
      */
     public void buildWithAttachments() {
-        if (!this.done) {
+        if (!isComplete()) {
             this.build();
         }
     }
 
-    /**
-     * This method is intended only to be used by Axiom intenals when merging Objects from different
-     * Axiom implementations to the LLOM implementation.
-     *
-     * @param child
-     */
-    protected OMNode importNode(OMNode child) {
-        int type = child.getType();
-        switch (type) {
-            case (OMNode.ELEMENT_NODE): {
-                OMElement childElement = (OMElement) child;
-                OMElement newElement = (new StAXOMBuilder(this.factory, childElement
-                        .getXMLStreamReader())).getDocumentElement();
-                newElement.buildWithAttachments();
-                return newElement;
-            }
-            case (OMNode.TEXT_NODE): {
-                OMText importedText = (OMText) child;
-                OMText newText;
-                if (importedText.isBinary()) {
-                    boolean isOptimize = importedText.isOptimized();
-                    newText = this.factory.createOMText(importedText
-                            .getDataHandler(), isOptimize);
-                } else if (importedText.isCharacters()) {
-                    newText = this.factory.createOMText(null, importedText
-                            .getTextCharacters(), importedText.getType());
-                } else {
-                    newText = this.factory.createOMText(null, importedText
-                            .getText()/*, importedText.getOMNodeType()*/);
-                }
-                return newText;
-            }
-
-            case (OMNode.PI_NODE): {
-                OMProcessingInstruction importedPI = (OMProcessingInstruction) child;
-                return factory.createOMProcessingInstruction(null,
-                                                                  importedPI.getTarget(),
-                                                                  importedPI.getValue());
-            }
-            case (OMNode.COMMENT_NODE): {
-                OMComment importedComment = (OMComment) child;
-                return factory.createOMComment(null, importedComment.getValue());
-            }
-            case (OMNode.DTD_NODE) : {
-                OMDocType importedDocType = (OMDocType) child;
-                return factory.createOMDocType(null, importedDocType.getValue());
-            }
-            default: {
-                throw new UnsupportedOperationException(
-                        "Not Implemented Yet for the given node type");
-            }
-        }
-    }
-
     public void internalSerialize(XMLStreamWriter writer) throws XMLStreamException {
         internalSerialize(writer, true);
     }
@@ -366,4 +254,6 @@ public abstract class OMNodeImpl extends
     public void internalSerializeAndConsume(XMLStreamWriter writer) throws XMLStreamException {
         internalSerialize(writer, false);
     }
+    
+    abstract OMNode clone(OMCloneOptions options, OMContainer targetParent);
 }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMProcessingInstructionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMProcessingInstructionImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMProcessingInstructionImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMProcessingInstructionImpl.java Sat Jul  7 18:24:00 2012
@@ -19,8 +19,8 @@
 
 package org.apache.axiom.om.impl.llom;
 
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMContainer;
-import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMProcessingInstruction;
@@ -28,7 +28,7 @@ import org.apache.axiom.om.OMProcessingI
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
-public class OMProcessingInstructionImpl extends OMNodeImpl implements OMProcessingInstruction {
+public class OMProcessingInstructionImpl extends OMLeafNode implements OMProcessingInstruction {
     protected String target;
     protected String value;
 
@@ -40,21 +40,14 @@ public class OMProcessingInstructionImpl
      * @param value
      */
     public OMProcessingInstructionImpl(OMContainer parentNode, String target,
-                                       String value, OMFactory factory) {
-        super(parentNode, factory, true);
+                                       String value, OMFactory factory, boolean fromBuilder) {
+        super(parentNode, factory, fromBuilder);
         this.target = target;
         this.value = value;
-        nodeType = OMNode.PI_NODE;
     }
 
-    /**
-     * Constructor OMProcessingInstructionImpl.
-     *
-     * @param parentNode
-     */
-    public OMProcessingInstructionImpl(OMContainer parentNode,
-                                       OMFactory factory) {
-        this(parentNode, null, null, factory);
+    public final int getType() {
+        return OMNode.PI_NODE;
     }
 
     public void internalSerialize(XMLStreamWriter writer, boolean cache) throws XMLStreamException {
@@ -97,14 +90,7 @@ public class OMProcessingInstructionImpl
         this.value = text;
     }
 
-    /**
-     * Discards this node.
-     *
-     * @throws OMException
-     */
-    public void discard() throws OMException {
-        if (done) {
-            this.detach();
-        } 
+    OMNode clone(OMCloneOptions options, OMContainer targetParent) {
+        return factory.createOMProcessingInstruction(targetParent, target, value);
     }
 }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSerializableImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSerializableImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSerializableImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSerializableImpl.java Sat Jul  7 18:24:00 2012
@@ -32,6 +32,7 @@ import org.apache.axiom.om.OMSerializabl
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
 import org.apache.axiom.om.impl.builder.StAXBuilder;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.axiom.om.util.StAXUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -39,26 +40,18 @@ import org.apache.commons.logging.LogFac
 public abstract class OMSerializableImpl implements OMSerializable {
     private static final Log log = LogFactory.getLog(OMSerializableImpl.class);
     
-    /** Field parserWrapper */
-    public OMXMLParserWrapper builder;
-
-    /** Field done */
-    protected boolean done = false;
-
     protected final OMFactory factory;
 
     public OMSerializableImpl(OMFactory factory) {
         this.factory = factory;
     }
-
+    
     public OMFactory getOMFactory() {
         return factory;
     }
 
-    public boolean isComplete() {
-        return done;
-    }
-
+    public abstract OMXMLParserWrapper getBuilder();
+    
     /**
      * Parses this node and builds the object structure in memory. However a node, created
      * programmatically, will have done set to true by default and this will cause populateyourself
@@ -67,24 +60,42 @@ public abstract class OMSerializableImpl
      * @throws OMException
      */
     public void build() throws OMException {
+        OMXMLParserWrapper builder = getBuilder();
         if (builder != null && builder.isCompleted()) {
             log.debug("Builder is already complete.");
         }
-        while (!done) {
+        while (!isComplete()) {
 
             builder.next();    
-            if (builder.isCompleted() && !done) {
+            if (builder.isCompleted() && !isComplete()) {
                 log.debug("Builder is complete.  Setting OMObject to complete.");
                 setComplete(true);
             }
         }
     }
     
+    /** Forces the parser to proceed, if parser has not yet finished with the XML input. */
+    public void buildNext() {
+        OMXMLParserWrapper builder = getBuilder();
+        if (builder != null) {
+            if (((StAXOMBuilder)builder).isClosed()) {
+                throw new OMException("The builder has already been closed");
+            } else if (!builder.isCompleted()) {
+                builder.next();
+            } else {
+                // If the builder is suddenly complete, but the completion status of the node
+                // doesn't change, then this means that we built the wrong nodes
+                throw new IllegalStateException("Builder is already complete");
+            }         
+        }
+    }
+
     public void close(boolean build) {
+        OMXMLParserWrapper builder = getBuilder();
         if (build) {
             this.build();
         }
-        this.done = true;
+        setComplete(true);
         
         // If this is a StAXBuilder, close it.
         if (builder instanceof StAXBuilder &&

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java Sat Jul  7 18:24:00 2012
@@ -20,6 +20,7 @@
 package org.apache.axiom.om.impl.llom;
 
 import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDataSource;
 import org.apache.axiom.om.OMDataSourceExt;
@@ -32,6 +33,8 @@ import org.apache.axiom.om.OMOutputForma
 import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.OMXMLStreamReaderConfiguration;
+import org.apache.axiom.om.QNameAwareOMDataSource;
+import org.apache.axiom.om.ds.AbstractPushOMDataSource;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
 import org.apache.axiom.om.util.StAXUtils;
@@ -72,6 +75,15 @@ public class OMSourcedElementImpl extend
 
     /** Namespace for element, needed in order to bypass base class handling. */
     private OMNamespace definedNamespace = null;
+    
+    /**
+     * Flag indicating whether the {@link #definedNamespace} attribute has been set. If this flag is
+     * <code>true</code> and {@link #definedNamespace} is <code>null</code> then the element has no
+     * namespace. If this flag is set to <code>false</code> (in which case {@link #definedNamespace}
+     * is always <code>null</code>) then the namespace is not known and needs to be determined
+     * lazily. The flag is used only if {@link #isExpanded} is <code>false</code>.
+     */
+    private boolean definedNamespaceSet;
 
     /** Flag for parser provided to base element class. */
     private boolean isExpanded;
@@ -82,16 +94,17 @@ public class OMSourcedElementImpl extend
     
     private XMLStreamReader readerFromDS = null;  // Reader from DataSource
 
-    private static OMNamespace normalize(OMNamespace ns) {
-        // TODO: the ns.getPrefix() == null case actually doesn't make sense for a sourced element!
-        return ns == null || (ns.getPrefix() == null || ns.getPrefix().length() == 0) && ns.getNamespaceURI().length() == 0 ? null : ns;
-    }
-    
     private static OMNamespace getOMNamespace(QName qName) {
         return qName.getNamespaceURI().length() == 0 ? null
                 : new OMNamespaceImpl(qName.getNamespaceURI(), qName.getPrefix());
     }
     
+    public OMSourcedElementImpl(OMFactory factory, OMDataSource source) {
+        super(factory);
+        dataSource = source;
+        isExpanded = false;
+    }
+    
     /**
      * Constructor.
      *
@@ -102,19 +115,27 @@ public class OMSourcedElementImpl extend
      */
     public OMSourcedElementImpl(String localName, OMNamespace ns, OMFactory factory,
                                 OMDataSource source) {
-        super(localName, null, factory);
+        super(null, localName, null, null, factory, false);
         if (source == null) {
             throw new IllegalArgumentException("OMDataSource can't be null");
         }
         dataSource = source;
         isExpanded = false;
-        if (!isLossyPrefix(dataSource)) {
+        // Normalize the namespace. Note that this also covers the case where the
+        // namespace URI is empty and the prefix is null (in which case we know that
+        // the actual prefix must be empty)
+        if (ns != null && ns.getNamespaceURI().length() == 0) {
+            ns = null;
+        }
+        if (ns == null || !(isLossyPrefix(dataSource) || ns.getPrefix() == null)) {
             // Believe the prefix and create a normal OMNamespace
-            definedNamespace = normalize(ns);
+            definedNamespace = ns;
         } else {
             // Create a deferred namespace that forces an expand to get the prefix
-            definedNamespace = new DeferredNamespace(ns.getNamespaceURI());
+            String uri = ns.getNamespaceURI();
+            definedNamespace = new DeferredNamespace(uri);
         }
+        definedNamespaceSet = true;
     }
 
     /**
@@ -126,7 +147,7 @@ public class OMSourcedElementImpl extend
      */
     public OMSourcedElementImpl(QName qName, OMFactory factory, OMDataSource source) {
         //create a namespace
-        super(qName.getLocalPart(), null, factory);
+        super(null, qName.getLocalPart(), null, null, factory, false);
         if (source == null) {
             throw new IllegalArgumentException("OMDataSource can't be null");
         }
@@ -137,12 +158,14 @@ public class OMSourcedElementImpl extend
             definedNamespace = getOMNamespace(qName);
         } else {
             // Create a deferred namespace that forces an expand to get the prefix
-            definedNamespace = new DeferredNamespace(qName.getNamespaceURI());
+            String uri = qName.getNamespaceURI();
+            definedNamespace = uri.length() == 0 ? null : new DeferredNamespace(uri);
         }
+        definedNamespaceSet = true;
     }
 
     public OMSourcedElementImpl(String localName, OMNamespace ns, OMContainer parent, OMFactory factory) {
-        super(localName, null, parent, factory);
+        super(parent, localName, null, null, factory, false);
         dataSource = null;
         definedNamespace = ns;
         isExpanded = true;
@@ -151,27 +174,13 @@ public class OMSourcedElementImpl extend
         }
     }
 
-    public OMSourcedElementImpl(String localName, OMNamespace ns, OMContainer parent, OMXMLParserWrapper builder, OMFactory factory) {
-        super(localName, null, parent, builder, factory);
-        dataSource = null;
+    public OMSourcedElementImpl(OMContainer parent, String localName, OMNamespace ns,
+            OMXMLParserWrapper builder, OMFactory factory, boolean generateNSDecl) {
+        super(parent, localName, ns, builder, factory, generateNSDecl);
         definedNamespace = ns;
         isExpanded = true;
-        if (ns != null) {
-            this.setNamespace(ns);
-        }
     }
 
-    public OMSourcedElementImpl(String localName, OMNamespace ns, OMFactory factory) {
-        super(localName, null, factory);
-        dataSource = null;
-        definedNamespace = ns;
-        isExpanded = true;
-        if (ns != null) {
-            this.setNamespace(ns);
-        }
-    }
-    
-    
     /**
      * The namespace uri is immutable, but the OMDataSource may change
      * the value of the prefix.  This method queries the OMDataSource to 
@@ -188,21 +197,6 @@ public class OMSourcedElementImpl extend
         }
         return lossyPrefix == Boolean.TRUE;
     }
-    private void setDeferredNamespace(OMDataSource source, String uri, String prefix) {
-        Object lossyPrefix = null;
-        if (source instanceof OMDataSourceExt) {
-            lossyPrefix = 
-                ((OMDataSourceExt) source).getProperty(OMDataSourceExt.LOSSY_PREFIX);
-                        
-        }
-        if (lossyPrefix != Boolean.TRUE) {
-            // Believe the prefix and create a normal OMNamespace
-            definedNamespace = new OMNamespaceImpl(uri, prefix);
-        } else {
-            // Create a deferred namespace that forces an expand to get the prefix
-            definedNamespace = new DeferredNamespace(uri);
-        }
-    }
 
     /**
      * Generate element name for output.
@@ -210,36 +204,18 @@ public class OMSourcedElementImpl extend
      * @return name
      */
     private String getPrintableName() {
-        String uri = null;
-        if (getNamespace() != null) {
-            uri = getNamespace().getNamespaceURI();
-        }
-        if (uri == null || uri.length() == 0) {
-            return getLocalName();
-        } else {
-            return "{" + uri + '}' + getLocalName();
-        }
-    }
-
-    /**
-     * Get parser from data source. Note that getDataReader may consume the underlying data source.
-     *
-     * @return parser
-     */
-    private XMLStreamReader getDirectReader() {
-        try {
-            // If expansion has occurred, then the reader from the datasource is consumed or stale.
-            // In such cases use the stream reader from the OMElementImpl
-            if (isExpanded()) {
-                return super.getXMLStreamReader();
+        if (isExpanded || (definedNamespaceSet && localName != null)) {
+            String uri = null;
+            if (getNamespace() != null) {
+                uri = getNamespace().getNamespaceURI();
+            }
+            if (uri == null || uri.length() == 0) {
+                return getLocalName();
             } else {
-                return dataSource.getReader();  
+                return "{" + uri + '}' + getLocalName();
             }
-        } catch (XMLStreamException e) {
-            log.error("Could not get parser from data source for element " +
-                    getPrintableName(), e);
-            throw new RuntimeException("Error obtaining parser from data source:" +
-                    e.getMessage(), e);
+        } else {
+            return "<unknown>";
         }
     }
 
@@ -264,79 +240,98 @@ public class OMSourcedElementImpl extend
                 }
             }
 
-            // Get the XMLStreamReader
-            readerFromDS = getDirectReader();
-            
-            // Advance past the START_DOCUMENT to the start tag.
-            // Remember the character encoding.
-            String characterEncoding = readerFromDS.getCharacterEncodingScheme();
-            if (characterEncoding != null) {
-                characterEncoding = readerFromDS.getEncoding();
-            }
-            try {
-                if (readerFromDS.getEventType() != XMLStreamConstants.START_ELEMENT) {
-                    while (readerFromDS.next() != XMLStreamConstants.START_ELEMENT) ;
+            if (isPushDataSource()) {
+                // Set this before we start expanding; otherwise this would result in an infinite recursion
+                isExpanded = true;
+                try {
+                    dataSource.serialize(new PushOMBuilder(this));
+                } catch (XMLStreamException ex) {
+                    throw new OMException("Failed to expand data source", ex);
                 }
-            } catch (XMLStreamException e) {
-                log.error("forceExpand: error parsing data soruce document for element " +
-                        getLocalName(), e);
-                throw new RuntimeException("Error parsing data source document:" +
-                        e.getMessage(), e);
+            } else {
+                // Get the XMLStreamReader
+                try {
+                    readerFromDS = dataSource.getReader();  
+                } catch (XMLStreamException ex) {
+                    throw new OMException("Error obtaining parser from data source for element " + getPrintableName(), ex);
+                }
+                
+                // Advance past the START_DOCUMENT to the start tag.
+                // Remember the character encoding.
+                String characterEncoding = readerFromDS.getCharacterEncodingScheme();
+                if (characterEncoding != null) {
+                    characterEncoding = readerFromDS.getEncoding();
+                }
+                try {
+                    if (readerFromDS.getEventType() != XMLStreamConstants.START_ELEMENT) {
+                        while (readerFromDS.next() != XMLStreamConstants.START_ELEMENT) ;
+                    }
+                } catch (XMLStreamException ex) {
+                    throw new OMException("Error parsing data source document for element " + getLocalName(), ex);
+                }
+    
+                validateName(readerFromDS.getPrefix(), readerFromDS.getLocalName(), readerFromDS.getNamespaceURI());
+    
+                // Set the builder for this element. Note that the StAXOMBuilder constructor will also
+                // update the namespace of the element, so we don't need to do that here.
+                isExpanded = true;
+                super.setBuilder(new StAXOMBuilder(getOMFactory(), 
+                                                   readerFromDS, 
+                                                   this, 
+                                                   characterEncoding));
+                setComplete(false);
             }
+        }
+    }
+    
+    private boolean isPushDataSource() {
+        return dataSource instanceof AbstractPushOMDataSource;
+    }
 
+    /**
+     * Validates that the actual name of the element obtained from StAX matches the information
+     * specified when the sourced element was constructed or retrieved through the
+     * {@link QNameAwareOMDataSource} interface. Also updates the local name if necessary. Note that
+     * the namespace information is not updated; this is the responsibility of the builder (and is
+     * done at the same time as namespace repairing).
+     * 
+     * @param staxPrefix
+     * @param staxLocalName
+     * @param staxNamespaceURI
+     */
+    void validateName(String staxPrefix, String staxLocalName, String staxNamespaceURI) {
+        if (localName == null) {
+            // The local name was not known in advance; initialize it from the reader
+            localName = staxLocalName;
+        } else {
             // Make sure element local name and namespace matches what was expected
-            if (!readerFromDS.getLocalName().equals(getLocalName())) {
-                log.error("forceExpand: expected element name " +
-                        getLocalName() + ", found " + readerFromDS.getLocalName());
-                throw new RuntimeException("Element name from data source is " +
-                        readerFromDS.getLocalName() + ", not the expected " + getLocalName());
-            }
-            String readerURI = readerFromDS.getNamespaceURI();
-            readerURI = (readerURI == null) ? "" : readerURI;
-            String uri = (getNamespace() == null) ? "" : 
-                ((getNamespace().getNamespaceURI() == null) ? "" : getNamespace().getNamespaceURI());
-            if (!readerURI.equals(uri)) {
-                log.error("forceExpand: expected element namespace " +
-                        getLocalName() + ", found " + uri);
-                throw new RuntimeException("Element namespace from data source is " +
-                        readerURI + ", not the expected " + uri);
-            }
-
-            // Get the current prefix and the reader's prefix
-            String readerPrefix = readerFromDS.getPrefix();
-            readerPrefix = (readerPrefix == null) ? "" : readerPrefix;
-            String prefix = null;
-            
-            OMNamespace ns = getNamespace();
-            if (ns == null || ns instanceof DeferredNamespace) {
-                // prefix is not available until after expansion
-            } else {
-                prefix = ns.getPrefix();
+            if (!staxLocalName.equals(localName)) {
+                throw new OMException("Element name from data source is " +
+                        staxLocalName + ", not the expected " + localName);
             }
-            
-            // Set the builder for this element
-            isExpanded = true;
-            super.setBuilder(new StAXOMBuilder(getOMFactory(), 
-                                               readerFromDS, 
-                                               this, 
-                                               characterEncoding));
-            setComplete(false);
-
-            // Update the prefix if necessary.  This must be done after
-            // isParserSet to avoid a recursive call
-            if (!readerPrefix.equals(prefix) ||
-                 getNamespace() == null ||
-                 ns instanceof DeferredNamespace) {
-                if (log.isDebugEnabled()) {
-                    log.debug(
-                            "forceExpand: changing prefix from " + prefix + " to " + readerPrefix);
+        }
+        if (definedNamespaceSet) {
+            if (staxNamespaceURI == null) {
+                staxNamespaceURI = "";
+            }
+            String namespaceURI = definedNamespace == null ? "" : definedNamespace.getNamespaceURI();
+            if (!staxNamespaceURI.equals(namespaceURI)) {
+                throw new OMException("Element namespace from data source is " +
+                        staxNamespaceURI + ", not the expected " + namespaceURI);
+            }
+            if (!(definedNamespace instanceof DeferredNamespace)) {
+                if (staxPrefix == null) {
+                    staxPrefix = "";
+                }
+                String prefix = definedNamespace == null ? "" : definedNamespace.getPrefix();
+                if (!staxPrefix.equals(prefix)) {
+                    throw new OMException("Element prefix from data source is '" +
+                            staxPrefix + "', not the expected '" + prefix + "'");
                 }
-                setNamespace(new OMNamespaceImpl(readerURI, readerPrefix));
             }
-
         }
     }
-
+    
     /**
      * Check if element has been expanded into tree.
      *
@@ -375,6 +370,10 @@ public class OMSourcedElementImpl extend
         return super.addNamespaceDeclaration(uri, prefix);
     }
 
+    void addNamespaceDeclaration(OMNamespace ns) {
+        super.addNamespaceDeclaration(ns);
+    }
+
     public void undeclarePrefix(String prefix) {
         forceExpand();
         super.undeclarePrefix(prefix);
@@ -430,6 +429,10 @@ public class OMSourcedElementImpl extend
         return super.addAttribute(attributeName, value, namespace);
     }
 
+    void appendAttribute(OMAttribute attr) {
+        super.appendAttribute(attr);
+    }
+
     public void removeAttribute(OMAttribute attr) {
         forceExpand();
         super.removeAttribute(attr);
@@ -472,11 +475,16 @@ public class OMSourcedElementImpl extend
         if (isExpanded) {
             return super.getXMLStreamReader(cache, configuration);
         } else {
-            if (cache && isDestructiveRead()) {
+            if ((cache && isDestructiveRead()) || isPushDataSource()) {
                 forceExpand();
                 return super.getXMLStreamReader(true, configuration);
+            } else {
+                try {
+                    return dataSource.getReader();  
+                } catch (XMLStreamException ex) {
+                    throw new OMException("Error obtaining parser from data source for element " + getPrintableName(), ex);
+                }
             }
-            return getDirectReader();
         }
     }
 
@@ -516,21 +524,64 @@ public class OMSourcedElementImpl extend
         super.writeTextTo(out, cache);
     }
 
+    private void ensureLocalNameSet() {
+        if (localName == null) {
+            if (dataSource instanceof QNameAwareOMDataSource) {
+                localName = ((QNameAwareOMDataSource)dataSource).getLocalName();
+            }
+            if (localName == null) {
+                forceExpand();
+            }
+        }
+    }
+    
     public String getLocalName() {
-        // no need to set the parser, just call base method directly
+        ensureLocalNameSet();
         return super.getLocalName();
     }
 
     public void setLocalName(String localName) {
-        // no need to expand the tree, just call base method directly
+        // Need to expand the element so that the method actually overrides the the local name
+        forceExpand();
         super.setLocalName(localName);
     }
 
     public OMNamespace getNamespace() throws OMException {
         if (isExpanded()) {
             return super.getNamespace();
+        } else if (definedNamespaceSet) {
+            return definedNamespace;
+        } else {
+            if (dataSource instanceof QNameAwareOMDataSource) {
+                String namespaceURI = ((QNameAwareOMDataSource)dataSource).getNamespaceURI();
+                if (namespaceURI != null) {
+                    if (namespaceURI.length() == 0) {
+                        // No namespace case. definedNamespace is already null, so we only need
+                        // to set definedNamespaceSet to true. Note that we don't need to retrieve
+                        // the namespace prefix because a prefix can't be bound to the empty
+                        // namespace URI.
+                        definedNamespaceSet = true;
+                    } else {
+                        String prefix = ((QNameAwareOMDataSource)dataSource).getPrefix();
+                        if (prefix == null) {
+                            // Prefix is unknown
+                            definedNamespace = new DeferredNamespace(namespaceURI);
+                        } else {
+                            definedNamespace = new OMNamespaceImpl(namespaceURI, prefix);
+                        }
+                        definedNamespaceSet = true;
+                    }
+                }
+            }
+            if (definedNamespaceSet) {
+                return definedNamespace;
+            } else {
+                // We have no information about the namespace of the element. Need to expand
+                // the element to get it.
+                forceExpand();
+                return super.getNamespace();
+            }
         }
-        return definedNamespace;
     }
 
     public String getPrefix() {
@@ -596,10 +647,64 @@ public class OMSourcedElementImpl extend
     }
 
     public OMElement cloneOMElement() {
-        forceExpand();
         return super.cloneOMElement();
     }
 
+    public OMElement cloneOMElement(OMCloneOptions options) {
+        return super.cloneOMElement(options);
+    }
+
+    OMNode clone(OMCloneOptions options, OMContainer targetParent) {
+        // If already expanded or this is not an OMDataSourceExt, then
+        // create a copy of the OM Tree
+        OMDataSource ds = getDataSource();
+        if (!options.isCopyOMDataSources() ||
+            ds == null || 
+            isExpanded() || 
+            !(ds instanceof OMDataSourceExt)) {
+            return super.clone(options, targetParent);
+        }
+        
+        // If copying is destructive, then copy the OM tree
+        OMDataSourceExt sourceDS = (OMDataSourceExt) ds;
+        if (sourceDS.isDestructiveRead() ||
+            sourceDS.isDestructiveWrite()) {
+            return super.clone(options, targetParent);
+        }
+        OMDataSourceExt targetDS = ((OMDataSourceExt) ds).copy();
+        if (targetDS == null) {
+            return super.clone(options, targetParent);
+        }
+        // Otherwise create a target OMSE with the copied DataSource
+        OMSourcedElementImpl targetOMSE;
+        if (options.isPreserveModel()) {
+            targetOMSE = (OMSourcedElementImpl)createClone(options, targetDS);
+        } else {
+            targetOMSE = (OMSourcedElementImpl)factory.createOMElement(targetDS);
+        }
+        
+        targetOMSE.localName = localName;
+        targetOMSE.definedNamespaceSet = definedNamespaceSet;
+        if (definedNamespace instanceof DeferredNamespace) {
+            targetOMSE.definedNamespace = targetOMSE.new DeferredNamespace(definedNamespace.getNamespaceURI());
+        } else {
+            targetOMSE.definedNamespace = definedNamespace;
+        }
+        
+        if (targetParent != null) {
+            targetParent.addChild(targetOMSE);
+        }
+        return targetOMSE;
+    }
+
+    protected OMElement createClone(OMCloneOptions options, OMContainer targetParent) {
+        return super.createClone(options, targetParent);
+    }
+    
+    protected OMSourcedElement createClone(OMCloneOptions options, OMDataSource ds) {
+        return factory.createOMElement(ds);
+    }
+
     public void setLineNumber(int lineNumber) {
         // no need to expand the tree, just call base method directly
         super.setLineNumber(lineNumber);
@@ -734,6 +839,11 @@ public class OMSourcedElementImpl extend
         super.addChild(omNode);
     }
 
+    public void addChild(OMNode omNode, boolean fromBuilder) {
+        forceExpand();
+        super.addChild(omNode, fromBuilder);
+    }
+
     public Iterator getChildrenWithName(QName elementQName) {
         forceExpand();
         return super.getChildrenWithName(elementQName);
@@ -773,6 +883,10 @@ public class OMSourcedElementImpl extend
         return super.getFirstOMChildIfAvailable();
     }
 
+    public OMNode getLastKnownOMChild() {
+        return super.getLastKnownOMChild();
+    }
+
     public void buildNext() {
         forceExpand();
         super.buildNext();
@@ -968,7 +1082,8 @@ public class OMSourcedElementImpl extend
             if (!isExpanded()) {
                 forceExpand();
             }
-            return getNamespace().getPrefix();
+            OMNamespace actualNS = getNamespace();
+            return actualNS == null ? "" : actualNS.getPrefix();
         }
         
         public int hashCode() {
@@ -989,4 +1104,12 @@ public class OMSourcedElementImpl extend
         }
         
     }
+
+    public Object getObject(Class dataSourceClass) {
+        if (dataSource == null || isExpanded || !dataSourceClass.isInstance(dataSource)) {
+            return null;
+        } else {
+            return ((OMDataSourceExt)dataSource).getObject();
+        }
+    }
 }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java Sat Jul  7 18:24:00 2012
@@ -20,14 +20,15 @@
 package org.apache.axiom.om.impl.llom;
 
 import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.om.OMCloneOptions;
 import org.apache.axiom.om.OMConstants;
 import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMText;
-import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
 import org.apache.axiom.util.UIDGenerator;
 import org.apache.axiom.util.base64.Base64Utils;
@@ -40,11 +41,13 @@ import javax.xml.stream.XMLStreamWriter;
 import java.io.IOException;
 import java.io.InputStream;
 
-public class OMTextImpl extends OMNodeImpl implements OMText, OMConstants {
+public class OMTextImpl extends OMLeafNode implements OMText, OMConstants {
     /** Field nameSpace used when serializing Binary stuff as MTOM optimized. */
     public static final OMNamespace XOP_NS = new OMNamespaceImpl(
             "http://www.w3.org/2004/08/xop/include", "xop");
 
+    private int nodeType;
+
     protected String value = null;
     protected char[] charArray;
 
@@ -83,7 +86,7 @@ public class OMTextImpl extends OMNodeIm
      *                 Constants for this can be found in OMNode.
      */
     public OMTextImpl(String s, int nodeType, OMFactory factory) {
-        this(null, s, nodeType, factory);
+        this(null, s, nodeType, factory, false);
     }
 
     /**
@@ -93,7 +96,7 @@ public class OMTextImpl extends OMNodeIm
      * @param text
      */
     public OMTextImpl(OMContainer parent, String text, OMFactory factory) {
-        this(parent, text, TEXT_NODE, factory);
+        this(parent, text, TEXT_NODE, factory, false);
     }
     
     /**
@@ -103,7 +106,7 @@ public class OMTextImpl extends OMNodeIm
      * @param factory
      */
     public OMTextImpl(OMContainer parent, OMTextImpl source, OMFactory factory) {
-        super(parent, factory, true);
+        super(parent, factory, false);
         // Copy the value of the text
         this.value = source.value;
         this.nodeType = source.nodeType;
@@ -131,15 +134,15 @@ public class OMTextImpl extends OMNodeIm
     }
 
     public OMTextImpl(OMContainer parent, String text, int nodeType,
-                      OMFactory factory) {
-        super(parent, factory, true);
+                      OMFactory factory, boolean fromBuilder) {
+        super(parent, factory, fromBuilder);
         this.value = text == null ? EMTPY_STRING : text;
         this.nodeType = nodeType;
     }
 
     public OMTextImpl(OMContainer parent, char[] charArray, int nodeType,
                       OMFactory factory) {
-        super(parent, factory, true);
+        super(parent, factory, false);
         this.charArray = charArray;
         this.nodeType = nodeType;
     }
@@ -151,7 +154,7 @@ public class OMTextImpl extends OMNodeIm
 
     public OMTextImpl(OMContainer parent, QName text, int nodeType,
                       OMFactory factory) {
-        super(parent, factory, true);
+        super(parent, factory, false);
         if (text == null) throw new IllegalArgumentException("QName text arg cannot be null!");
         this.calcNS = true;
         this.textNS =
@@ -180,25 +183,23 @@ public class OMTextImpl extends OMNodeIm
         this.mimeType = mimeType;
         this.optimize = optimize;
         this.isBinary = true;
-        done = true;
         this.nodeType = TEXT_NODE;
     }
 
     /** @param dataHandler To send binary optimised content Created programatically. */
     public OMTextImpl(Object dataHandler, OMFactory factory) {
-        this(dataHandler, true, factory);
+        this(null, dataHandler, true, factory, false);
     }
 
     /**
      * @param dataHandler
      * @param optimize    To send binary content. Created progrmatically.
      */
-    public OMTextImpl(Object dataHandler, boolean optimize, OMFactory factory) {
-        super(factory);
+    public OMTextImpl(OMContainer parent, Object dataHandler, boolean optimize, OMFactory factory, boolean fromBuilder) {
+        super(parent, factory, fromBuilder);
         this.dataHandlerObject = dataHandler;
         this.isBinary = true;
         this.optimize = optimize;
-        done = true;
         this.nodeType = TEXT_NODE;
     }
 
@@ -216,25 +217,11 @@ public class OMTextImpl extends OMNodeIm
         dataHandlerObject = dataHandlerProvider;
         isBinary = true;
         this.optimize = optimize;
-        done = true;
         nodeType = TEXT_NODE;
     }
 
-    /**
-     * @param contentID
-     * @param parent
-     * @param builder   Used when the builder is encountered with a XOP:Include tag Stores a
-     *                  reference to the builder and the content-id. Supports deferred parsing of
-     *                  MIME messages.
-     */
-    public OMTextImpl(String contentID, OMContainer parent,
-                      OMXMLParserWrapper builder, OMFactory factory) {
-        super(parent, factory, false);
-        this.contentID = contentID;
-        this.optimize = true;
-        this.isBinary = true;
-        this.builder = builder;
-        this.nodeType = TEXT_NODE;
+    public final int getType() {
+        return nodeType;
     }
 
     /**
@@ -413,24 +400,10 @@ public class OMTextImpl extends OMNodeIm
         }
     }
 
-    /**
-     * A slightly different implementation of the discard method.
-     *
-     * @throws OMException
-     */
-    public void discard() throws OMException {
-        if (done) {
-            this.detach();
-        } 
-    }
-
     /* (non-Javadoc)
       * @see org.apache.axiom.om.OMNode#buildAll()
       */
     public void buildWithAttachments() {
-        if (!this.done) {
-            this.build();
-        }
         if (isOptimized()) {
             // The call to getDataSource ensures that the MIME part is completely read
             ((DataHandler)this.getDataHandler()).getDataSource();
@@ -441,4 +414,12 @@ public class OMTextImpl extends OMNodeIm
         this.contentID = cid;
     }
 
+    OMNode clone(OMCloneOptions options, OMContainer targetParent) {
+        if (isBinary && options.isFetchDataHandlers()) {
+            // Force loading of the reference to the DataHandler and ensure that its content is
+            // completely fetched into memory (or temporary storage).
+            ((DataHandler)getDataHandler()).getDataSource();
+        }
+        return factory.createOMText(targetParent, this);
+    }
 }

Modified: webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java?rev=1358610&r1=1358609&r2=1358610&view=diff
==============================================================================
--- webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java (original)
+++ webservices/axiom/branches/AXIOM-201/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java Sat Jul  7 18:24:00 2012
@@ -28,13 +28,15 @@ import org.apache.axiom.om.OMDocType;
 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.OMMetaFactory;
 import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMProcessingInstruction;
 import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.impl.builder.OMFactoryEx;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
 import org.apache.axiom.om.impl.llom.OMAttributeImpl;
 import org.apache.axiom.om.impl.llom.OMCommentImpl;
@@ -50,7 +52,7 @@ import javax.xml.namespace.QName;
 
 /** Class OMLinkedListImplFactory
  */
-public class OMLinkedListImplFactory implements OMFactory {
+public class OMLinkedListImplFactory implements OMFactoryEx {
     private final OMLinkedListMetaFactory metaFactory;
     
     public OMLinkedListImplFactory(OMLinkedListMetaFactory metaFactory) {
@@ -73,27 +75,24 @@ public class OMLinkedListImplFactory imp
      * @return Returns OMElement.
      */
     public OMElement createOMElement(String localName, OMNamespace ns) {
-        return new OMElementImpl(localName, ns, this);
+        return new OMElementImpl(null, localName, ns, null, this, true);
     }
 
     public OMElement createOMElement(String localName, OMNamespace ns, OMContainer parent) {
-        return new OMElementImpl(localName, ns, parent, this);
+        return new OMElementImpl(parent, localName, ns, null, this, true);
     }
 
     /**
      * Method createOMElement.
      *
      * @param localName
-     * @param ns
      * @param parent
      * @param builder
      * @return Returns OMElement.
      */
-    public OMElement createOMElement(String localName, OMNamespace ns,
-                                     OMContainer parent,
+    public OMElement createOMElement(String localName, OMContainer parent,
                                      OMXMLParserWrapper builder) {
-        return new OMElementImpl(localName, ns, parent,
-                                 builder, this);
+        return new OMElementImpl(parent, localName, null, builder, this, false);
     }
 
     public OMElement createOMElement(String localName, String namespaceURI, String prefix) {
@@ -140,6 +139,10 @@ public class OMLinkedListImplFactory imp
         return new OMElementImpl(qname, null, this);
     }
 
+    public OMSourcedElement createOMElement(OMDataSource source) {
+        return new OMSourcedElementImpl(this, source);
+    }
+
     /**
      * Construct element with arbitrary data source.
      *
@@ -188,7 +191,11 @@ public class OMLinkedListImplFactory imp
     }
 
     public OMText createOMText(OMContainer parent, String text, int type) {
-        return new OMTextImpl(parent, text, type, this);
+        return createOMText(parent, text, type, false);
+    }
+
+    public OMText createOMText(OMContainer parent, String text, int type, boolean fromBuilder) {
+        return new OMTextImpl(parent, text, type, this, fromBuilder);
     }
 
     public OMText createOMText(OMContainer parent, char[] charArary, int type) {
@@ -233,7 +240,11 @@ public class OMLinkedListImplFactory imp
      * @return Returns OMText.
      */
     public OMText createOMText(Object dataHandler, boolean optimize) {
-        return new OMTextImpl(dataHandler, optimize, this);
+        return createOMText(null, dataHandler, optimize, false);
+    }
+
+    public OMText createOMText(OMContainer parent, Object dataHandler, boolean optimize, boolean fromBuilder) {
+        return new OMTextImpl(parent, dataHandler, optimize, this, fromBuilder);
     }
 
     public OMText createOMText(String contentID, DataHandlerProvider dataHandlerProvider,
@@ -241,11 +252,6 @@ public class OMLinkedListImplFactory imp
         return new OMTextImpl(contentID, dataHandlerProvider, optimize, this);
     }
 
-    public OMText createOMText(String contentID, OMContainer parent,
-                               OMXMLParserWrapper builder) {
-        return new OMTextImpl(contentID, parent, builder, this);
-    }
-    
     public OMText createOMText(OMContainer parent, OMText source) {
         return new OMTextImpl(parent, (OMTextImpl) source, this);
     }
@@ -296,7 +302,11 @@ public class OMLinkedListImplFactory imp
      * @return Returns doctype.
      */
     public OMDocType createOMDocType(OMContainer parent, String content) {
-        return new OMDocTypeImpl(parent, content, this);
+        return createOMDocType(parent, content, false);
+    }
+
+    public OMDocType createOMDocType(OMContainer parent, String content, boolean fromBuilder) {
+        return new OMDocTypeImpl(parent, content, this, fromBuilder);
     }
 
     /**
@@ -309,7 +319,12 @@ public class OMLinkedListImplFactory imp
      */
     public OMProcessingInstruction createOMProcessingInstruction(OMContainer parent,
                                                                  String piTarget, String piData) {
-        return new OMProcessingInstructionImpl(parent, piTarget, piData, this);
+        return createOMProcessingInstruction(parent, piTarget, piData, false);
+    }
+
+    public OMProcessingInstruction createOMProcessingInstruction(OMContainer parent,
+            String piTarget, String piData, boolean fromBuilder) {
+        return new OMProcessingInstructionImpl(parent, piTarget, piData, this, fromBuilder);
     }
 
     /**
@@ -320,7 +335,11 @@ public class OMLinkedListImplFactory imp
      * @return Returns OMComment.
      */
     public OMComment createOMComment(OMContainer parent, String content) {
-        return new OMCommentImpl(parent, content, this);
+        return createOMComment(parent, content, false);
+    }
+
+    public OMComment createOMComment(OMContainer parent, String content, boolean fromBuilder) {
+        return new OMCommentImpl(parent, content, this, fromBuilder);
     }
 
     /* (non-Javadoc)
@@ -336,4 +355,58 @@ public class OMLinkedListImplFactory imp
     public OMDocument createOMDocument(OMXMLParserWrapper builder) {
         return new OMDocumentImpl(builder, this);
     }
+
+    /**
+     * This method is intended only to be used by Axiom intenals when merging Objects from different
+     * Axiom implementations to the LLOM implementation.
+     *
+     * @param child
+     */
+    public OMNode importNode(OMNode child) {
+        int type = child.getType();
+        switch (type) {
+            case (OMNode.ELEMENT_NODE): {
+                OMElement childElement = (OMElement) child;
+                OMElement newElement = (new StAXOMBuilder(this, childElement
+                        .getXMLStreamReader())).getDocumentElement();
+                newElement.buildWithAttachments();
+                return newElement;
+            }
+            case (OMNode.TEXT_NODE): {
+                OMText importedText = (OMText) child;
+                OMText newText;
+                if (importedText.isBinary()) {
+                    boolean isOptimize = importedText.isOptimized();
+                    newText = createOMText(importedText
+                            .getDataHandler(), isOptimize);
+                } else if (importedText.isCharacters()) {
+                    newText = createOMText(null, importedText
+                            .getTextCharacters(), importedText.getType());
+                } else {
+                    newText = createOMText(null, importedText
+                            .getText()/*, importedText.getOMNodeType()*/);
+                }
+                return newText;
+            }
+
+            case (OMNode.PI_NODE): {
+                OMProcessingInstruction importedPI = (OMProcessingInstruction) child;
+                return createOMProcessingInstruction(null,
+                                                                  importedPI.getTarget(),
+                                                                  importedPI.getValue());
+            }
+            case (OMNode.COMMENT_NODE): {
+                OMComment importedComment = (OMComment) child;
+                return createOMComment(null, importedComment.getValue());
+            }
+            case (OMNode.DTD_NODE) : {
+                OMDocType importedDocType = (OMDocType) child;
+                return createOMDocType(null, importedDocType.getValue());
+            }
+            default: {
+                throw new UnsupportedOperationException(
+                        "Not Implemented Yet for the given node type");
+            }
+        }
+    }
 }