20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 package dom; |
23 package dom; |
24 |
24 |
|
25 import com.sun.org.apache.xerces.internal.dom.AttrImpl; |
|
26 import com.sun.org.apache.xerces.internal.dom.DocumentImpl; |
|
27 import com.sun.org.apache.xerces.internal.dom.ElementImpl; |
|
28 import com.sun.org.apache.xerces.internal.dom.events.MutationEventImpl; |
|
29 import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; |
25 import java.io.ByteArrayInputStream; |
30 import java.io.ByteArrayInputStream; |
26 import java.io.IOException; |
|
27 import java.io.InputStream; |
31 import java.io.InputStream; |
28 import javax.xml.parsers.DocumentBuilder; |
32 import javax.xml.parsers.DocumentBuilder; |
29 import javax.xml.parsers.DocumentBuilderFactory; |
33 import javax.xml.parsers.DocumentBuilderFactory; |
30 import org.testng.Assert; |
34 import org.testng.Assert; |
31 import org.testng.annotations.Listeners; |
35 import org.testng.annotations.Listeners; |
32 import org.testng.annotations.Test; |
36 import org.testng.annotations.Test; |
33 import org.w3c.dom.Document; |
37 import org.w3c.dom.Document; |
34 import org.w3c.dom.Element; |
38 import org.w3c.dom.Element; |
35 import org.w3c.dom.Node; |
39 import org.w3c.dom.Node; |
36 import org.xml.sax.SAXException; |
40 import org.w3c.dom.events.Event; |
|
41 import org.w3c.dom.events.EventListener; |
37 |
42 |
38 /* |
43 /* |
39 * @test |
44 * @test |
40 * @bug 8213117 |
45 * @bug 8213117 8222743 |
41 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest |
46 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest |
|
47 * @modules java.xml |
|
48 * @modules java.xml/com.sun.org.apache.xerces.internal.dom |
|
49 * @modules java.xml/com.sun.org.apache.xerces.internal.dom.events |
|
50 * @modules java.xml/com.sun.org.apache.xerces.internal.jaxp |
42 * @run testng dom.DocumentTest |
51 * @run testng dom.DocumentTest |
43 * @summary Tests functionalities for Document. |
52 * @summary Tests functionalities for Document. |
44 */ |
53 */ |
45 @Listeners({jaxp.library.BasePolicy.class}) |
54 @Listeners({jaxp.library.BasePolicy.class}) |
46 public class DocumentTest { |
55 public class DocumentTest { |
47 |
56 static final int DOC1 = 1; |
48 private static final String XML1 = "<root><oldNode oldAttrib1=\"old value 1\" oldAttrib2=\"old value 2\"></oldNode></root>"; |
57 static final int DOC2 = 2; |
49 private static final String XML2 = "<root><newNode newAttrib=\"new value\"></newNode></root>"; |
|
50 |
58 |
51 /** |
59 /** |
52 * Verifies the adoptNode method. Before a node from a deferred DOM can be |
60 * Verifies the adoptNode method. Before a node from a deferred DOM can be |
53 * adopted, it needs to be fully expanded. |
61 * adopted, it needs to be fully expanded. |
54 */ |
62 */ |
55 @Test |
63 @Test |
56 public void testAdoptNode() throws Exception { |
64 public void testAdoptNode() throws Exception { |
|
65 String xml1 = "<root><oldNode oldAttrib1=\"old value 1\" oldAttrib2=\"old value 2\"></oldNode></root>"; |
|
66 String xml2 = "<root><newNode newAttrib=\"new value\"></newNode></root>"; |
57 |
67 |
58 DocumentBuilder builder = DocumentBuilderFactory.newInstance() |
68 Document doc1 = getDocument(xml1); |
59 .newDocumentBuilder(); |
69 Document doc2 = getDocument(xml2); |
60 |
|
61 Document doc1 = getDocument(builder, XML1); |
|
62 Document doc2 = getDocument(builder, XML2); |
|
63 |
70 |
64 Element newNode = (Element) doc2.getFirstChild().getFirstChild(); |
71 Element newNode = (Element) doc2.getFirstChild().getFirstChild(); |
65 Element replacementNode = (Element) doc1.adoptNode(newNode); |
72 Element replacementNode = (Element) doc1.adoptNode(newNode); |
66 |
73 |
67 Node oldNode = doc1.getFirstChild().getFirstChild(); |
74 Node oldNode = doc1.getFirstChild().getFirstChild(); |
70 String attrValue = doc1.getFirstChild().getFirstChild().getAttributes() |
77 String attrValue = doc1.getFirstChild().getFirstChild().getAttributes() |
71 .getNamedItem("newAttrib").getNodeValue(); |
78 .getNamedItem("newAttrib").getNodeValue(); |
72 Assert.assertEquals(attrValue, "new value"); |
79 Assert.assertEquals(attrValue, "new value"); |
73 } |
80 } |
74 |
81 |
75 private static Document getDocument(DocumentBuilder builder, String xml) throws SAXException, IOException { |
82 /** |
|
83 * Verifies that the lookupNamespaceURI method returns null (not empty string) |
|
84 * for unbound prefix. |
|
85 * |
|
86 * Specification for lookupNamespaceURI: |
|
87 * Returns the associated namespace URI or null if none is found. |
|
88 * |
|
89 * @throws Exception |
|
90 */ |
|
91 @Test |
|
92 public void testUnboundNamespaceURI() throws Exception { |
|
93 String xml = "<?xml version='1.1'?>" |
|
94 + "<root><e1 xmlns='' xmlns:p1='' xmlns:p2='uri2'><e2/></e1></root>"; |
|
95 |
|
96 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); |
|
97 Document doc = getDocument(xml); |
|
98 Element e1 = doc.getDocumentElement(); |
|
99 Element e2 = (Element)e1.getFirstChild().getFirstChild(); |
|
100 |
|
101 Assert.assertEquals(e1.lookupNamespaceURI(null), null); |
|
102 Assert.assertEquals(e2.lookupNamespaceURI(null), null); |
|
103 |
|
104 Assert.assertEquals(e1.lookupNamespaceURI("p1"), null); |
|
105 Assert.assertEquals(e2.lookupNamespaceURI("p1"), null); |
|
106 |
|
107 Assert.assertEquals(e1.lookupNamespaceURI("p2"), null); |
|
108 Assert.assertEquals(e2.lookupNamespaceURI("p2"), "uri2"); |
|
109 } |
|
110 |
|
111 /** |
|
112 * Verifies that calling namespace methods on an empty document won't result |
|
113 * in a NPE. |
|
114 * @throws Exception |
|
115 */ |
|
116 @Test |
|
117 public void testNamespaceNPE() throws Exception { |
|
118 Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); |
|
119 document.lookupNamespaceURI("prefix"); |
|
120 document.lookupPrefix("uri"); |
|
121 document.isDefaultNamespace("uri"); |
|
122 } |
|
123 |
|
124 /** |
|
125 * Verifies that manipulating an independent document from within a mutation |
|
126 * listener does not modify the original event object. |
|
127 */ |
|
128 @Test |
|
129 public void testMutation() throws Exception { |
|
130 String xml1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
|
131 + "<root><a a_attr=\"a_attr_value\"/></root>"; |
|
132 String xml2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
|
133 + "<root><b b_attr=\"b_attr_value\"/></root>"; |
|
134 DocumentBuilder db = DocumentBuilderFactoryImpl.newInstance().newDocumentBuilder(); |
|
135 DocumentImpl doc1 = (DocumentImpl)getDocument(xml1); |
|
136 DocumentImpl doc2 = (DocumentImpl)getDocument(xml2); |
|
137 ElementImpl a = (ElementImpl) doc1.getDocumentElement().getFirstChild(); |
|
138 AttrImpl attr = (AttrImpl) a.getAttributeNode("a_attr"); |
|
139 attr.addEventListener(MutationEventImpl.DOM_NODE_REMOVED, new MyEventListener(DOC1, doc2), false); |
|
140 doc2.addEventListener(MutationEventImpl.DOM_ATTR_MODIFIED, new MyEventListener(DOC2), true); |
|
141 |
|
142 // make a change to doc1 to trigger the event |
|
143 Element a1 = (Element) doc1.getDocumentElement().getFirstChild(); |
|
144 a1.setAttribute("a_attr", "a_attr_newvalue"); |
|
145 } |
|
146 |
|
147 private static Document getDocument(String xml) throws Exception { |
|
148 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
|
149 dbf.setNamespaceAware(true); |
|
150 DocumentBuilder db = dbf.newDocumentBuilder(); |
76 InputStream a = new ByteArrayInputStream(xml.getBytes()); |
151 InputStream a = new ByteArrayInputStream(xml.getBytes()); |
77 Document out = builder.parse(a); |
152 Document out = db.parse(a); |
78 return out; |
153 return out; |
79 } |
154 } |
80 |
155 |
|
156 // EventListener that mutates an unrelated document when an event is received. |
|
157 static class MyEventListener implements EventListener { |
|
158 |
|
159 private int docId; |
|
160 private Document doc = null; |
|
161 |
|
162 public MyEventListener(int docId) { |
|
163 this.docId = docId; |
|
164 } |
|
165 |
|
166 public MyEventListener(int docId, Document doc) { |
|
167 this.docId = docId; |
|
168 this.doc = doc; |
|
169 } |
|
170 |
|
171 public void handleEvent(Event evt) { |
|
172 if (docId == DOC1) { |
|
173 //check the related node before making changes |
|
174 checkRelatedNode(evt, "a_attr_value"); |
|
175 //make a change to doc2 |
|
176 Element ele = (Element)doc.getDocumentElement().getFirstChild(); |
|
177 ele.setAttribute("b_attr", "value for b_attr in doc2"); |
|
178 //check the related node again after the change |
|
179 checkRelatedNode(evt, "a_attr_value"); |
|
180 } else { //DOC2 |
|
181 checkRelatedNode(evt, "value for b_attr in doc2"); |
|
182 } |
|
183 } |
|
184 |
|
185 } |
|
186 |
|
187 // Utility method to display an event |
|
188 public static void checkRelatedNode(Event evt, String expected) { |
|
189 //System.out.println(" Event: " + evt + ", on " + evt.getTarget()); |
|
190 if (evt instanceof MutationEventImpl) { |
|
191 MutationEventImpl mutation = (MutationEventImpl) evt; |
|
192 //System.out.println(" + Related: " + mutation.getRelatedNode()); |
|
193 Assert.assertTrue(mutation.getRelatedNode().toString().contains(expected)); |
|
194 } |
|
195 } |
81 } |
196 } |