1 /*
   2  * Copyright (c) 2003, 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 package org.xml.sax.ptests;
  24 
  25 import java.io.FileInputStream;
  26 import javax.xml.parsers.SAXParserFactory;
  27 import jaxp.library.JAXPFileReadOnlyBaseTest;
  28 import static org.testng.Assert.assertEquals;
  29 import static org.testng.Assert.assertFalse;
  30 import static org.testng.Assert.assertNotNull;
  31 import static org.testng.Assert.assertNull;
  32 import static org.testng.Assert.assertTrue;
  33 import org.testng.annotations.Test;
  34 import org.xml.sax.InputSource;
  35 import org.xml.sax.SAXException;
  36 import org.xml.sax.SAXNotRecognizedException;
  37 import org.xml.sax.SAXNotSupportedException;
  38 import org.xml.sax.XMLReader;
  39 import org.xml.sax.ext.DeclHandler;
  40 import org.xml.sax.ext.LexicalHandler;
  41 import org.xml.sax.helpers.XMLFilterImpl;
  42 import static org.xml.sax.ptests.SAXTestConst.XML_DIR;
  43 
  44 /**
  45  * Class containing the test cases for SAXParser API
  46  */
  47 public class XMLReaderTest extends JAXPFileReadOnlyBaseTest {
  48 
  49     /**
  50      * XML namespaces.
  51      */
  52     private static final String NAMESPACES
  53             = "http://xml.org/sax/features/namespaces";
  54 
  55     /**
  56      * XML namespaces prefixes.
  57      */
  58     private static final String NAMESPACE_PREFIXES
  59             = "http://xml.org/sax/features/namespace-prefixes";
  60 
  61     /**
  62      * A string intern name.
  63      */
  64     private static final String STRING_INTERNING
  65             = "http://xml.org/sax/features/string-interning";
  66 
  67     /**
  68      * Validation name.
  69      */
  70     private static final String VALIDATION
  71             = "http://xml.org/sax/features/validation";
  72 
  73     /**
  74      * A general external entities name
  75      */
  76     private static final String EXTERNAL_G_ENTITIES
  77             = "http://xml.org/sax/features/external-general-entities";
  78 
  79     /**
  80      * A external parameter entities name
  81      */
  82     private static final String EXTERNAL_P_ENTITIES
  83             = "http://xml.org/sax/features/external-parameter-entities";
  84 
  85     /**
  86      * XML DOM node name.
  87      */
  88     private static final String DOM_NODE = "http://xml.org/sax/properties/dom-node";
  89 
  90     /**
  91      * XML String name.
  92      */
  93     private static final String XML_STRING = "http://xml.org/sax/properties/xml-string";
  94 
  95     /**
  96      * Declare handler name
  97      */
  98     private static final String DECL_HANDLER
  99             = "http://xml.org/sax/properties/declaration-handler";
 100 
 101     /**
 102      * Lexical handler name
 103      */
 104     private static final String LEXICAL_HANDLER
 105             = "http://xml.org/sax/properties/lexical-handler";
 106 
 107     /**
 108      * According to the SAX2 specs, All XMLReaders are required to recognize the
 109      * http://xml.org/sax/features/namespaces feature names. This test case is
 110      * to test this.
 111      *
 112      * @throws Exception If any errors occur.
 113      */
 114     @Test
 115     public void featureNS01() throws Exception {
 116         SAXParserFactory spf = SAXParserFactory.newInstance();
 117         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 118         assertFalse(xmlReader.getFeature(NAMESPACES));
 119     }
 120 
 121     /**
 122      * According to the SAX2 specs, All XMLReaders are required to recognize the
 123      * http://xml.org/sax/features/namespaces feature names. This test case is
 124      * to test this.
 125      *
 126      * @throws Exception If any errors occur.
 127      */
 128     @Test
 129     public void featureNS02() throws Exception {
 130         SAXParserFactory spf = SAXParserFactory.newInstance();
 131         spf.setNamespaceAware(true);
 132         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 133         assertTrue(xmlReader.getFeature(NAMESPACES));
 134     }
 135 
 136     /**
 137      * Obtain http://xml.org/sax/features/namespaces feature name after it's
 138      * just set. Expect it's same as set value.
 139      *
 140      * @throws Exception If any errors occur.
 141      */
 142     @Test
 143     public void featureNS03() throws Exception {
 144         SAXParserFactory spf = SAXParserFactory.newInstance();
 145         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 146         xmlReader.setFeature(NAMESPACES, true);
 147         assertTrue(xmlReader.getFeature(NAMESPACES));
 148         xmlReader.setFeature(NAMESPACES, false);
 149         assertFalse(xmlReader.getFeature(NAMESPACES));
 150     }
 151 
 152     /**
 153      * According to the SAX2 specs, All XMLReaders are required to recognize the
 154      * http://xml.org/sax/features/namespace-prefixes feature names. This test
 155      * case is to test this.
 156      *
 157      * @throws Exception If any errors occur.
 158      */
 159     @Test
 160     public void featureNSP01() throws Exception {
 161         SAXParserFactory spf = SAXParserFactory.newInstance();
 162         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 163         assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES));
 164     }
 165 
 166     /**
 167      * According to the SAX2 specs, All XMLReaders are required to recognize the
 168      * http://xml.org/sax/features/namespace-prefixes feature names. This test
 169      * case is to test this.
 170      *
 171      * @throws Exception If any errors occur.
 172      */
 173     @Test
 174     public void featureNSP02() throws Exception {
 175         SAXParserFactory spf = SAXParserFactory.newInstance();
 176         spf.setNamespaceAware(true);
 177         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 178         assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES));
 179     }
 180 
 181     /**
 182      * Obtain http://xml.org/sax/features/namespaces-prefixes feature name after
 183      * it's just set. Expect it's same as set value.
 184      *
 185      * @throws Exception If any errors occur.
 186      */
 187     @Test
 188     public void featureNSP03() throws Exception {
 189         SAXParserFactory spf = SAXParserFactory.newInstance();
 190         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 191         xmlReader.setFeature(NAMESPACE_PREFIXES, true);
 192         assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES));
 193         xmlReader.setFeature(NAMESPACE_PREFIXES, false);
 194         assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES));
 195     }
 196 
 197     /**
 198      * getFeature returns true if a feature has not been preset when namespace
 199      * awareness is set.
 200      *
 201      * @throws Exception If any errors occur.
 202      */
 203     @Test
 204     public void featureSI01() throws Exception {
 205         SAXParserFactory spf = SAXParserFactory.newInstance();
 206         spf.setNamespaceAware(true);
 207         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 208         assertTrue(xmlReader.getFeature(STRING_INTERNING));
 209     }
 210 
 211     /**
 212      * getFeature with validation feature name returns the value that
 213      * setValidation set.
 214      *
 215      * @throws Exception If any errors occur.
 216      */
 217     @Test
 218     public void featureV01() throws Exception {
 219         SAXParserFactory spf = SAXParserFactory.newInstance();
 220         assertFalse(spf.newSAXParser().getXMLReader().getFeature(VALIDATION));
 221         spf.setValidating(true);
 222         assertTrue(spf.newSAXParser().getXMLReader().getFeature(VALIDATION));
 223     }
 224 
 225     /**
 226      * getFeature returns the value that a feature has been preset as when
 227      * namespace awareness is set.
 228      *
 229      * @throws Exception If any errors occur.
 230      */
 231     @Test
 232     public void featureV02() throws Exception {
 233         SAXParserFactory spf = SAXParserFactory.newInstance();
 234         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 235 
 236         xmlReader.setFeature(VALIDATION, true);
 237         assertTrue(xmlReader.getFeature(VALIDATION));
 238         xmlReader.setFeature(VALIDATION, false);
 239         assertFalse(xmlReader.getFeature(VALIDATION));
 240     }
 241 
 242     /**
 243      * getFeature returns true if a feature has not been preset when namespace
 244      * awareness is set.
 245      *
 246      * @throws Exception If any errors occur.
 247      */
 248     @Test
 249     public void featureEGE01() throws Exception {
 250         SAXParserFactory spf = SAXParserFactory.newInstance();
 251         spf.setNamespaceAware(true);
 252         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 253         assertTrue(xmlReader.getFeature(EXTERNAL_G_ENTITIES));
 254     }
 255 
 256     /**
 257      * getFeature returns false if a feature has been preset as false when
 258      * namespace awareness is set.
 259      *
 260      * @throws Exception If any errors occur.
 261      */
 262     @Test
 263     public void featureEGE02() throws Exception {
 264         SAXParserFactory spf = SAXParserFactory.newInstance();
 265         spf.setNamespaceAware(true);
 266         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 267         xmlReader.setFeature(EXTERNAL_G_ENTITIES, false);
 268         assertFalse(xmlReader.getFeature(EXTERNAL_G_ENTITIES));
 269     }
 270 
 271     /**
 272      * getFeature returns true if a feature has not been preset when namespace
 273      * awareness is set.
 274      *
 275      * @throws Exception If any errors occur.
 276      */
 277     @Test
 278     public void featureEPE01() throws Exception {
 279         SAXParserFactory spf = SAXParserFactory.newInstance();
 280         spf.setNamespaceAware(true);
 281         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 282         assertTrue(xmlReader.getFeature(EXTERNAL_P_ENTITIES));
 283     }
 284 
 285     /**
 286      * getFeature returns false if a feature has been preset as false when
 287      * namespace awareness is set.
 288      *
 289      * @throws Exception If any errors occur.
 290      */
 291     @Test
 292     public void featureEPE02() throws Exception {
 293         SAXParserFactory spf = SAXParserFactory.newInstance();
 294         spf.setNamespaceAware(true);
 295         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 296         xmlReader.setFeature(EXTERNAL_P_ENTITIES, false);
 297         assertFalse(xmlReader.getFeature(EXTERNAL_P_ENTITIES));
 298     }
 299 
 300     /**
 301      * getFeature with a unknown feature name throws SAXNotRecognizedException.
 302      *
 303      * @throws Exception If any errors occur.
 304      */
 305     @Test(expectedExceptions = SAXNotRecognizedException.class)
 306     public void featureNE01() throws Exception {
 307         SAXParserFactory spf = SAXParserFactory.newInstance();
 308         spf.setNamespaceAware(true);
 309         spf.newSAXParser().getXMLReader().getFeature("no-meaning-feature");
 310     }
 311 
 312     /**
 313      * No exception expected when set entity resolver as simple entity resolver.
 314      *
 315      * @throws Exception If any errors occur.
 316      */
 317     @Test
 318     public void entity01() throws Exception {
 319         SAXParserFactory spf = SAXParserFactory.newInstance();
 320         spf.setNamespaceAware(true);
 321         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 322         XMLFilterImpl xmlFilter = new XMLFilterImpl();
 323         xmlReader.setEntityResolver(xmlFilter);
 324         assertEquals(xmlReader.getEntityResolver(), xmlFilter);
 325     }
 326 
 327     /**
 328      * No NPE expected when set entity resolver as null.
 329      *
 330      * @throws Exception If any errors occur.
 331      */
 332     @Test
 333     public void entity02() throws Exception {
 334         SAXParserFactory spf = SAXParserFactory.newInstance();
 335         spf.setNamespaceAware(true);
 336         spf.newSAXParser().getXMLReader().setEntityResolver(null);
 337     }
 338 
 339     /**
 340      * No exception expected when set DTD handler as simple DTD handler.
 341      *
 342      * @throws Exception If any errors occur.
 343      */
 344     @Test
 345     public void dtdhandler01() throws Exception {
 346         SAXParserFactory spf = SAXParserFactory.newInstance();
 347         spf.setNamespaceAware(true);
 348         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 349         XMLFilterImpl xmlFilter = new XMLFilterImpl();
 350         xmlReader.setDTDHandler(xmlFilter);
 351         assertEquals(xmlReader.getDTDHandler(), xmlFilter);
 352     }
 353 
 354     /**
 355      * No NPE expected when set DTD handler as null.
 356      *
 357      * @throws Exception If any errors occur.
 358      */
 359     @Test
 360     public void dtdhandler02() throws Exception {
 361         SAXParserFactory spf = SAXParserFactory.newInstance();
 362         spf.setNamespaceAware(true);
 363         spf.newSAXParser().getXMLReader().setDTDHandler(null);
 364     }
 365 
 366     /**
 367      * No exception expected when set content handler as simple content handler.
 368      *
 369      * @throws Exception If any errors occur.
 370      */
 371     @Test
 372     public void contenthandler01() throws Exception {
 373         SAXParserFactory spf = SAXParserFactory.newInstance();
 374         spf.setNamespaceAware(true);
 375         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 376         XMLFilterImpl xmlFilter = new XMLFilterImpl();
 377         xmlReader.setContentHandler(xmlFilter);
 378         assertEquals(xmlReader.getContentHandler(), xmlFilter);
 379     }
 380 
 381     /**
 382      * No NPE expected when set content handler as null.
 383      *
 384      * @throws Exception If any errors occur.
 385      */
 386     @Test
 387     public void contenthandler02() throws Exception {
 388         SAXParserFactory spf = SAXParserFactory.newInstance();
 389         spf.setNamespaceAware(true);
 390         spf.newSAXParser().getXMLReader().setContentHandler(null);
 391     }
 392 
 393     /**
 394      * No exception expected when set content handler as simple error handler.
 395      *
 396      * @throws Exception If any errors occur.
 397      */
 398     @Test
 399     public void errorhandler01() throws Exception {
 400         SAXParserFactory spf = SAXParserFactory.newInstance();
 401         spf.setNamespaceAware(true);
 402         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 403         xmlReader.setErrorHandler(new XMLFilterImpl());
 404         assertNotNull(xmlReader.getErrorHandler());
 405     }
 406 
 407     /**
 408      * No NPE expected when set error handler as null.
 409      *
 410      * @throws Exception If any errors occur.
 411      */
 412     @Test
 413     public void errorhandler02() throws Exception {
 414         SAXParserFactory spf = SAXParserFactory.newInstance();
 415         spf.setNamespaceAware(true);
 416         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 417         xmlReader.setErrorHandler(null);
 418     }
 419 
 420     /**
 421      * Parse a null input source throw NPE.
 422      *
 423      * @throws Exception If any errors occur.
 424      */
 425     @Test(expectedExceptions = NullPointerException.class)
 426     public void parse01() throws Exception {
 427         SAXParserFactory spf = SAXParserFactory.newInstance();
 428         spf.setNamespaceAware(true);
 429         spf.newSAXParser().getXMLReader().parse((InputSource) null);
 430     }
 431 
 432     /**
 433      * Unit test for parse a error-formatted file. SAXException is expected.
 434      *
 435      * @throws Exception If any errors occur.
 436      */
 437     @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class)
 438     public void parse02() throws Exception {
 439         try (FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) {
 440             SAXParserFactory spf = SAXParserFactory.newInstance();
 441             spf.setNamespaceAware(true);
 442             spf.newSAXParser().getXMLReader().parse(new InputSource(fis));
 443         }
 444     }
 445 
 446     /**
 447      * Unit test for parse a well-formatted file. No exception is expected.
 448      *
 449      * @throws Exception If any errors occur.
 450      */
 451     @Test(groups = {"readLocalFiles"})
 452     public void parse03() throws Exception {
 453         try (FileInputStream fis = new FileInputStream(XML_DIR + "correct2.xml")) {
 454             SAXParserFactory spf = SAXParserFactory.newInstance();
 455             spf.setNamespaceAware(true);
 456             spf.newSAXParser().getXMLReader().parse(new InputSource(fis));
 457         }
 458     }
 459 
 460     /**
 461      * Modified by IBM Xerces does not support this feature and it is not
 462      * mandatory.
 463      *
 464      * @throws Exception If any errors occur.
 465      */
 466     @Test(expectedExceptions = SAXNotSupportedException.class)
 467     public void xrProperty01() throws Exception {
 468         SAXParserFactory spf = SAXParserFactory.newInstance();
 469         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 470         xmlReader.getProperty(XML_STRING);
 471     }
 472 
 473     /**
 474      * SAXNotSupportedException thrown if property name is known but no value
 475      * assigned to this property.
 476      *
 477      * @throws Exception If any errors occur.
 478      */
 479     @Test(expectedExceptions = SAXNotSupportedException.class)
 480     public void xrProperty02() throws Exception {
 481         SAXParserFactory spf = SAXParserFactory.newInstance();
 482         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 483         assertNull(xmlReader.getProperty(DOM_NODE));
 484     }
 485 
 486     /**
 487      * XMLReader.getProperty returns null if LEXICAL_HANDLER wasn't set.
 488      *
 489      * @throws Exception If any errors occur.
 490      */
 491     @Test
 492     public void xrProperty03() throws Exception {
 493         SAXParserFactory spf = SAXParserFactory.newInstance();
 494         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 495         assertNull(xmlReader.getProperty(LEXICAL_HANDLER));
 496     }
 497 
 498     /**
 499      * XMLReader.getProperty returns null if DECL_HANDLER wasn't set.
 500      *
 501      * @throws Exception If any errors occur.
 502      */
 503     @Test
 504     public void xrProperty04() throws Exception {
 505         SAXParserFactory spf = SAXParserFactory.newInstance();
 506         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 507         assertNull(xmlReader.getProperty(DECL_HANDLER));
 508     }
 509 
 510     /**
 511      * XMLReader.setProperty/getProperty for LEXICAL_HANDLER unit test.
 512      *
 513      * @throws Exception If any errors occur.
 514      */
 515     @Test
 516     public void xrProperty05() throws Exception {
 517         SAXParserFactory spf = SAXParserFactory.newInstance();
 518         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 519         MyLexicalHandler myLexicalHandler = new MyLexicalHandler();
 520         xmlReader.setProperty(LEXICAL_HANDLER, myLexicalHandler);
 521         assertNotNull(xmlReader.getProperty(LEXICAL_HANDLER));
 522     }
 523 
 524     /**
 525      * XMLReader.setProperty/getProperty for DECL_HANDLER unit test.
 526      *
 527      * @throws Exception If any errors occur.
 528      */
 529     @Test
 530     public void xrProperty06() throws Exception {
 531         SAXParserFactory spf = SAXParserFactory.newInstance();
 532         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
 533         MyDeclHandler myDeclHandler = new MyDeclHandler();
 534         xmlReader.setProperty(DECL_HANDLER, myDeclHandler);
 535         assertNotNull(xmlReader.getProperty(DECL_HANDLER));
 536     }
 537 }
 538 
 539 /**
 540  * Simple LexicalHandler that skips every lexical event.
 541  */
 542 class MyLexicalHandler implements LexicalHandler {
 543 
 544     /**
 545      * Report an XML comment anywhere in the document.
 546      *
 547      * @param ch An array holding the characters in the comment.
 548      * @param start The starting position in the array.
 549      * @param length The number of characters to use from the array.
 550      */
 551     @Override
 552     public void comment(char[] ch, int start, int length) {
 553     }
 554 
 555     /**
 556      * Report the end of a CDATA section.
 557      */
 558     @Override
 559     public void endCDATA() {
 560     }
 561 
 562     /**
 563      * Report the end of DTD declarations.
 564      */
 565     @Override
 566     public void endDTD() {
 567     }
 568 
 569     /**
 570      * Report the end of an entity.
 571      *
 572      * @param name The name of the entity that is ending.
 573      */
 574     @Override
 575     public void endEntity(String name) {
 576     }
 577 
 578     /**
 579      * Report the start of a CDATA section.
 580      */
 581     @Override
 582     public void startCDATA() {
 583     }
 584 
 585     /**
 586      * Report the start of DTD declarations, if any.
 587      *
 588      * @param name The document type name.
 589      * @param publicId The declared public identifier for the external DTD
 590      * subset.
 591      * @param systemId The declared system identifier for the external DTD
 592      * subset.
 593      */
 594     @Override
 595     public void startDTD(String name, String publicId, String systemId) {
 596     }
 597 
 598     /**
 599      * Report the beginning of some internal and external XML entities.
 600      *
 601      * @param name The name of the entity.
 602      */
 603     @Override
 604     public void startEntity(String name) {
 605     }
 606 }
 607 
 608 /**
 609  * Simple DeclHandler that skips every DTD declaration event.
 610  */
 611 class MyDeclHandler implements DeclHandler {
 612 
 613     /**
 614      * Report an attribute type declaration.
 615      *
 616      * @param eName The name of the associated element.
 617      * @param aName The name of the attribute.
 618      * @param type A string representing the attribute type.
 619      * @param mode A string representing the attribute defaulting mode
 620      * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if none of these applies.
 621      * @param value A string representing the attribute's default value, or null
 622      * if there is none.
 623      */
 624     @Override
 625     public void attributeDecl(String eName, String aName, String type,
 626             String valueDefault, String value) {
 627     }
 628 
 629     /**
 630      * Report an element type declaration.
 631      *
 632      * @param name The element type name.
 633      * @param model The content model as a normalized string.
 634      */
 635     @Override
 636     public void elementDecl(String name, String model) {
 637     }
 638 
 639     /**
 640      * Report a parsed external entity declaration.
 641      *
 642      * @param name The name of the entity. If it is a parameter entity, the name
 643      * will begin with '%'.
 644      * @param publicId The entity's public identifier, or null if none was
 645      * given.
 646      * @param systemId The entity's system identifier.
 647      */
 648     @Override
 649     public void externalEntityDecl(String name, String publicId,
 650             String systemId) {
 651     }
 652 
 653     /**
 654      * Report an internal entity declaration.
 655      *
 656      * @param name The name of the entity. If it is a parameter entity, the name
 657      * will begin with '%'.
 658      * @param value The replacement text of the entity.
 659      */
 660     @Override
 661     public void internalEntityDecl(String name, String value) {
 662     }
 663 }