1 /*
   2  * Copyright (c) 1999, 2015, 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  */
  23 
  24 package javax.xml.parsers.ptests;
  25 
  26 import static org.testng.Assert.assertEquals;
  27 import static org.testng.Assert.assertNotNull;
  28 import static org.testng.Assert.assertNull;
  29 import java.io.BufferedReader;
  30 import java.io.File;
  31 import java.io.FileInputStream;
  32 import java.io.FilePermission;
  33 import java.io.FileReader;
  34 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
  35 import javax.xml.parsers.DocumentBuilder;
  36 import javax.xml.parsers.DocumentBuilderFactory;
  37 import javax.xml.parsers.SAXParser;
  38 import javax.xml.parsers.SAXParserFactory;
  39 import static javax.xml.parsers.ptests.ParserTestConst.GOLDEN_DIR;
  40 import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR;
  41 import javax.xml.transform.Transformer;
  42 import javax.xml.transform.TransformerFactory;
  43 import javax.xml.transform.dom.DOMSource;
  44 import javax.xml.transform.sax.SAXResult;
  45 import jaxp.library.JAXPFileBaseTest;
  46 import static jaxp.library.JAXPTestUtilities.USER_DIR;
  47 import static jaxp.library.JAXPTestUtilities.compareWithGold;
  48 import static org.testng.Assert.assertFalse;
  49 import static org.testng.Assert.assertTrue;
  50 import org.testng.annotations.Test;
  51 import org.w3c.dom.Document;
  52 import org.w3c.dom.Element;
  53 import org.w3c.dom.NodeList;
  54 import org.xml.sax.InputSource;
  55 import org.xml.sax.SAXException;
  56 import org.xml.sax.helpers.DefaultHandler;
  57 
  58 /**
  59  * This checks the methods of DocumentBuilderFactoryImpl.
  60  */
  61 public class DocumentBuilderFactoryTest extends JAXPFileBaseTest {
  62     /**
  63      * Test the default functionality of schema support method.
  64      * @throws Exception If any errors occur.
  65      */
  66     @Test
  67     public void testCheckSchemaSupport1() throws Exception {
  68         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  69         dbf.setValidating(true);
  70         dbf.setNamespaceAware(true);
  71         dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", 
  72                 W3C_XML_SCHEMA_NS_URI);
  73         MyErrorHandler eh = MyErrorHandler.newInstance();
  74         DocumentBuilder db = dbf.newDocumentBuilder();
  75         db.setErrorHandler(eh);
  76         db.parse(new File(XML_DIR, "test.xml"));
  77         assertFalse(eh.isErrorOccured());
  78     }
  79 
  80     /**
  81      * Test the default functionality of schema support method. In
  82      * this case the schema source property is set.
  83      * @throws Exception If any errors occur.
  84      */
  85     @Test
  86     public void testCheckSchemaSupport2() throws Exception {
  87         try (FileInputStream fis = new FileInputStream(new File(
  88                 XML_DIR, "test.xsd"))) {
  89             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  90             dbf.setValidating(true);
  91             dbf.setNamespaceAware(true);
  92             dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", 
  93                     W3C_XML_SCHEMA_NS_URI);
  94             dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", 
  95                     new InputSource(fis));
  96             MyErrorHandler eh = MyErrorHandler.newInstance();
  97             DocumentBuilder db = dbf.newDocumentBuilder();
  98             db.setErrorHandler(eh);
  99             db.parse(new File(XML_DIR, "test1.xml"));
 100             assertFalse(eh.isErrorOccured());
 101         }
 102     }
 103 
 104     /**
 105      * Test the default functionality of schema support method. In
 106      * this case the schema source property is set.
 107      * @throws Exception If any errors occur.
 108      */
 109     @Test
 110     public void testCheckSchemaSupport3() throws Exception {
 111         try (FileInputStream fis = new FileInputStream(new File(
 112                 XML_DIR, "test.xsd"))) {
 113             SAXParserFactory spf = SAXParserFactory.newInstance();
 114             spf.setNamespaceAware(true);
 115             spf.setValidating(true);
 116             spf.setNamespaceAware(true);
 117             SAXParser sp = spf.newSAXParser();
 118             sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", 
 119                     W3C_XML_SCHEMA_NS_URI);
 120             sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
 121                     new InputSource(fis));
 122             DefaultHandler dh = new DefaultHandler();
 123             // Not expect any unrecoverable error here.
 124             sp.parse(new File(XML_DIR, "test1.xml"), dh);
 125         }
 126     }
 127 
 128     /**
 129      * Test the default functionality of newInstance method. To test
 130      * the isCoalescing method and setCoalescing This checks to see if the CDATA
 131      * and text nodes got combined In that case it will print "<xml>This
 132      * is not parsed</xml> yet".
 133      * @throws Exception If any errors occur.
 134      */
 135     @Test
 136     public void testCheckDocumentBuilderFactory02() throws Exception {
 137         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 138         dbf.setCoalescing(true);
 139         DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 140         Document doc = docBuilder.parse(new File(XML_DIR, "DocumentBuilderFactory01.xml"));
 141         Element e = (Element) doc.getElementsByTagName("html").item(0);
 142         NodeList nl = e.getChildNodes();
 143         assertEquals(nl.getLength(), 1);
 144     }
 145 
 146     /**
 147      * Test the isIgnoringComments. By default it is false.
 148      */
 149     @Test
 150     public void testCheckDocumentBuilderFactory03() {
 151         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 152         assertFalse(dbf.isIgnoringComments());
 153     }
 154 
 155     /**
 156      * Test the isValidating. By default it is false, set it to true and then 
 157      * use a document which is not valid. It should throw a warning or
 158      * an error at least. The test passes in case retval 0 is set in the error
 159      * method .
 160      * @throws Exception If any errors occur.
 161      */
 162     @Test
 163     public void testCheckDocumentBuilderFactory04() throws Exception {
 164         MyErrorHandler eh = MyErrorHandler.newInstance();
 165         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 166         dbf.setValidating(true);
 167         DocumentBuilder db = dbf.newDocumentBuilder();
 168         db.setErrorHandler(eh);
 169         db.parse(new File(XML_DIR, "DocumentBuilderFactory05.xml"));
 170         assertTrue(eh.isErrorOccured());
 171     }
 172 
 173     /**
 174      * Test the setValidating. By default it is false, use a
 175      * document which is not valid. It should not throw a warning or an error.
 176      * The test passes in case the return value equals 1.
 177      * @throws Exception If any errors occur.
 178      */
 179     @Test
 180     public void testCheckDocumentBuilderFactory16() throws Exception {
 181         MyErrorHandler eh = MyErrorHandler.newInstance();
 182         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 183         DocumentBuilder db = dbf.newDocumentBuilder();
 184         db.setErrorHandler(eh);
 185         db.parse(new File(XML_DIR, "DocumentBuilderFactory05.xml"));
 186         assertFalse(eh.isErrorOccured());
 187     }
 188 
 189     /**
 190      * Test the setValidating. By default it is false, use a
 191      * document which is valid. It should not throw a warning or an error. The
 192      * test passes in case the return value equals 1.
 193      * @throws Exception If any errors occur.
 194      */
 195     @Test
 196     public void testCheckDocumentBuilderFactory17() throws Exception {
 197         MyErrorHandler eh = MyErrorHandler.newInstance();
 198         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 199         DocumentBuilder db = dbf.newDocumentBuilder();
 200         db.setErrorHandler(eh);
 201         db.parse(new File(XML_DIR, "DocumentBuilderFactory04.xml"));
 202         assertFalse(eh.isErrorOccured());
 203     }
 204 
 205     /**
 206      * Test the isExpandEntityReferences. By default it is true.
 207      * @throws Exception If any errors occur.
 208      */
 209     @Test
 210     public void testCheckDocumentBuilderFactory05() throws Exception {
 211         try(FileInputStream fis = new FileInputStream(new File(
 212                 XML_DIR, "DocumentBuilderFactory02.xml"))) {
 213             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 214             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 215             Document doc = docBuilder.parse(fis);
 216             Element e = (Element) doc.getElementsByTagName("title").item(0);
 217             NodeList nl = e.getChildNodes();
 218             assertTrue(dbf.isExpandEntityReferences());
 219             assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W');
 220         }
 221     }
 222 
 223     /**
 224      * Test the default functionality of setValidating method. The
 225      * XML file has a DTD which has namespaces defined. The parser takes care to
 226      * check if the namespaces using elements and defined attributes are there
 227      * or not.
 228      * @throws Exception If any errors occur.
 229      */
 230     @Test
 231     public void testCheckDocumentBuilderFactory06() throws Exception {
 232         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 233         dbf.setValidating(true);
 234         DocumentBuilder db = dbf.newDocumentBuilder();
 235         MyErrorHandler eh = MyErrorHandler.newInstance();
 236         db.setErrorHandler(eh);
 237         Document doc = db.parse(new File(XML_DIR, "DocumentBuilderFactory04.xml"));
 238         assertTrue(doc instanceof Document);
 239         assertFalse(eh.isErrorOccured());
 240     }
 241 
 242     /**
 243      * Test the setExpandEntityReferences.
 244      * @throws Exception If any errors occur.
 245      */
 246     @Test
 247     public void testCheckDocumentBuilderFactory07() throws Exception {
 248         try (FileInputStream fis = new FileInputStream(new File(
 249                 XML_DIR, "DocumentBuilderFactory02.xml"))) {
 250             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 251             dbf.setExpandEntityReferences(true);
 252             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 253             Document doc = docBuilder.parse(fis);
 254             Element e = (Element) doc.getElementsByTagName("title").item(0);
 255             NodeList nl = e.getChildNodes();
 256             assertTrue(dbf.isExpandEntityReferences());
 257             assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W');
 258         } 
 259     }
 260 
 261     /**
 262      * Test the setExpandEntityReferences.
 263      * @throws Exception If any errors occur.
 264      */
 265     @Test
 266     public void testCheckDocumentBuilderFactory08() throws Exception {
 267         try (FileInputStream fis = new FileInputStream(new File(
 268                 XML_DIR, "DocumentBuilderFactory02.xml"))) {
 269             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 270             dbf.setExpandEntityReferences(false);
 271             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 272             Document doc = docBuilder.parse(fis);
 273             Element e = (Element) doc.getElementsByTagName("title").item(0);
 274             NodeList nl = e.getChildNodes();
 275             assertNull(nl.item(0).getNodeValue());
 276         }
 277     }
 278 
 279     /**
 280      * Test the setIgnoringComments. By default it is set to false.
 281      * explicitly setting it to false, it recognizes the comment which is in
 282      * Element Node Hence the Element's child node is not null.
 283      * @throws Exception If any errors occur.
 284      */
 285     @Test
 286     public void testCheckDocumentBuilderFactory09() throws Exception {
 287         try (FileInputStream fis = new FileInputStream(new File(
 288                 XML_DIR, "DocumentBuilderFactory07.xml"))) {
 289             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 290             dbf.setIgnoringComments(false);
 291             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 292             Document doc = docBuilder.parse(fis);
 293             Element e = (Element) doc.getElementsByTagName("body").item(0);
 294             NodeList nl = e.getChildNodes();
 295             assertNotNull(nl.item(0).getNodeValue());
 296         }
 297     }
 298 
 299     /**
 300      * This tests for the parse(InputSource).
 301      * @throws Exception If any errors occur.
 302      */
 303     @Test
 304     public void testCheckDocumentBuilderFactory10() throws Exception {
 305         try (BufferedReader br = new BufferedReader(new FileReader(new File(
 306                 XML_DIR, "DocumentBuilderFactory07.xml")))) {
 307             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 308             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 309             Document doc = docBuilder.parse(new InputSource(br));
 310             assertNotNull(doc);
 311         } 
 312     }
 313 
 314     /**
 315      * This tests for the parse InputStream with SystemID as a second parameter.
 316      * @throws Exception If any errors occur.
 317      */
 318     @Test
 319     public void testCheckDocumentBuilderFactory11() throws Exception {
 320         try (FileInputStream fis = new FileInputStream(new File(
 321                 XML_DIR, "dbf10import.xsl"))) {
 322             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 323             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 324             Document doc = docBuilder.parse(fis, new File(XML_DIR).toURI()
 325                     .toASCIIString());
 326             assertNotNull(doc);
 327         }
 328     }
 329 
 330     /**
 331      * This tests for the parse InputStream with empty SystemID as a second
 332      * parameter.
 333      * @throws Exception If any errors occur.
 334      */
 335     @Test
 336     public void testCheckDocumentBuilderFactory12() throws Exception {
 337         try (FileInputStream fis = new FileInputStream(new File(
 338                 XML_DIR, "dbf10import.xsl"))) {
 339             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 340             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 341             Document doc = docBuilder.parse(fis, " ");
 342             assertNotNull(doc);
 343         }
 344     }
 345 
 346     /**
 347      * This tests for the parse(uri).
 348      * @throws Exception If any errors occur.
 349      */
 350     @Test
 351     public void testCheckDocumentBuilderFactory13() throws Exception {
 352         // Accesing default working directory.
 353         String workingDir = getSystemProperty("user.dir");
 354         setPermissions(new FilePermission(workingDir + "/*", "read"));
 355         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 356         DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 357         Document doc = docBuilder.parse(new File(XML_DIR + "dbf10import.xsl")
 358                 .toURI().toASCIIString());
 359         assertNotNull(doc);  
 360     }
 361 
 362     /**
 363      * This tests for the parse(uri) with empty string as parameter should
 364      * throw Sax Exception.
 365      * @throws Exception If any errors occur.
 366      */
 367     @Test(expectedExceptions = SAXException.class)
 368     public void testCheckDocumentBuilderFactory14() throws Exception {
 369         // Accesing default working directory.  
 370         String workingDir = getSystemProperty("user.dir");
 371         setPermissions(new FilePermission(workingDir, "read"));
 372         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 373         DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 374         docBuilder.parse("");
 375     }
 376 
 377     /**
 378      * This tests for the parse (uri) with null uri as parameter should throw
 379      * IllegalArgumentException.
 380      * @throws Exception If any errors occur.
 381      *
 382      */
 383     @Test(expectedExceptions = IllegalArgumentException.class)
 384     public void testCheckDocumentBuilderFactory15() throws Exception {
 385         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 386         DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 387         String uri = null;
 388         docBuilder.parse(uri);
 389     }
 390 
 391     /**
 392      * Test the setIgnoringComments. By default it is set to false,
 393      * setting this to true, It does not recognize the comment, Here the
 394      * nodelist has a length 0 because the ignoring comments is true.
 395      * @throws Exception If any errors occur.
 396      */
 397     @Test
 398     public void testCheckIgnoringComments() throws Exception {
 399         try (FileInputStream fis = new FileInputStream(new File(
 400                 XML_DIR, "DocumentBuilderFactory08.xml"))) {
 401             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 402             dbf.setIgnoringComments(true);
 403             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 404             Document doc = docBuilder.parse(fis);
 405             Element e = (Element) doc.getElementsByTagName("body").item(0);
 406             NodeList nl = e.getChildNodes();
 407             assertEquals(nl.getLength(), 0);
 408         }
 409     }
 410 
 411     /**
 412      * Test the default behaviour of setIgnoringComments. By default
 413      * it is set to false, this is similar to case 9 but not setIgnoringComments
 414      * explicitly, it does not recognize the comment.
 415      * @throws Exception If any errors occur.
 416      */
 417     @Test
 418     public void testCheckIgnoringComments1() throws Exception {
 419         try (FileInputStream fis = new FileInputStream(new File(
 420                 XML_DIR, "DocumentBuilderFactory07.xml"))) {
 421             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 422             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 423             Document doc = docBuilder.parse(fis);
 424             Element e = (Element) doc.getElementsByTagName("body").item(0);
 425             NodeList nl = e.getChildNodes();
 426             assertFalse(dbf.isIgnoringComments());
 427             assertNotNull(nl.item(0).getNodeValue());
 428         }
 429     }
 430 
 431     /**
 432      * Test for the isIgnoringElementContentWhitespace and the
 433      * setIgnoringElementContentWhitespace. The xml file has all kinds of
 434      * whitespace,tab and newline characters, it uses the MyNSContentHandler
 435      * which does not invoke the characters callback when this
 436      * setIgnoringElementContentWhitespace is set to true.
 437      * @throws Exception If any errors occur.
 438      */
 439     @Test
 440     public void testCheckElementContentWhitespace() throws Exception {
 441         String goldFile = GOLDEN_DIR + "dbfactory02GF.out";
 442         String outputFile = USER_DIR + "dbfactory02.out";
 443         MyErrorHandler eh = MyErrorHandler.newInstance();
 444         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 445         dbf.setValidating(true);
 446         assertFalse(dbf.isIgnoringElementContentWhitespace());
 447         dbf.setIgnoringElementContentWhitespace(true);
 448         DocumentBuilder db = dbf.newDocumentBuilder();
 449         db.setErrorHandler(eh);
 450         Document doc = db.parse(new File(XML_DIR, "DocumentBuilderFactory06.xml"));
 451         assertFalse(eh.isErrorOccured());
 452         DOMSource domSource = new DOMSource(doc);
 453         TransformerFactory tfactory = TransformerFactory.newInstance();
 454         Transformer transformer = tfactory.newTransformer();
 455         SAXResult saxResult = new SAXResult();
 456         try(MyCHandler handler = MyCHandler.newInstance(new File(outputFile))) {
 457             saxResult.setHandler(handler);
 458             transformer.transform(domSource, saxResult);
 459         }
 460         assertTrue(compareWithGold(goldFile, outputFile));
 461     }
 462 }