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