You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by sc...@apache.org on 2007/08/19 14:43:00 UTC

svn commit: r567394 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/om/ axiom-api/src/main/java/org/apache/axiom/om/util/ axiom-api/src/main/java/org/apache/axiom/soap/ axiom-dom/src/main/java/org/apache/...

Author: scheu
Date: Sun Aug 19 05:42:58 2007
New Revision: 567394

URL: http://svn.apache.org/viewvc?view=rev&rev=567394
Log:
WSCOMMONS-236
Introduce CopyUtils code that makes a copy of an OM Tree
Contributor:Rich Scheuerle

Summary of Changes: 
1) Added CopyUtils class.
2) Added tests that validate the processing of CopyUtils.
3) Minor changes to factory classes 
3a) Added createSOAPEnvelope(OMNamespace).  This is necessary to pass the soap envelope's prefix.
3b) Added createOMText(OMContainer, OMText).  This is necessary to create a text node that is a copy of another text node.

Follow-on: 
I will be changing the SandeshaUtils code to delegate to this new utility class.  See the JIRA.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/CopyUtils.java
    webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/CopyUtilsTest.java
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/factory/DOMSOAPFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap11/SOAP11Factory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap12/SOAP12Factory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java Sun Aug 19 05:42:58 2007
@@ -116,6 +116,14 @@
     OMText createOMText(OMContainer parent, String text);
 
     /**
+     * Create OMText node that is a copy of the source text node
+     * @param parent
+     * @param source
+     * @return
+     */
+    public OMText createOMText(OMContainer parent, OMText source);
+    
+    /**
      * @param parent
      * @param text   - This text itself can contain a namespace inside it.
      */

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/CopyUtils.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/CopyUtils.java?view=auto&rev=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/CopyUtils.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/CopyUtils.java Sun Aug 19 05:42:58 2007
@@ -0,0 +1,505 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om.util;
+
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMComment;
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMSourcedElement;
+import org.apache.axiom.om.OMText;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.SOAPFault;
+import org.apache.axiom.soap.SOAPFaultCode;
+import org.apache.axiom.soap.SOAPFaultDetail;
+import org.apache.axiom.soap.SOAPFaultNode;
+import org.apache.axiom.soap.SOAPFaultReason;
+import org.apache.axiom.soap.SOAPFaultRole;
+import org.apache.axiom.soap.SOAPFaultSubCode;
+import org.apache.axiom.soap.SOAPFaultText;
+import org.apache.axiom.soap.SOAPFaultValue;
+import org.apache.axiom.soap.SOAPHeader;
+import org.apache.axiom.soap.SOAPHeaderBlock;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import java.util.Iterator;
+
+/**
+ * CopyUtils provides static utility methods that are useful for creating a copy of 
+ * an OM/SOAPEnvelope tree.  
+ * During the expansion, the Source tree retains its shape
+ * (OMSourcedElement nodes are not expanded).  
+ * The Target tree has nodes that retain the class identity of the source node.  For 
+ * example, a SOAPFault in the source tree will have a SOAPFault in the target tree.
+ */
+public class CopyUtils {
+
+
+    /**
+     * Private Constructor
+     */
+    private CopyUtils() {
+    }
+
+
+    /**
+     * Creates a copy of the source envelope.
+     * If there are OMSourcedElements in the source tree, 
+     * similar MSourcedElements are used in the target tree.
+     *
+     * @param sourceEnv
+     * @return targetEnv
+     */
+    public static SOAPEnvelope copy(SOAPEnvelope sourceEnv) {
+
+        SOAPFactory factory = (SOAPFactory) sourceEnv.getOMFactory();
+        // Create envelope with the same prefix
+        SOAPEnvelope targetEnv = factory.createSOAPEnvelope(sourceEnv.getNamespace());
+
+        // Copy the attributes and namespaces from the source
+        // envelope to the target envelope.
+        copyTagData(sourceEnv, targetEnv);
+
+        Iterator i = sourceEnv.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            if (node instanceof SOAPHeader) {
+                // Copy the SOAPHeader tree
+                SOAPHeader targetHeader = factory.createSOAPHeader(targetEnv);
+                Iterator j = ((SOAPHeader)node).getChildren();
+                while (j.hasNext()) {
+                    OMNode child = (OMNode) j.next();
+                    copy(factory, targetHeader, child);
+                }
+            } else if (node instanceof SOAPBody) {
+                // Copy the SOAPBody tree
+                SOAPBody targetBody = factory.createSOAPBody(targetEnv);
+                Iterator j = ((SOAPBody)node).getChildren();
+                while (j.hasNext()) {
+                    OMNode child = (OMNode) j.next();
+                    copy(factory, targetBody, child);
+                }
+                
+            } else {
+                // Comments, text, etc.
+                copy(factory, targetEnv, node);
+            }  
+        }
+
+        return targetEnv;
+    }
+
+    /**
+     * Simple utility that takes an XMLStreamReader and writes it
+     * to an XMLStreamWriter
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
+     */
+    public static void reader2writer(XMLStreamReader reader, 
+                                     XMLStreamWriter writer)
+    throws XMLStreamException {
+        StAXOMBuilder builder = new StAXOMBuilder(reader);
+        builder.releaseParserOnClose(true);
+        try {
+            OMDocument omDocument = builder.getDocument();
+            Iterator it = omDocument.getChildren();
+            while (it.hasNext()) {
+                OMNode omNode = (OMNode) it.next();
+                omNode.serializeAndConsume(writer);
+            }
+        } finally {
+            builder.close();
+        }
+    }
+
+    /**
+     * Create a copy of the sourceNode and attach it to the targetParent
+     * @param factory OMFactory
+     * @param targetParent
+     * @param sourceNode
+     */
+    private static void copy(SOAPFactory factory, 
+                             OMContainer targetParent, 
+                             OMNode sourceNode) {
+
+        // Create and attach a node of the same class
+        // TODO It would be nice if you could do this directly from the
+        // OMNode, but OMNode.clone() does not gurantee that an object of the correct
+        // class is created.
+        if (sourceNode instanceof SOAPHeaderBlock) {
+            copySOAPHeaderBlock(factory, targetParent, (SOAPHeaderBlock) sourceNode);
+        } else if (sourceNode instanceof SOAPFault) {
+            copySOAPFault(factory, targetParent, (SOAPFault) sourceNode);
+        } else if (sourceNode instanceof OMSourcedElement) {
+            copyOMSourcedElement(factory, targetParent, (OMSourcedElement) sourceNode);
+        } else if (sourceNode instanceof OMElement) {
+            copyOMElement(factory, targetParent, (OMElement) sourceNode);
+        } else if (sourceNode instanceof OMText) {
+            copyOMText(factory, targetParent, (OMText) sourceNode);
+        } else if (sourceNode instanceof OMComment) {
+            copyOMComment(factory, targetParent, (OMComment) sourceNode);
+        } else {
+            throw new OMException("Internal Failure: Cannot make a copy of "
+                    + sourceNode.getClass().getCanonicalName());
+        }
+    }
+
+    /**
+     * Create a copy of the source OMComment
+     * @param factory
+     * @param targetParent
+     * @param sourceComment
+     */
+    private static void copyOMComment(SOAPFactory factory, 
+                                      OMContainer targetParent, 
+                                      OMComment sourceComment) {
+        // Create and attach the comment
+        factory.createOMComment(targetParent, sourceComment.getValue());
+    }
+
+    /**
+     * Create a copy of the OM Text
+     * @param factory
+     * @param targetParent
+     * @param sourceText
+     */
+    private static void copyOMText(SOAPFactory factory, 
+                                   OMContainer targetParent, 
+                                   OMText sourceText) {
+        factory.createOMText(targetParent, sourceText);
+    }
+
+    /**
+     * Create a copy of an ordinary OMElement
+     * @param factory
+     * @param targetParent
+     * @param sourceElement
+     */
+    private static void copyOMElement(SOAPFactory factory, 
+                                      OMContainer targetParent, 
+                                      OMElement sourceElement) {
+        // Clone and attach the OMElement.
+        // REVIEW This clone will expand the underlying tree.  We may want consider traversing
+        // a few levels deeper to see if there are any additional OMSourcedElements.
+        targetParent.addChild(sourceElement.cloneOMElement());
+    }
+
+    /**
+     * Create a copy of the OMSourcedElement
+     * @param factory
+     * @param targetParent
+     * @param sourceOMSE
+     */
+    private static void copyOMSourcedElement(SOAPFactory factory, 
+                                             OMContainer targetParent,
+                                             OMSourcedElement sourceOMSE) {
+        // If already expanded or this is not an OMDataSourceExt, then
+        // create a copy of the OM Tree
+        OMDataSource ds = sourceOMSE.getDataSource();
+        if (ds == null || 
+            sourceOMSE.isExpanded() || 
+            !(ds instanceof OMDataSourceExt)) {
+            copyOMElement(factory, targetParent, sourceOMSE);
+            return;
+        }
+        
+        // If copying is destructive, then copy the OM tree
+        OMDataSourceExt sourceDS = (OMDataSourceExt) ds;
+        if (sourceDS.isDestructiveRead() ||
+            sourceDS.isDestructiveWrite()) {
+            copyOMElement(factory, targetParent, sourceOMSE);
+            return;
+        }
+        
+        // Otherwise create a copy of the OMDataSource
+        OMDataSourceExt targetDS = ((OMDataSourceExt) ds).copy();
+        OMSourcedElement targetOMSE =
+            factory.createOMElement(targetDS, 
+                                    sourceOMSE.getLocalName(), 
+                                    sourceOMSE.getNamespace());
+        targetParent.addChild(targetOMSE);
+
+    }
+
+    /**
+     * Create a copy of the SOAPHeaderBlock
+     * @param factory
+     * @param targetParent
+     * @param sourceSHB
+     */
+    private static void copySOAPHeaderBlock(SOAPFactory factory, 
+                                            OMContainer targetParent,
+                                            SOAPHeaderBlock sourceSHB) {
+        
+        // TODO We need to consider the case where the 
+        // the SOAPHeaderBlock is also an OMSourcedElement
+        SOAPHeader header = (SOAPHeader) targetParent;
+        String localName = sourceSHB.getLocalName();
+        OMNamespace ns = sourceSHB.getNamespace();
+        SOAPHeaderBlock targetSHB = factory.createSOAPHeaderBlock(localName, ns, header);
+        
+        // A SOAPHeaderBlock has tag data, plus extra header processing flags
+        copyTagData(sourceSHB, targetSHB);
+        copySOAPHeaderBlockData(sourceSHB, targetSHB);
+        Iterator i = sourceSHB.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            copy(factory, targetSHB, node);
+        }
+    }
+
+    /**
+     * Create a copy of a SOAPFault
+     * @param factory
+     * @param targetParent
+     * @param sourceSOAPFault
+     */
+    private static void copySOAPFault(SOAPFactory factory, 
+                                      OMContainer targetParent,
+                                      SOAPFault sourceSOAPFault) {
+        Exception e = sourceSOAPFault.getException();
+        
+        SOAPFault newSOAPFault = (e == null) ?
+                    factory.createSOAPFault((SOAPBody) targetParent):
+                    factory.createSOAPFault((SOAPBody) targetParent, e);
+                                        
+        copyTagData(sourceSOAPFault, newSOAPFault);
+        Iterator i = sourceSOAPFault.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            // Copy the tree under the SOAPFault
+            copyFaultData(factory, newSOAPFault, node);
+        }
+    }
+
+    /**
+     * Copy the source Node, which is a child fo a SOAPFault,
+     * to the target SOAPFault
+     * @param factory
+     * @param targetFault
+     * @param sourceNode
+     */
+    private static void copyFaultData(SOAPFactory factory, 
+                                      SOAPFault targetFault, 
+                                      OMNode sourceNode) {
+
+        if (sourceNode instanceof SOAPFaultCode) {
+            copySOAPFaultCode(factory, targetFault, (SOAPFaultCode) sourceNode);
+        } else if (sourceNode instanceof SOAPFaultDetail) {
+            copySOAPFaultDetail(factory, targetFault, (SOAPFaultDetail) sourceNode);
+        } else if (sourceNode instanceof SOAPFaultNode) {
+            copySOAPFaultNode(factory, targetFault, (SOAPFaultNode) sourceNode);
+        } else if (sourceNode instanceof SOAPFaultReason) {
+            copySOAPFaultReason(factory, targetFault, (SOAPFaultReason) sourceNode);
+        } else if (sourceNode instanceof SOAPFaultRole) {
+            copySOAPFaultRole(factory, targetFault, (SOAPFaultRole) sourceNode);
+        } else if (sourceNode instanceof OMText) {
+            copyOMText(factory, targetFault, (OMText) sourceNode);
+        } else if (sourceNode instanceof OMComment) {
+            copyOMComment(factory, targetFault, (OMComment) sourceNode);
+        } else {
+            throw new OMException("Internal Failure: Cannot make a copy of "
+                    + sourceNode.getClass().getCanonicalName() + " object found in a SOAPFault.");
+        }
+    }
+
+    /**
+     * Create a copy of a SOAPFaultRole
+     * @param factory
+     * @param targetFault
+     * @param sourceRole
+     */
+    private static void copySOAPFaultRole(SOAPFactory factory, 
+                                          SOAPFault targetFault, 
+                                          SOAPFaultRole sourceRole) {
+        SOAPFaultRole targetRole = factory.createSOAPFaultRole(targetFault);
+        copyTagData(sourceRole, targetRole);
+        targetRole.setRoleValue(sourceRole.getRoleValue());
+    }
+
+    /**
+     * Create a copy of a SOAPFaultNode
+     * @param factory
+     * @param targetFault
+     * @param sourceNode
+     */
+    private static void copySOAPFaultNode(SOAPFactory factory, 
+                                          SOAPFault targetFault, 
+                                          SOAPFaultNode sourceNode) {
+        SOAPFaultNode targetNode = factory.createSOAPFaultNode(targetFault);
+        copyTagData(sourceNode, targetNode);
+        targetNode.setNodeValue(sourceNode.getNodeValue());
+    }
+
+    /**
+     * Create a copy of a SOAPFaultDetail
+     * @param factory
+     * @param targetFault
+     * @param sourceDetail
+     */
+    private static void copySOAPFaultDetail(SOAPFactory factory, 
+                                            SOAPFault targetFault,
+                                            SOAPFaultDetail sourceDetail) {
+        SOAPFaultDetail targetDetail = factory.createSOAPFaultDetail(targetFault);
+        copyTagData(sourceDetail, targetDetail);
+        
+        // Copy the detail entries
+        Iterator i = sourceDetail.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            copy(factory, targetDetail, node);
+        }
+    }
+
+    /**
+     * Create a copy of the SOAPFaultReason
+     * @param factory
+     * @param targetFault
+     * @param sourceReason
+     */
+    private static void copySOAPFaultReason(SOAPFactory factory, 
+                                            SOAPFault targetFault,
+                                            SOAPFaultReason sourceReason) {
+        SOAPFaultReason targetReason = factory.createSOAPFaultReason(targetFault);
+        copyTagData(sourceReason, targetReason);
+        Iterator i = sourceReason.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            if (node instanceof SOAPFaultText) {
+                SOAPFaultText oldText = (SOAPFaultText) node;
+                SOAPFaultText newText = factory.createSOAPFaultText(targetReason);
+                copyTagData(oldText, newText); // The lang is copied as an attribute
+            } else {
+                // Copy any comments or child nodes
+                copy(factory, targetReason, node);
+            }
+        }
+    }
+
+    /**
+     * Copy the SOAPFaultCode tree
+     * @param factory
+     * @param targetFault
+     * @param sourceCode
+     */
+    private static void copySOAPFaultCode(SOAPFactory factory, 
+                                          SOAPFault targetFault, 
+                                          SOAPFaultCode sourceCode) {
+        SOAPFaultCode targetCode = factory.createSOAPFaultCode(targetFault);
+        copyTagData(sourceCode, targetCode);
+
+        // Create the Value
+        SOAPFaultValue sourceValue = sourceCode.getValue();
+        SOAPFaultValue targetValue = factory.createSOAPFaultValue(targetCode);
+        copyTagData(sourceValue, targetValue);
+        
+        // There should only be a text node for the value, but in case there is more
+        Iterator i = sourceValue.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            copy(factory, targetValue, node);
+        }
+
+        // Now get process the SubCode
+        SOAPFaultSubCode sourceSubCode = sourceCode.getSubCode();
+        if (sourceSubCode != null) {
+            copySOAPFaultSubCode(factory, targetCode, sourceSubCode);
+        }
+    }
+
+    /**
+     * Copy the SOAPFaultSubCode tree
+     * @param factory
+     * @param targetParent (SOAPFaultCode or SOAPFaultSubCode)
+     * @param sourceSubCode
+     */
+    private static void copySOAPFaultSubCode(SOAPFactory factory, 
+                                             OMElement targetParent,
+                                             SOAPFaultSubCode sourceSubCode) {
+        SOAPFaultSubCode targetSubCode;
+        if (targetParent instanceof SOAPFaultSubCode) {
+            targetSubCode = factory.createSOAPFaultSubCode((SOAPFaultSubCode) targetParent);
+        } else {
+            targetSubCode = factory.createSOAPFaultSubCode((SOAPFaultCode) targetParent);
+        }
+        copyTagData(sourceSubCode, targetSubCode);
+
+        // Process the SOAP FaultValue
+        SOAPFaultValue sourceValue = sourceSubCode.getValue();
+        SOAPFaultValue targetValue = factory.createSOAPFaultValue(targetSubCode);
+        copyTagData(sourceValue, targetValue);
+        // There should only be a text node for the value, but in case there is more
+        Iterator i = sourceValue.getChildren();
+        while (i.hasNext()) {
+            OMNode node = (OMNode) i.next();
+            copy(factory, targetValue, node);
+        }
+
+        // Now process the SubCode of the SubCode
+        SOAPFaultSubCode sourceSubSubCode = sourceSubCode.getSubCode();
+        if (sourceSubSubCode != null) {
+            copySOAPFaultSubCode(factory, targetSubCode, sourceSubSubCode);
+        }
+    }
+
+
+    /**
+     * Copy the tag data (attributes and namespaces) from the source
+     * element to the target element.
+     * @param sourceElement
+     * @param targetElement
+     */
+    private static void copyTagData(OMElement sourceElement, 
+                                    OMElement targetElement) {
+        for (Iterator i = sourceElement.getAllDeclaredNamespaces(); i.hasNext();) {
+            OMNamespace ns = (OMNamespace) i.next();
+            targetElement.declareNamespace(ns);
+        }
+
+        for (Iterator i = sourceElement.getAllAttributes(); i.hasNext();) {
+            OMAttribute attr = (OMAttribute) i.next();
+            targetElement.addAttribute(attr);
+        }
+    }
+
+    /**
+     * Copy Header data (currently only the processed flag) from the
+     * source SOAPHeaderBlock to the target SOAPHeaderBlock
+     * @param sourceSHB
+     * @param targetSHB
+     */
+    private static void copySOAPHeaderBlockData(SOAPHeaderBlock sourceSHB, 
+                                                SOAPHeaderBlock targetSHB) {
+        // Copy the processed flag.  The other SOAPHeaderBlock information 
+        //(e.g. role, mustUnderstand) are attributes on the tag and are copied in copyTagData.
+        if (sourceSHB.isProcessed()) {
+            targetSHB.setProcessed();
+        }
+    }
+}

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java Sun Aug 19 05:42:58 2007
@@ -40,6 +40,8 @@
 
     /** @return Returns SOAPEnvelope. */
     SOAPEnvelope createSOAPEnvelope() throws SOAPProcessingException;
