< prev index next >

jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/SOAPDocumentImpl.java

Print this page

        

@@ -30,17 +30,20 @@
 package com.sun.xml.internal.messaging.saaj.soap;
 
 import com.sun.xml.internal.messaging.saaj.soap.impl.CDATAImpl;
 import com.sun.xml.internal.messaging.saaj.soap.impl.ElementFactory;
 import com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl;
+import com.sun.xml.internal.messaging.saaj.soap.impl.NamedNodeMapImpl;
+import com.sun.xml.internal.messaging.saaj.soap.impl.NodeListImpl;
 import com.sun.xml.internal.messaging.saaj.soap.impl.SOAPCommentImpl;
 import com.sun.xml.internal.messaging.saaj.soap.impl.SOAPTextImpl;
 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants;
 import com.sun.xml.internal.messaging.saaj.util.SAAJUtil;
 import org.w3c.dom.Attr;
 import org.w3c.dom.CDATASection;
+import org.w3c.dom.CharacterData;
 import org.w3c.dom.Comment;
 import org.w3c.dom.DOMConfiguration;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;

@@ -50,35 +53,35 @@
 import org.w3c.dom.EntityReference;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
 import org.w3c.dom.UserDataHandler;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.soap.SOAPElement;
 import javax.xml.soap.SOAPException;
