You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xindice-dev@xml.apache.org by vg...@apache.org on 2006/11/04 06:17:22 UTC

svn commit: r471122 - in /xml/xindice/trunk/java: src/org/apache/xindice/xml/dom/ tests/src/org/apache/xindice/xml/dom/

Author: vgritsenko
Date: Fri Nov  3 21:17:20 2006
New Revision: 471122

URL: http://svn.apache.org/viewvc?view=rev&rev=471122
Log:
DOM Level 3: User data handlers

Modified:
    xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/AttrImpl.java
    xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DocumentImpl.java
    xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/ElementImpl.java
    xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/NodeImpl.java
    xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/dom/NodeTest.java

Modified: xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/AttrImpl.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/AttrImpl.java?view=diff&rev=471122&r1=471121&r2=471122
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/AttrImpl.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/AttrImpl.java Fri Nov  3 21:17:20 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * CVS $Id$
+ * $Id$
  */
 
 package org.apache.xindice.xml.dom;
@@ -23,11 +23,12 @@
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Element;
 import org.w3c.dom.TypeInfo;
+import org.w3c.dom.UserDataHandler;
 
 /**
  * AttrImpl
  *
- * @version CVS $Revision$, $Date$
+ * @version $Revision$, $Date$
  */
 public final class AttrImpl extends ContainerNodeImpl
                             implements Attr {
@@ -202,6 +203,7 @@
             getOwnerElement().setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + prefix, namespaceURI);
         }
 
+        invokeHandlers(UserDataHandler.NODE_RENAMED, this, null);
         return this;
     }
 }

Modified: xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DocumentImpl.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DocumentImpl.java?view=diff&rev=471122&r1=471121&r2=471122
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DocumentImpl.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/DocumentImpl.java Fri Nov  3 21:17:20 2006
@@ -41,6 +41,7 @@
 import org.w3c.dom.NodeList;
 import org.w3c.dom.ProcessingInstruction;
 import org.w3c.dom.Text;
+import org.w3c.dom.UserDataHandler;
 import org.w3c.dom.traversal.DocumentTraversal;
 import org.w3c.dom.traversal.NodeFilter;
 import org.w3c.dom.traversal.NodeIterator;
@@ -359,23 +360,27 @@
     }
 
     public Node importNode(Node importedNode, boolean deep) {
-		return importNode(importedNode, deep, true);
+		return importNode(importedNode, deep, true, true);
 	}
 
-	private Node importNode(Node importedNode, boolean deep, boolean importNamespaces) {
+	private Node importNode(Node importedNode, boolean deep, boolean importNamespaces, boolean invokeHandler) {
         try {
-            // If we're a Xindice DOM Node and share the same symbol table,
+            // If we're a Xindice Compressed DOM Node, and share the same symbol table,
             // then we're golden
             if (importedNode instanceof NodeImpl) {
                 NodeImpl impl = (NodeImpl) importedNode;
                 DocumentImpl docImpl = (DocumentImpl) impl.getOwnerDocument();
                 if (docImpl.getSymbols() != null && (docImpl.getSymbols() == symbols)) {
-                    NodeImpl clone = (NodeImpl) impl.cloneNode(deep);
+                    NodeImpl clone = (NodeImpl) impl.cloneNode(deep, false);
                     clone.setParentNode(this);
-					if (importNamespaces)
-					{
+
+					if (importNamespaces) {
 						importNamespaces(importedNode, clone);
 					}
+                    if (invokeHandler) {
+                        invokeHandlers(UserDataHandler.NODE_IMPORTED, importedNode, clone);
+                    }
+
                     return clone;
                 }
             }
@@ -425,7 +430,8 @@
                     result = createTextNode(importedNode.getNodeValue());
                     break;
 
-                default :
+                default:
+                    // FIXME Huh?
             }
 
             if (deep && result != null) {
@@ -433,7 +439,11 @@
                 int size = list.getLength();
                 for (int i = 0; i < size; i++) {
                     Node n = list.item(i);
-                    result.appendChild(importNode(n, deep, false));
+                    result.appendChild(importNode(n, deep, false, invokeHandler));
+                }
+
+                if (invokeHandler) {
+                    invokeHandlers(UserDataHandler.NODE_IMPORTED, importedNode, result);
                 }
             }
 
@@ -478,10 +488,15 @@
             if (docImpl.getSymbols() == null || docImpl.getSymbols() == symbols) {
                 impl.getParentNode().removeChild(impl);
                 impl.setParentNode(this);
+                invokeHandlers(UserDataHandler.NODE_ADOPTED, src, null);
                 return impl;
             }
         }
-        return importNode(src, true);
+
+        Node node = importNode(src, true, true, false);
+        invokeHandlers(UserDataHandler.NODE_ADOPTED, src, node);
+
+        return node;
     }
 
     /**

Modified: xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/ElementImpl.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/ElementImpl.java?view=diff&rev=471122&r1=471121&r2=471122
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/ElementImpl.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/ElementImpl.java Fri Nov  3 21:17:20 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * CVS $Id$
+ * $Id$
  */
 
 package org.apache.xindice.xml.dom;
@@ -31,6 +31,7 @@
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.TypeInfo;
+import org.w3c.dom.UserDataHandler;
 
 import java.io.IOException;
 import java.util.HashSet;
@@ -40,7 +41,8 @@
  *
  * @version $Revision$, $Date$
  */
-public final class ElementImpl extends ContainerNodeImpl implements Element {
+public final class ElementImpl extends ContainerNodeImpl
+                               implements Element {
 
     private static final Log log = LogFactory.getLog(ElementImpl.class);
 
@@ -540,6 +542,7 @@
             setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + prefix, namespaceURI);
         }
 
+        invokeHandlers(UserDataHandler.NODE_RENAMED, this, null);
         return this;
     }
 }