+    
+    SOAPEnvelope createSOAPEnvelope(OMNamespace ns); 
 
     SOAPEnvelope createSOAPEnvelope(OMXMLParserWrapper builder);
 

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextImpl.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextImpl.java Sun Aug 19 05:42:58 2007
@@ -107,6 +107,57 @@
         this.builder = builder;
         this.ns = XOP_NS;
     }
+    
+    /**
+     * Construct TextImpl that is a copy of the source OMTextImpl
+     * @param parent
+     * @param source TextImpl
+     * @param factory
+     */
+    public TextImpl(OMContainer parent, TextImpl source, OMFactory factory) {
+        super((DocumentImpl) ((ParentNode) parent).getOwnerDocument(), factory);
+        this.done = true;
+        
+        // Copy the value of the text
+        if (source.textValue != null) {
+            this.textValue = new StringBuffer();
+            this.textValue.append(source.textValue.toString());
+        }
+        
+        // Clone the charArray (if it exists)
+        if (source.charArray != null) {
+            this.charArray = new char[source.charArray.length];
+            for (int i=0; i<source.charArray.length; i++) {
+                this.charArray[i] = source.charArray[i];
+            }
+        }
+        
+        
+        // Turn off textNS...the namespace will need to be recalculated
+        // in the new tree's context.
+        this.textNS = null;
+        
+        // Copy the optimized related settings.
+        this.optimize = source.optimize;
+        this.mimeType = source.mimeType;
+        this.isBinary = source.isBinary;
+        
+        // TODO
+        // Do we need a deep copy of the data-handler 
+        this.contentID = source.contentID;
+        this.dataHandlerObject = source.dataHandlerObject;
+        
+        this.localName = source.localName;
+        if (source.ns != null) {
+            this.ns = new OMNamespaceImpl(source.ns.getNamespaceURI(), 
+                                          source.ns.getPrefix());
+        }
+        if (source.attribute != null) {
+            this.attribute = factory.createOMAttribute(source.attribute.getLocalName(),
+                                                       source.attribute.getNamespace(),
+                                                       source.attribute.getAttributeValue());
+        }
+    }
 
     public TextImpl(String text, String mimeType, boolean optimize,
                     OMFactory factory) {

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java Sun Aug 19 05:42:58 2007
@@ -235,6 +235,17 @@
         ((OMNodeEx) textNode).setType(type);
         return textNode;
     }
