Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit c1abaa8

Browse files
committed
fixing ODE-663. Thanks to Dave Carver!
git-svn-id: https://svn.apache.org/repos/asf/ode/branches/APACHE_ODE_1.X@943325 13f79535-47bb-0310-9956-ffa450edef68
1 parent f3cade8 commit c1abaa8

File tree

2 files changed

+126
-26
lines changed

2 files changed

+126
-26
lines changed

utils/src/main/java/org/apache/ode/utils/DOMUtils.java

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,25 +1109,7 @@ public static Node cloneNode(Document document, Node sourceNode) {
11091109

11101110
switch (sourceNode.getNodeType()) {
11111111
case Node.ATTRIBUTE_NODE:
1112-
if (namespaceURI == null) {
1113-
clonedNode = document.createAttribute(nodeName);
1114-
} else {
1115-
String prefix = ((Attr) sourceNode).lookupPrefix(namespaceURI);
1116-
// the prefix for the XML namespace can't be looked up, hence this...
1117-
if (prefix == null && namespaceURI.equals(NS_URI_XMLNS)) {
1118-
prefix = "xmlns";
1119-
}
1120-
// if a prefix exists, qualify the name with it
1121-
if (prefix != null && !"".equals(prefix)) {
1122-
nodeName = prefix + ":" + nodeName;
1123-
}
1124-
// create the appropriate type of attribute
1125-
if (prefix != null) {
1126-
clonedNode = document.createAttributeNS(namespaceURI, nodeName);
1127-
} else {
1128-
clonedNode = document.createAttribute(nodeName);
1129-
}
1130-
}
1112+
clonedNode = document.importNode(sourceNode, false);
11311113
break;
11321114
case Node.CDATA_SECTION_NODE:
11331115
clonedNode = document.createCDATASection(((CDATASection) sourceNode).getData());
@@ -1190,13 +1172,16 @@ public static Node cloneNode(Document document, Node sourceNode) {
11901172
NodeList sourceChildren = sourceNode.getChildNodes();
11911173
if (sourceChildren != null) {
11921174
for (int i = 0; i < sourceChildren.getLength(); i++) {
1193-
Node sourceChild = sourceChildren.item(i);
1194-
Node clonedChild = cloneNode(document, sourceChild);
1195-
clonedNode.appendChild(clonedChild);
1175+
if (sourceNode.getNodeType() != Node.ATTRIBUTE_NODE) {
1176+
Node sourceChild = sourceChildren.item(i);
1177+
Node clonedChild = cloneNode(document, sourceChild);
1178+
clonedNode.appendChild(clonedChild);
1179+
}
1180+
11961181
// if the child has a textual value, parse it for any embedded prefixes
1197-
if (clonedChild.getNodeType() == Node.TEXT_NODE ||
1198-
clonedChild.getNodeType() == Node.CDATA_SECTION_NODE) {
1199-
parseEmbeddedPrefixes(sourceNode, clonedNode, clonedChild);
1182+
if (sourceChildren.item(i).getNodeType() == Node.TEXT_NODE ||
1183+
sourceChildren.item(i).getNodeType() == Node.CDATA_SECTION_NODE) {
1184+
parseEmbeddedPrefixes(sourceNode, clonedNode, sourceChildren.item(i));
12001185
}
12011186
}
12021187
}

utils/src/test/java/org/apache/ode/utils/DOMUtilsTest.java

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,48 @@
1818
*/
1919
package org.apache.ode.utils;
2020

21+
import net.sf.saxon.dom.DocumentBuilderFactoryImpl;
22+
2123
import org.apache.ode.utils.TestResources;
2224

25+
import java.io.ByteArrayInputStream;
26+
import java.io.IOException;
2327
import java.io.InputStream;
28+
import java.util.Map;
29+
30+
import javax.xml.parsers.DocumentBuilder;
31+
import javax.xml.parsers.DocumentBuilderFactory;
32+
import javax.xml.parsers.ParserConfigurationException;
2433

2534
import junit.framework.TestCase;
2635

2736
import org.w3c.dom.Document;
2837
import org.w3c.dom.Element;
2938
import org.w3c.dom.Node;
3039
import org.w3c.dom.NodeList;
40+
import org.xml.sax.SAXException;
3141

3242
/**
3343
* Test the {@link DOMUtils} class.
3444
*/
3545
public class DOMUtilsTest extends TestCase {
36-
46+
private static final String SAXON_DOM_DOCUMENT_BUILDER_FACTORY = "net.sf.saxon.dom.DocumentBuilderFactoryImpl";
47+
private static final String DOCUMENT_BUILDER_FACTORY = "javax.xml.parsers.DocumentBuilderFactory";
48+
String defaultBuilderFactory = null;
49+
50+
@Override
51+
protected void setUp() throws Exception {
52+
super.setUp();
53+
defaultBuilderFactory = System.getProperty(DOCUMENT_BUILDER_FACTORY, "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
54+
}
55+
56+
@Override
57+
protected void tearDown() throws Exception {
58+
super.tearDown();
59+
60+
System.setProperty(DOCUMENT_BUILDER_FACTORY, defaultBuilderFactory);
61+
}
62+
3763
public void testParseInputStream() throws Exception {
3864
Document doc = DOMUtils.parse(TestResources.getLoanApprovalProcess().openStream());
3965
assertEquals("process", doc.getDocumentElement().getLocalName());
@@ -110,5 +136,94 @@ public void testIsEmptyElement() throws Exception {
110136
}
111137
}
112138
}
139+
140+
public void testCloneNode() throws Exception {
141+
String testString = "<ns1:parent xmlns:ns1=\"abc\">\n" +
142+
" <ns1:child xmlns=\"def\">\n" +
143+
" <ns2:nestedChild xmlns:ns2=\"def\"/>\n" +
144+
" </ns1:child>\n" +
145+
"</ns1:parent>";
146+
147+
Document doc = DOMUtils.parse(new ByteArrayInputStream(testString.getBytes()));
148+
Node node = doc.getFirstChild();
149+
Node clonedNode = DOMUtils.cloneNode(doc, node);
150+
String actualString = DOMUtils.domToString(clonedNode).replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "");
151+
assertEquals("XML Result", testString, actualString);
152+
}
153+
154+
public void testCloneNodeNewDocument() throws Exception {
155+
String testString = "<ns1:parent xmlns:ns1=\"abc\">\n" +
156+
" <ns1:child xmlns=\"def\">\n" +
157+
" <ns2:nestedChild xmlns:ns2=\"def\"/>\n" +
158+
" </ns1:child>\n" +
159+
"</ns1:parent>";
160+
161+
Document doc = DOMUtils.parse(new ByteArrayInputStream(testString.getBytes()));
162+
Document doc2 = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
163+
Node node = doc.getFirstChild();
164+
Node clonedNode = DOMUtils.cloneNode(doc2, node);
165+
166+
assertNotSame("DOM's are the same", doc, doc2);
167+
String actualString = DOMUtils.domToString(clonedNode).replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "");
168+
assertEquals("XML Result", testString, actualString);
169+
170+
}
171+
172+
/**
173+
* A Saxon's DOM is read only. cloneNode should throw an UnsupportedOperationException.
174+
*
175+
* @throws Exception
176+
*/
177+
public void testCloneNodeSaxon() throws Exception {
178+
String testString = "<ns1:parent xmlns:ns1=\"abc\">\n" +
179+
" <ns1:child xmlns=\"def\">\n" +
180+
" <ns2:nestedChild xmlns:ns2=\"def\"/>\n" +
181+
" </ns1:child>\n" +
182+
"</ns1:parent>";
183+
184+
Document doc = createSaxonDOM(testString);
185+
186+
Node node = doc.getFirstChild();
187+
try {
188+
Node clonedNode = DOMUtils.cloneNode(doc, node);
189+
} catch (UnsupportedOperationException ex) {
190+
191+
}
192+
193+
}
194+
195+
public void testCloneNodeNewDocumentSaxon() throws Exception {
196+
String testString = "<ns1:parent xmlns:ns1=\"abc\">\n" +
197+
" <ns1:child xmlns=\"def\">\n" +
198+
" <ns2:nestedChild xmlns:ns2=\"def\"/>\n" +
199+
" </ns1:child>\n" +
200+
"</ns1:parent>";
201+
202+
String saxonString = "<ns1:parent xmlns:ns1=\"abc\">\n" +
203+
" <ns1:child xmlns=\"def\">\n" +
204+
" <nestedChild xmlns:ns2=\"def\"/>\n" +
205+
" </ns1:child>\n" +
206+
"</ns1:parent>";
207+
208+
Document doc = createSaxonDOM(testString);
209+
Document doc2 = DOMUtils.newDocument();
210+
Node node = doc.getFirstChild();
211+
Node clonedNode = DOMUtils.cloneNode(doc2, node);
212+
213+
assertNotSame("DOM's are the same", doc, doc2);
214+
String actualString = DOMUtils.domToString(clonedNode).replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "");
215+
assertEquals("XML Result", saxonString, actualString);
216+
217+
}
113218

219+
private Document createSaxonDOM(String testString)
220+
throws ParserConfigurationException, SAXException, IOException {
221+
System.setProperty(DOCUMENT_BUILDER_FACTORY, SAXON_DOM_DOCUMENT_BUILDER_FACTORY);
222+
DocumentBuilderFactory factory = DocumentBuilderFactoryImpl.newInstance();
223+
factory.setNamespaceAware(true);
224+
DocumentBuilder saxonBuilder = factory.newDocumentBuilder();
225+
Document doc = saxonBuilder.parse(new ByteArrayInputStream(testString.getBytes()));
226+
return doc;
227+
}
228+
114229
}

0 commit comments

Comments
 (0)