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;
+ }
}
}