summaryrefslogtreecommitdiff
path: root/gnu/xml
diff options
context:
space:
mode:
authorChris Burdess <dog@bluezoo.org>2007-06-01 09:43:53 +0000
committerChris Burdess <dog@bluezoo.org>2007-06-01 09:43:53 +0000
commita1721947a46086f4e15bc28b92a5b63cf8805bf8 (patch)
tree4c0fa7bb25c6807ef60a7edc665fa14f77a4450b /gnu/xml
parent6777f788a9f82babbf3bd508dcd0f1c636fdf220 (diff)
downloadclasspath-a1721947a46086f4e15bc28b92a5b63cf8805bf8.tar.gz
2007-06-01 Robin Garner <robin.garner@anu.edu.au>
Fixes #32162 * gnu/xml/dom/DomNode.java: Correct concurrency problem when deep cloning nodes.
Diffstat (limited to 'gnu/xml')
-rw-r--r--gnu/xml/dom/DomNode.java45
1 files changed, 33 insertions, 12 deletions
diff --git a/gnu/xml/dom/DomNode.java b/gnu/xml/dom/DomNode.java
index 9af3f3e54..1cbdc2aec 100644
--- a/gnu/xml/dom/DomNode.java
+++ b/gnu/xml/dom/DomNode.java
@@ -1108,26 +1108,47 @@ public abstract class DomNode
*/
public Node cloneNode(boolean deep)
{
- DomNode node = (DomNode) clone();
-
if (deep)
{
- DomDocument doc = (nodeType == DOCUMENT_NODE) ?
- (DomDocument) node : node.owner;
- boolean building = doc.building;
+ return cloneNodeDeepInternal(true, null);
+ }
+
+ DomNode node = (DomNode) clone();
+ if (nodeType == ENTITY_REFERENCE_NODE)
+ {
+ node.makeReadonly();
+ }
+ notifyUserDataHandlers(UserDataHandler.NODE_CLONED, this, node);
+ return node;
+ }
+
+ /**
+ * Returns a deep clone of this node.
+ */
+ private DomNode cloneNodeDeepInternal(boolean root, DomDocument doc)
+ {
+ DomNode node = (DomNode) clone();
+ boolean building = false; // Never used unless root is true
+ if (root)
+ {
+ doc = (nodeType == DOCUMENT_NODE) ? (DomDocument) node : node.owner;
+ building = doc.building;
doc.building = true; // Permit certain structural rules
- for (DomNode ctx = first; ctx != null; ctx = ctx.next)
- {
- DomNode newChild = (DomNode) ctx.cloneNode(deep);
- newChild.setOwner(doc);
- node.appendChild(newChild);
- }
- doc.building = building;
+ }
+ node.owner = doc;
+ for (DomNode ctx = first; ctx != null; ctx = ctx.next)
+ {
+ DomNode newChild = ctx.cloneNodeDeepInternal(false, doc);
+ node.appendChild(newChild);
}
if (nodeType == ENTITY_REFERENCE_NODE)
{
node.makeReadonly();
}
+ if (root)
+ {
+ doc.building = building;
+ }
notifyUserDataHandlers(UserDataHandler.NODE_CLONED, this, node);
return node;
}