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