1/*
2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.w3c.dom.ptests;
24
25import static jaxp.library.JAXPTestUtilities.USER_DIR;
26import static jaxp.library.JAXPTestUtilities.compareWithGold;
27import static jaxp.library.JAXPTestUtilities.tryRunWithTmpPermission;
28import static org.testng.Assert.assertEquals;
29import static org.testng.Assert.assertFalse;
30import static org.testng.Assert.assertNotEquals;
31import static org.testng.Assert.assertTrue;
32import static org.w3c.dom.ptests.DOMTestUtil.GOLDEN_DIR;
33import static org.w3c.dom.ptests.DOMTestUtil.createDOM;
34import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS;
35import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument;
36
37import java.io.File;
38import java.util.PropertyPermission;
39
40import javax.xml.transform.Transformer;
41import javax.xml.transform.TransformerException;
42import javax.xml.transform.TransformerFactory;
43import javax.xml.transform.TransformerFactoryConfigurationError;
44import javax.xml.transform.dom.DOMSource;
45import javax.xml.transform.stream.StreamResult;
46
47import org.testng.annotations.DataProvider;
48import org.testng.annotations.Listeners;
49import org.testng.annotations.Test;
50import org.w3c.dom.DOMException;
51import org.w3c.dom.Document;
52import org.w3c.dom.DocumentFragment;
53import org.w3c.dom.Element;
54import org.w3c.dom.Node;
55import org.w3c.dom.NodeList;
56
57/*
58 * @test
59 * @library /javax/xml/jaxp/libs
60 * @run testng/othervm -DrunSecMngr=true org.w3c.dom.ptests.NodeTest
61 * @run testng/othervm org.w3c.dom.ptests.NodeTest
62 * @summary Test Node interface
63 */
64@Listeners({jaxp.library.FilePolicy.class})
65public class NodeTest {
66    @DataProvider(name = "feature-supported")
67    public Object[][] getFeatureSupportedList() throws Exception {
68        Document document = createDOMWithNS("Node01.xml");
69        Node node = document.getElementsByTagName("body").item(0);
70        return new Object[][] {
71                { node, "XML", "2.0", true },
72                { node, "HTML", "2.0", false },
73                { node, "Views", "2.0", false },
74                { node, "StyleSheets", "2.0", false },
75                { node, "CSS", "2.0", false },
76                { node, "CSS2", "2.0", false },
77                { node, "Events", "2.0", true },
78                { node, "UIEvents", "2.0", false },
79                { node, "MouseEvents", "2.0", false },
80                { node, "HTMLEvents", "2.0", false },
81                { node, "Traversal", "2.0", true },
82                { node, "Range", "2.0", true } };
83    }
84
85    /*
86     * Verify Node for feature supporting.
87     */
88    @Test(dataProvider = "feature-supported")
89    public void testHasFeature(Node node, String feature, String version, boolean supported) {
90        assertEquals(node.isSupported(feature, version), supported);
91    }
92
93    /*
94     * Test normalize method will merge adjacent Text nodes.
95     */
96    @Test
97    public void testNormalize() throws Exception {
98        Document document = createDOM("Node05.xml");
99
100        Element root = document.getDocumentElement();
101
102        Node node =  document.getElementsByTagName("title").item(0);
103        node.appendChild(document.createTextNode("test"));
104        root.normalize();
105        assertEquals(node.getChildNodes().item(0).getNodeValue(), "Typographytest");
106    }
107
108    /*
109     * Test cloneNode deeply, and the clone node can be appended on the same document.
110     */
111    @Test
112    public void testCloneNode() throws Exception {
113        Document document = createDOMWithNS("Node02.xml");
114
115        NodeList nodeList = document.getElementsByTagName("body");
116        Node node = nodeList.item(0);
117        Node cloneNode = node.cloneNode(true);
118
119        assertTrue(node.isEqualNode(cloneNode));
120        assertNotEquals(node, cloneNode);
121
122        nodeList = document.getElementsByTagName("html");
123        Node node2 = nodeList.item(0);
124        node2.appendChild(cloneNode);
125    }
126
127    /*
128     * Test importing node from one document to another.
129     */
130    @Test
131    public void testImportNode() throws Exception {
132        Document document = createDOMWithNS("Node02.xml");
133        Document otherDocument = createDOMWithNS("ElementSample01.xml");
134
135        NodeList otherNodeList = otherDocument.getElementsByTagName("body");
136        Node importedNode = otherNodeList.item(0);
137        Node clone = importedNode.cloneNode(true);
138
139        Node retNode = document.importNode(importedNode, true);
140        assertTrue(clone.isEqualNode(importedNode)); //verify importedNode is not changed
141        assertNotEquals(retNode, importedNode);
142        assertTrue(importedNode.isEqualNode(retNode));
143
144        retNode = document.importNode(importedNode, false);
145        assertTrue(clone.isEqualNode(importedNode)); //verify importedNode is not changed
146        assertEquals(retNode.getNodeName(), importedNode.getNodeName());
147        assertFalse(importedNode.isEqualNode(retNode));
148    }
149
150    /*
151     * Test inserting a document fragment before a particular node.
152     */
153    @Test
154    public void testInsertBefore() throws Exception {
155        Document document = createDOM("Node04.xml");
156
157        Element parentElement = (Element) document.getElementsByTagName("to").item(0);
158        Element element = (Element) document.getElementsByTagName("sender").item(0);
159        parentElement.insertBefore(createTestDocumentFragment(document), element);
160
161        String outputfile = USER_DIR + "InsertBefore.out";
162        String goldfile = GOLDEN_DIR + "InsertBeforeGF.out";
163        tryRunWithTmpPermission(() -> outputXml(document, outputfile), new PropertyPermission("user.dir", "read"));
164        assertTrue(compareWithGold(goldfile, outputfile));
165    }
166
167
168    /*
169     * Test replacing a particular node with a document fragment.
170     */
171    @Test
172    public void testReplaceChild() throws Exception {
173        Document document = createDOM("Node04.xml");
174
175        Element parentElement = (Element) document.getElementsByTagName("to").item(0);
176        Element element = (Element) document.getElementsByTagName("sender").item(0);
177        parentElement.replaceChild(createTestDocumentFragment(document), element);
178
179        String outputfile = USER_DIR + "ReplaceChild3.out";
180        String goldfile = GOLDEN_DIR + "ReplaceChild3GF.out";
181        tryRunWithTmpPermission(() -> outputXml(document, outputfile), new PropertyPermission("user.dir", "read"));
182        assertTrue(compareWithGold(goldfile, outputfile));
183    }
184
185    /*
186     * This test case checks for the replaceChild replacing a particular node
187     * with a node which was created from a different document than the one
188     * which is trying to use this method. It should throw a DOMException.
189     */
190    @Test(expectedExceptions = DOMException.class)
191    public void testReplaceChildNeg() throws Exception {
192        Document document = createDOM("Node04.xml");
193        Document doc2 = createNewDocument();
194
195        Element parentElement = (Element) document.getElementsByTagName("to").item(0);
196        Element element = (Element) document.getElementsByTagName("sender").item(0);
197        parentElement.replaceChild(createTestDocumentFragment(doc2), element);
198    }
199
200    private DocumentFragment createTestDocumentFragment(Document document) {
201        DocumentFragment docFragment = document.createDocumentFragment();
202        Element elem = document.createElement("dfElement");
203        elem.appendChild(document.createTextNode("Text in it"));
204        docFragment.appendChild(elem);
205        return docFragment;
206    }
207
208    private void outputXml(Document document, String outputFileName) throws TransformerFactoryConfigurationError, TransformerException {
209        DOMSource domSource = new DOMSource(document);
210        Transformer transformer = TransformerFactory.newInstance().newTransformer();
211        StreamResult streamResult = new StreamResult(new File(outputFileName));
212        transformer.transform(domSource, streamResult);
213    }
214}
215