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 }