+    
+    
+    /**
+     * Create OMText node that is a copy of the source text node
+     * @param parent
+     * @param source
+     * @return
+     */
+    public OMText createOMText(OMContainer parent, OMText source) {
+        return new TextImpl(parent, (TextImpl) source, this);
+    }
 
     public OMText createOMText(OMContainer parent, char[] charArary, int type) {
         ElementImpl parentElem = (ElementImpl) parent;

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/factory/DOMSOAPFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/factory/DOMSOAPFactory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/factory/DOMSOAPFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/factory/DOMSOAPFactory.java Sun Aug 19 05:42:58 2007
@@ -80,6 +80,10 @@
     public SOAPEnvelope createSOAPEnvelope() throws SOAPProcessingException {
         throw new UnsupportedOperationException();
     }
+    
+    public SOAPEnvelope createSOAPEnvelope(OMNamespace ns) {
+        throw new UnsupportedOperationException();
+    }
 
     public SOAPHeader createSOAPHeader(SOAPEnvelope envelope) throws SOAPProcessingException {
         throw new UnsupportedOperationException();

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap11/SOAP11Factory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap11/SOAP11Factory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap11/SOAP11Factory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap11/SOAP11Factory.java Sun Aug 19 05:42:58 2007
@@ -68,6 +68,11 @@
                         SOAP11Constants.SOAP_DEFAULT_NAMESPACE_PREFIX),
                 this);
     }