Modified: xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/NodeImpl.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/NodeImpl.java?view=diff&rev=471122&r1=471121&r2=471122
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/NodeImpl.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/xml/dom/NodeImpl.java Fri Nov  3 21:17:20 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * CVS $Id$
+ * $Id$
  */
 
 package org.apache.xindice.xml.dom;
@@ -37,6 +37,8 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Iterator;
+import java.util.Map;
 
 /**
  * NodeImpl implements the foundation of the Xindice compressed DOM.
@@ -489,7 +491,7 @@
     /**
      *  This is a convenience method to allow easy determination of whether a
      * node has any children.
-     * @return  <code>true</code> if the node has any children,
+     * @return <code>true</code> if the node has any children,
      *   <code>false</code> if the node has no children.
      */
     public boolean hasChildNodes() {
@@ -511,9 +513,14 @@
      *   its attributes, if it is an <code>Element</code>).
      * @return The duplicate node.
      */
-    public final synchronized Node cloneNode(boolean deep) {
+    public final Node cloneNode(boolean deep) {
+        return cloneNode(deep, true);
+    }
+
+    protected final synchronized Node cloneNode(boolean deep, boolean invokeHandler) {
         DocumentImpl doc = (DocumentImpl) getOwnerDocument();
         if (deep) {
+            // FIXME Does not account for non compressed documents
             byte[] data = this.data;
             int pos = this.pos;
             int len = this.len;
@@ -549,11 +556,9 @@
 
                 case Node.DOCUMENT_FRAGMENT_NODE:
                     DocumentFragmentImpl df = new DocumentFragmentImpl(this);
-                    if (deep) {
-                        NodeList nl = getChildNodes();
-                        for (int i = 0; i < nl.getLength(); i++) {
-                            df.appendChild(nl.item(i).cloneNode(deep));
-                        }
+                    NodeList nl = getChildNodes();
+                    for (int i = 0; i < nl.getLength(); i++) {
+                        df.appendChild(nl.item(i).cloneNode(deep));
                     }
                     newNode = df;
                     break;
@@ -584,25 +589,33 @@
                     }
             }
             if (newNode != null) {
+                if (invokeHandler) {
+                    invokeHandlers(UserDataHandler.NODE_CLONED, this, newNode);
+                }
                 return newNode;
             }
         }
 
         checkLoaded();
+        Node node = null;
         switch (getNodeType()) {
             case Node.ATTRIBUTE_NODE:
                 Attr attr = doc.createAttribute(nodeName);
                 attr.setValue(nodeValue);
-                return attr;
+                node = attr;
+                break;
 
             case Node.CDATA_SECTION_NODE:
-                return doc.createCDATASection(nodeValue);
+                node = doc.createCDATASection(nodeValue);
+                break;
 
             case Node.COMMENT_NODE:
-                return doc.createComment(nodeValue);
+                node = doc.createComment(nodeValue);
+                break;
 
             case Node.DOCUMENT_FRAGMENT_NODE:
-                return doc.createDocumentFragment();
+                node = doc.createDocumentFragment();
+                break;
 
             case Node.ELEMENT_NODE:
                 Element elem = doc.createElement(nodeName);
@@ -612,24 +625,33 @@
                     Attr a = (Attr) attrs.item(i);
                     elem.setAttribute(a.getName(), a.getValue());
                 }
-                return elem;
+                node = elem;
+                break;
 
             case Node.ENTITY_REFERENCE_NODE:
-                return doc.createEntityReference(nodeValue);
+                node = doc.createEntityReference(nodeValue);
+                break;
 
             case Node.PROCESSING_INSTRUCTION_NODE:
-                return doc.createProcessingInstruction(nodeName, nodeValue);
+                node = doc.createProcessingInstruction(nodeName, nodeValue);
+                break;
 
             case Node.TEXT_NODE:
-                return doc.createTextNode(nodeValue);
+                node = doc.createTextNode(nodeValue);
+                break;
 
             default:
                 if (log.isWarnEnabled()) {
                     log.warn("invalid node type : " + getNodeType());
                 }
+                break;
         }
 
