test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java
changeset 54628 dcb78d2f07e5
parent 52721 732bec44c89e
equal deleted inserted replaced
54627:22323f20401b 54628:dcb78d2f07e5
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    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 }