+    
+    public SOAPEnvelope createSOAPEnvelope(OMNamespace ns) {
+        return new SOAPEnvelopeImpl(ns,
+                                    this);
+    }
 
     public SOAPHeader createSOAPHeader(SOAPEnvelope envelope)
             throws SOAPProcessingException {

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap12/SOAP12Factory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap12/SOAP12Factory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap12/SOAP12Factory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/soap12/SOAP12Factory.java Sun Aug 19 05:42:58 2007
@@ -67,6 +67,11 @@
                         SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX),
                 this);
     }
+    
+    public SOAPEnvelope createSOAPEnvelope(OMNamespace ns) {
+        return new SOAPEnvelopeImpl(ns,
+                                    this);
+    }
 
     public SOAPHeader createSOAPHeader(SOAPEnvelope envelope) throws SOAPProcessingException {
         return new SOAP12HeaderImpl(envelope, this);

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java Sun Aug 19 05:42:58 2007
@@ -102,6 +102,49 @@
     public OMTextImpl(OMContainer parent, String text, OMFactory factory) {
         this(parent, text, TEXT_NODE, factory);
     }
+    
+    /**
+     * Construct OMTextImpl that is a copy of the source OMTextImpl
+     * @param parent
+     * @param source OMTextImpl
+     * @param factory
+     */
+    public OMTextImpl(OMContainer parent, OMTextImpl source, OMFactory factory) {
+        super(parent, factory, true);
+        // Copy the value of the text
+        this.value = source.value;
+        this.nodeType = source.nodeType;
+        
+        // Clone the charArray (if it exists)
+        if (source.charArray != null) {
+            this.charArray = new char[source.charArray.length];
+            for (int i=0; i<source.charArray.length; i++) {
+                this.charArray[i] = source.charArray[i];
+            }
+        }
+        
+        // Turn off calcNS...the namespace will need to be recalculated
+        // in the new tree's context.
+        this.calcNS = false;
+        this.textNS = null;
+        
+        // Copy the optimized related settings.
+        this.optimize = source.optimize;
+        this.mimeType = source.mimeType;
+        this.isBinary = source.isBinary;
+        
+        // TODO
+        // Do we need a deep copy of the data-handler 
+        this.contentID = source.contentID;
+        this.dataHandlerObject = source.dataHandlerObject;
+        
+        this.localName = source.localName;
+        if (source.attribute != null) {
+            this.attribute = factory.createOMAttribute(source.attribute.getLocalName(),
+                                                       source.attribute.getNamespace(),
+                                                       source.attribute.getAttributeValue());
+        }
+    }
 
     public OMTextImpl(OMContainer parent, String text, int nodeType,
                       OMFactory factory) {

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java Sun Aug 19 05:42:58 2007
@@ -233,6 +233,16 @@
                                OMXMLParserWrapper builder) {
         return new OMTextImpl(contentID, parent, builder, this);
     }
+    
+    /**
+     * Create OMText node that is a copy of the source text node
+     * @param parent
+     * @param source
+     * @return
+     */
+    public OMText createOMText(OMContainer parent, OMText source) {
+        return new OMTextImpl(parent, (OMTextImpl) source, this);
+    }
 
     /**
      * Creates text.

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java Sun Aug 19 05:42:58 2007
@@ -69,6 +69,11 @@
                         SOAP11Constants.SOAP_DEFAULT_NAMESPACE_PREFIX),
                 this);
     }
+    
+    public SOAPEnvelope createSOAPEnvelope(OMNamespace ns) {
+        return new SOAPEnvelopeImpl(ns,
+                                    this);
+    }
 
     public SOAPHeader createSOAPHeader(SOAPEnvelope envelope)
             throws SOAPProcessingException {

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java?view=diff&rev=567394&r1=567393&r2=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java Sun Aug 19 05:42:58 2007
@@ -68,6 +68,11 @@
                         SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX),
                 this);
     }
+    
+    public SOAPEnvelope createSOAPEnvelope(OMNamespace ns) {
+        return new SOAPEnvelopeImpl(ns,
+                                    this);
+    }
 
     public SOAPHeader createSOAPHeader(SOAPEnvelope envelope) throws SOAPProcessingException {
         return new SOAP12HeaderImpl(envelope, this);

Added: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/CopyUtilsTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/CopyUtilsTest.java?view=auto&rev=567394
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/CopyUtilsTest.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/util/CopyUtilsTest.java Sun Aug 19 05:42:58 2007
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om.util;
+
+import org.apache.axiom.om.AbstractTestCase;
+import org.apache.axiom.om.OMElement;
+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.TestConstants;
+import org.apache.axiom.om.ds.ByteArrayDataSource;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import java.io.File;
+import java.io.FileReader;
+import java.util.Iterator;
+
+/**
+ * Validates CopyUtils utility
+ */
+/**
+ * @author scheu
+ *
+ */
+public class CopyUtilsTest extends AbstractTestCase {
+
+    public CopyUtilsTest(String testName) {
+        super(testName);
+    }
+    
+    public void testSample1() throws Exception {
+        File file = getTestResourceFile(TestConstants.SAMPLE1);
+        copyAndCheck(createEnvelope(file), true);
+    }
+    
+    public void testSOAPMESSAGE() throws Exception {
+        File file = getTestResourceFile(TestConstants.SOAP_SOAPMESSAGE);
+        copyAndCheck(createEnvelope(file), true);
+    }
+    
+    public void testSOAPMESSAGE1() throws Exception {
+        File file = getTestResourceFile(TestConstants.SOAP_SOAPMESSAGE1);
+        copyAndCheck(createEnvelope(file), false);  // Ignore the serialization comparison
+    }
+    
+    public void testWHITESPACE_MESSAGE() throws Exception {
+        File file = getTestResourceFile(TestConstants.WHITESPACE_MESSAGE);
+        copyAndCheck(createEnvelope(file), true);
+    }
+    
+    public void testMINIMAL_MESSAGE() throws Exception {
+        File file = getTestResourceFile(TestConstants.MINIMAL_MESSAGE);
+        copyAndCheck(createEnvelope(file), true);
+    }
+    public void testREALLY_BIG_MESSAGE() throws Exception {
+        File file = getTestResourceFile(TestConstants.REALLY_BIG_MESSAGE);
+        copyAndCheck(createEnvelope(file), false);  // Ignore the serialization comparison
+    }
+    public void testEMPTY_BODY_MESSAGE() throws Exception {
+        File file = getTestResourceFile(TestConstants.EMPTY_BODY_MESSAGE);
+        copyAndCheck(createEnvelope(file), true);
+    }
+    
+    public void testOMSE() throws Exception {
+        File file = getTestResourceFile(TestConstants.EMPTY_BODY_MESSAGE);
+        SOAPEnvelope sourceEnv = createEnvelope(file);
+        SOAPBody body = sourceEnv.getBody();
+        
+        // Create a payload
+        String text = "<tns:payload xmlns:tns=\"urn://test\">Hello World</tns:payload>";
+        String encoding = "UTF-8";
+        ByteArrayDataSource bads = new ByteArrayDataSource(text.getBytes(encoding), encoding);
+        OMNamespace ns = body.getOMFactory().createOMNamespace("urn://test", "tns");
+        OMSourcedElement omse =body.getOMFactory().createOMElement(bads, "payload", ns);
+        body.addChild(omse);
+        copyAndCheck(sourceEnv, true);
+    }
+    
+    /**
+     * Create SOAPEnvelope from the test in the indicated file
+     * @param file
+     * @return
+     * @throws Exception
+     */
+    protected SOAPEnvelope createEnvelope(File file) throws Exception {
+        XMLStreamReader parser =
+            XMLInputFactory.newInstance().createXMLStreamReader(new FileReader(file));
+        OMXMLParserWrapper builder = new StAXSOAPModelBuilder(parser, null);
+        SOAPEnvelope sourceEnv = (SOAPEnvelope) builder.getDocumentElement();
+        return sourceEnv;
+    }
+    
+    /**
+     * Make a copy of the source envelope and validate the target tree
+     * @param sourceEnv
+     * @param checkText (if true, check the serialization of the source and target tree)
+     * @throws Exception
+     */
+    protected void copyAndCheck(SOAPEnvelope sourceEnv, boolean checkText) throws Exception {
+       
+        SOAPEnvelope targetEnv = CopyUtils.copy(sourceEnv);
+        
+        identityCheck(sourceEnv, targetEnv, "");
+        
+        String sourceText = sourceEnv.toString();
+        String targetText = targetEnv.toString();
+        
+        // In some cases the serialization code or internal hashmaps cause
+        // attributes or namespaces to be in a different order...accept this for now.
+        if (checkText) {
+            assertTrue("\nSource=" + sourceText +
+                   "\nTarget=" + targetText,
+                   sourceText.equals(targetText));
+        }
+        
+        
+    }
+    
+    /**
+     * Check the identity of each object in the tree
+     * @param source
+     * @param target
+     * @param depth
+     */
+    protected void identityCheck(OMNode source, OMNode target, String depth) {
+        // System.out.println(depth + source.getClass().getCanonicalName());
+        if (source instanceof OMElement) {
+            
+            if (source instanceof OMSourcedElement) {
+                assertTrue("Source = " + source.getClass().getCanonicalName() + 
+                           "Target = " + target.getClass().getCanonicalName(),
+                           target instanceof OMSourcedElement);
+                assertTrue("Source Expansion = " +((OMSourcedElement)source).isExpanded() +
+                           "Target Expansion = " + ((OMSourcedElement)target).isExpanded(),
+                           ((OMSourcedElement)source).isExpanded() ==
+                               ((OMSourcedElement)target).isExpanded());
+                if (((OMSourcedElement)source).isExpanded()) {
+                    Iterator i = ((OMElement) source).getChildren();
+                    Iterator j = ((OMElement) target).getChildren();
+                    while(i.hasNext() && j.hasNext()) {
+                        OMNode sourceChild = (OMNode) i.next();
+                        OMNode targetChild = (OMNode) j.next();
+                        identityCheck(sourceChild, targetChild, depth + "  ");
+                    }
+                    assertTrue("Source and Target have different number of children",
+                               i.hasNext() == j.hasNext());
+                }
+            } else {
+                assertTrue("Source = " + source.getClass().getCanonicalName() + 
+                           "Target = " + target.getClass().getCanonicalName(),
+                           source.getClass().getCanonicalName().equals(
+                           target.getClass().getCanonicalName()));
+                Iterator i = ((OMElement) source).getChildren();
+                Iterator j = ((OMElement) target).getChildren();
+                while(i.hasNext() && j.hasNext()) {
+                    OMNode sourceChild = (OMNode) i.next();
+                    OMNode targetChild = (OMNode) j.next();
+                    identityCheck(sourceChild, targetChild, depth + "  ");
+                }
+                assertTrue("Source and Target have different number of children",
+                           i.hasNext() == j.hasNext());
+            }
+        } else {
+            assertTrue("Source = " + source.getClass().getCanonicalName() + 
+                   "Target = " + target.getClass().getCanonicalName(),
+                   source.getClass().getCanonicalName().equals(
+                   target.getClass().getCanonicalName()));
+        }
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: commons-dev-help@ws.apache.org