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;
+ }
}
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.