+import java.lang.reflect.Constructor;
 import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.logging.Logger;
 
 public class SOAPDocumentImpl implements SOAPDocument, javax.xml.soap.Node, Document {
 
+    public static final String SAAJ_NODE = "javax.xml.soap.Node";
+
     private static final String XMLNS = "xmlns".intern();
     protected static final Logger log =
         Logger.getLogger(LogDomainConstants.SOAP_DOMAIN,
                          "com.sun.xml.internal.messaging.saaj.soap.LocalStrings");
 
     SOAPPartImpl enclosingSOAPPart;
 
     private Document document;
 
-    private Map<Node, javax.xml.soap.Node> domToSoap = new HashMap<>();
-
     public SOAPDocumentImpl(SOAPPartImpl enclosingDocument) {
         document = createDocument();
         this.enclosingSOAPPart = enclosingDocument;
         register(this);
     }

@@ -103,73 +106,85 @@
     //
     //    public SOAPDocumentImpl(DocumentType doctype, boolean grammarAccess) {
     //        super(doctype, grammarAccess);
     //    }
 
+    @Override
     public SOAPPartImpl getSOAPPart() {
         if (enclosingSOAPPart == null) {
             log.severe("SAAJ0541.soap.fragment.not.bound.to.part");
             throw new RuntimeException("Could not complete operation. Fragment not bound to SOAP part.");
         }
         return enclosingSOAPPart;
     }
 
+    @Override
     public SOAPDocumentImpl getDocument() {
         return this;
     }
 
+    @Override
     public DocumentType getDoctype() {
         // SOAP means no DTD, No DTD means no doctype (SOAP 1.2 only?)
         return null;
     }
 
+    @Override
     public DOMImplementation getImplementation() {
         return document.getImplementation();
     }
 
+    @Override
     public Element getDocumentElement() {
         // This had better be an Envelope!
         getSOAPPart().doGetDocumentElement();
         return doGetDocumentElement();
     }
 
     protected Element doGetDocumentElement() {
         return document.getDocumentElement();
     }
 
+    @Override
     public Element createElement(String tagName) throws DOMException {
         return ElementFactory.createElement(
             this,
             NameImpl.getLocalNameFromTagName(tagName),
             NameImpl.getPrefixFromTagName(tagName),
             null);
     }
 
+    @Override
     public DocumentFragment createDocumentFragment() {
-        return document.createDocumentFragment();
+        return new SOAPDocumentFragment(this);
     }
 
+    @Override
     public org.w3c.dom.Text createTextNode(String data) {
         return new SOAPTextImpl(this, data);
     }
 
+    @Override
     public Comment createComment(String data) {
         return new SOAPCommentImpl(this, data);
     }
 
+    @Override
     public CDATASection createCDATASection(String data) throws DOMException {
         return new CDATAImpl(this, data);
     }
 
+    @Override
     public ProcessingInstruction createProcessingInstruction(
         String target,
         String data)
         throws DOMException {
         log.severe("SAAJ0542.soap.proc.instructions.not.allowed.in.docs");
         throw new UnsupportedOperationException("Processing Instructions are not allowed in SOAP documents");
     }
 
+    @Override
     public Attr createAttribute(String name) throws DOMException {
         boolean isQualifiedName = (name.indexOf(":") > 0);
         if (isQualifiedName) {
             String nsUri = null;
             String prefix = name.substring(0, name.indexOf(":"));

@@ -182,50 +197,99 @@
         }
 
         return document.createAttribute(name);
     }
 
+    @Override
     public EntityReference createEntityReference(String name)
         throws DOMException {
             log.severe("SAAJ0543.soap.entity.refs.not.allowed.in.docs");
             throw new UnsupportedOperationException("Entity References are not allowed in SOAP documents");
     }
 
+    @Override
     public NodeList getElementsByTagName(String tagname) {
-        return document.getElementsByTagName(tagname);
+        return new NodeListImpl(this, document.getElementsByTagName(tagname));
     }
 
+    @Override
     public org.w3c.dom.Node importNode(Node importedNode, boolean deep)
         throws DOMException {
-        final Node node = document.importNode(getDomNode(importedNode), deep);
-        return node instanceof Element ?
-            ElementFactory.createElement(this, (Element) node)
-                : node;
+        Node domNode = getDomNode(importedNode);
+        final Node newNode = document.importNode(domNode, deep);
+
+        if (importedNode instanceof javax.xml.soap.Node) {
+            Node newSoapNode = createSoapNode(importedNode.getClass(), newNode);
+            newNode.setUserData(SAAJ_NODE, newSoapNode, null);
+            if (deep && importedNode.hasChildNodes()) {
+                NodeList childNodes = importedNode.getChildNodes();
+                for (int i = 0; i < childNodes.getLength(); i++) {
+                    registerChildNodes(childNodes.item(i), deep);
+                }
+            }
+            return newSoapNode;
+        }
+
+        registerChildNodes(newNode, deep);
+        return findIfPresent(newNode);
+    }
+
+    //If the parentNode is not registered to domToSoap, create soap wapper for parentNode and register it to domToSoap
+    //If deep = true, also register all children of parentNode to domToSoap map.
+    public void registerChildNodes(Node parentNode, boolean deep) {
+        if (parentNode.getUserData(SAAJ_NODE) == null) {
+            if (parentNode instanceof Element) {
+                ElementFactory.createElement(this, (Element) parentNode);
+            } else if (parentNode instanceof CharacterData) {
+                switch (parentNode.getNodeType()) {
+                    case CDATA_SECTION_NODE:
+                        new CDATAImpl(this, (CharacterData) parentNode);
+                        break;
+                    case COMMENT_NODE:
+                        new SOAPCommentImpl(this, (CharacterData) parentNode);
+                        break;
+                    case TEXT_NODE:
+                        new SOAPTextImpl(this, (CharacterData) parentNode);
+                        break;
+                }
+            }
+        }
+        if (deep) {
+            NodeList nodeList = parentNode.getChildNodes();
+            for (int i = 0; i < nodeList.getLength(); i++) {
+                Node nextChild = nodeList.item(i);
+                registerChildNodes(nextChild, true);
+            }
+        }
     }
 
+    @Override
     public Element createElementNS(String namespaceURI, String qualifiedName)
         throws DOMException {
         return ElementFactory.createElement(
             this,
             NameImpl.getLocalNameFromTagName(qualifiedName),
             NameImpl.getPrefixFromTagName(qualifiedName),
             namespaceURI);
     }
 
+    @Override
     public Attr createAttributeNS(String namespaceURI, String qualifiedName)
         throws DOMException {
         return document.createAttributeNS(namespaceURI, qualifiedName);
     }
 
+    @Override
     public NodeList getElementsByTagNameNS(
         String namespaceURI,
         String localName) {
-        return document.getElementsByTagNameNS(namespaceURI, localName);
+        return new NodeListImpl(this, document.getElementsByTagNameNS(namespaceURI, localName));
     }
 
+    @Override
     public Element getElementById(String elementId) {
-        return document.getElementById(elementId);
+        return (Element) findIfPresent(document.getElementById(elementId));
     }
 
     @Override
     public String getInputEncoding() {
         return document.getInputEncoding();

@@ -291,11 +355,11 @@
         document.normalizeDocument();
     }
 
     @Override
     public Node renameNode(Node n, String namespaceURI, String qualifiedName) throws DOMException {
-        return document.renameNode(n, namespaceURI, qualifiedName);
+        return findIfPresent(document.renameNode(n, namespaceURI, qualifiedName));
     }
 
     @Override
     public String getNodeName() {
         return document.getNodeName();

@@ -316,41 +380,41 @@
         return document.getNodeType();
     }
 
     @Override
     public Node getParentNode() {
-        return document.getParentNode();
+        return findIfPresent(document.getParentNode());
     }
 
     @Override
     public NodeList getChildNodes() {
-        return document.getChildNodes();
+        return new NodeListImpl(this, document.getChildNodes());
     }
 
     @Override
     public Node getFirstChild() {
-        return document.getFirstChild();
+        return findIfPresent(document.getFirstChild());
     }
 
     @Override
     public Node getLastChild() {
-        return document.getLastChild();
+        return findIfPresent(document.getLastChild());
     }
 
     @Override
     public Node getPreviousSibling() {
-        return document.getPreviousSibling();
+        return findIfPresent(document.getPreviousSibling());
     }
 
     @Override
     public Node getNextSibling() {
-        return document.getNextSibling();
+        return findIfPresent(document.getNextSibling());
     }
 
     @Override
     public NamedNodeMap getAttributes() {
-        return document.getAttributes();
+        return new NamedNodeMapImpl(document.getAttributes(), this);
     }
 
     @Override
     public Document getOwnerDocument() {
         return document.getOwnerDocument();

@@ -381,11 +445,13 @@
         return document.hasChildNodes();
     }
 
     @Override
     public Node cloneNode(boolean deep) {
-        return document.cloneNode(deep);
+        Node node = document.cloneNode(deep);
+        registerChildNodes(node, deep);
+        return findIfPresent(node);
     }
 
     @Override
     public void normalize() {
         document.normalize();

@@ -426,11 +492,11 @@
         return document.getBaseURI();
     }
 
     @Override
     public short compareDocumentPosition(Node other) throws DOMException {
-        return document.compareDocumentPosition(other);
+        return document.compareDocumentPosition(getDomNode(other));
     }
 
     @Override
     public String getTextContent() throws DOMException {
         return document.getTextContent();

@@ -441,11 +507,11 @@
         document.setTextContent(textContent);
     }
 
     @Override
     public boolean isSameNode(Node other) {
-        return document.isSameNode(other);
+        return document.isSameNode(getDomNode(other));
     }
 
     @Override
     public String lookupPrefix(String namespaceURI) {
         return document.lookupPrefix(namespaceURI);

@@ -461,11 +527,11 @@
         return document.lookupNamespaceURI(prefix);
     }
 
     @Override
     public boolean isEqualNode(Node arg) {
-        return document.isEqualNode(arg);
+        return document.isEqualNode(getDomNode(arg));
     }
 
     @Override
     public Object getFeature(String feature, String version) {
         return document.getFeature(feature, version);

@@ -494,15 +560,15 @@
      *
      * @param node SAAJ wrapper node for w3c DOM node
      */
     public void register(javax.xml.soap.Node node) {
         final Node domElement = getDomNode(node);
-        if (domToSoap.containsKey(domElement)) {
+        if (domElement.getUserData(SAAJ_NODE) != null) {
             throw new IllegalStateException("Element " + domElement.getNodeName()
                     + " is already registered");
         }
-        domToSoap.put(domElement, node);
+        domElement.setUserData(SAAJ_NODE, node, null);
     }
 
     /**
      * Find a soap wrapper for w3c dom node.
      *

@@ -520,11 +586,11 @@
             return null;
         }
         if (node instanceof javax.xml.soap.Node) {
             return (javax.xml.soap.Node) node;
         }
-        final javax.xml.soap.Node found = domToSoap.get(node);
+        final javax.xml.soap.Node found = (javax.xml.soap.Node) node.getUserData(SAAJ_NODE);
         if (found == null && required) {
             throw new IllegalArgumentException(MessageFormat.format("Cannot find SOAP wrapper for element {0}", node));
         }
         return found;
     }

@@ -560,10 +626,28 @@
             return ((CDATAImpl) node).getDomElement();
         }
         return node;
     }
 
+
+    private Node createSoapNode(Class nodeType, Node node) {
+        if (SOAPTextImpl.class.isAssignableFrom(nodeType)) {
+            return new SOAPTextImpl(this, (Text) node);
+        } else if (SOAPCommentImpl.class.isAssignableFrom(nodeType)) {
+            return new SOAPCommentImpl(this, (Comment) node);
+        } else if (CDATAImpl.class.isAssignableFrom(nodeType)) {
+            return new CDATAImpl(this, (CDATASection) node);
+        }
+        try {
+            Constructor<Node> constructor = nodeType.getConstructor(SOAPDocumentImpl.class, Element.class);
+            return constructor.newInstance(this, node);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+
     public Document getDomElement() {
         return document;
     }
 
     @Override
< prev index next >