-        return null;
+        if (node != null && invokeHandler) {
+            invokeHandlers(UserDataHandler.NODE_CLONED, this, node);
+        }
+
+        return node;
     }
 
     // Some DOM Level 2 Core Methods
@@ -1228,6 +1250,34 @@
         return key;
     }
      */
+
+    /** Invoke user data handlers with provided parameters. */
+    protected void invokeHandlers(short op, Node src, Node dst) {
+        if (!(src instanceof NodeImpl)) {
+            return;
+        }
+
+        ((NodeImpl) src).invokeHandlers(op, dst);
+    }
+
+    protected synchronized void invokeHandlers(short op, Node dst) {
+        if (handlers == null || handlers.isEmpty()) {
+            return;
+        }
+
+        for (Iterator i = handlers.entrySet().iterator(); i.hasNext(); ) {
+            final Map.Entry entry = (Map.Entry) i.next();
+            final String key = (String) entry.getKey();
+            final UserDataHandler handler = (UserDataHandler) entry.getValue();
+
+            try {
+                handler.handle(op, key, userData.get(key), this, dst);
+            } catch (Exception e) {
+                log.error("User data handler '" + key + "' failed for operation " + op, e);
+            }
+        }
+
+    }
 
     /**
      * Converts this node into its textual representation.

Modified: xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/dom/NodeTest.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/dom/NodeTest.java?view=diff&rev=471122&r1=471121&r2=471122
==============================================================================
--- xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/dom/NodeTest.java (original)
+++ xml/xindice/trunk/java/tests/src/org/apache/xindice/xml/dom/NodeTest.java Fri Nov  3 21:17:20 2006
@@ -1,13 +1,32 @@
+/*
+ * Copyright 2006 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.
+ *
+ * $Id$
+ */
+
 package org.apache.xindice.xml.dom;
 
 import junit.framework.TestCase;
 import org.w3c.dom.Node;
 import org.w3c.dom.Document;
+import org.w3c.dom.UserDataHandler;
 import org.apache.xindice.xml.SymbolTable;
 
 /**
  * Tests NodeImpl class
- *
+ * @version $Revision$, $Date$
  */
 public class NodeTest extends TestCase {
 
@@ -103,7 +122,7 @@
 //        assertEquals(null, node2.getParentNode());
     }
 
-    public void testCompareNodeposition() throws Exception {
+    public void testCompareNodePosition() throws Exception {
         Node node1 = cmpDom.getFirstChild().getNextSibling();
         assertEquals(NodeImpl.DOCUMENT_POSITION_CONTAINED_BY | NodeImpl.DOCUMENT_POSITION_FOLLOWING,
                 ((NodeImpl) cmpDoc).compareDocumentPosition(node1));
@@ -126,6 +145,55 @@
         node2 = cmpDom.getFirstChild().getNextSibling().getFirstChild();
         assertEquals(NodeImpl.DOCUMENT_POSITION_FOLLOWING | NodeImpl.DOCUMENT_POSITION_CONTAINED_BY,
                 ((NodeImpl) node1).compareDocumentPosition(node2));
+    }
+
+    public void testUserDataHandler() throws Exception {
+        SymbolTable symbols = new SymbolTable();
+        Document cdoc = new DocumentImpl(DOMCompressor.Compress(doc, symbols), symbols, null);
+
+        Node node1 = cdoc.getDocumentElement().getFirstChild().getNextSibling();
+        TestDataHandler handler = new TestDataHandler();
+        ((NodeImpl) node1).setUserData("key", "data", handler);
+        node1.cloneNode(true);
+        assertEquals(getExpectedResult(UserDataHandler.NODE_CLONED, "key", "data", node1), handler.getResult());
+
+        ((DocumentImpl) node1.getOwnerDocument()).renameNode(node1, "http://newURI", "test:bar");
+        assertEquals(getExpectedResult(UserDataHandler.NODE_RENAMED, "key", "data", node1), handler.getResult());
+    }
+
+    private String getExpectedResult(short op, String key, Object data, Node src) {
+        String result;
+        switch (op) {
+            case UserDataHandler.NODE_ADOPTED:
+                result = "NODE_ADOPTED";
+                break;
+            case UserDataHandler.NODE_CLONED:
+                result = "NODE_CLONED";
+                break;
+            case UserDataHandler.NODE_IMPORTED:
+                result = "NODE_IMPORTED";
+                break;
+            case UserDataHandler.NODE_RENAMED:
+                result = "NODE_RENAMED";
+                break;
+            default:
+                result = "Unknown";
+        }
+
+        return result + "|" + src.getNodeName() + "|" + key + "|" + data.toString();
+
+    }
+
+    private class TestDataHandler implements UserDataHandler {
+        String result;
+
+        public void handle(short op, String key, Object data, Node src, Node dst) {
+            result = getExpectedResult(op, key, data, src);
+        }
+
+        public String getResult() {
+            return result;
+        }
     }
 
 }