1 /* 2 * Copyright (c) 2015, 2017, 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 catalog; 24 25 import java.io.File; 26 import java.io.FileInputStream; 27 import java.io.IOException; 28 import java.io.InputStream; 29 import java.io.StringReader; 30 import java.io.StringWriter; 31 import java.net.URI; 32 import java.nio.file.Paths; 33 import javax.xml.XMLConstants; 34 import javax.xml.catalog.Catalog; 35 import javax.xml.catalog.CatalogException; 36 import javax.xml.catalog.CatalogFeatures; 37 import javax.xml.catalog.CatalogFeatures.Feature; 38 import javax.xml.catalog.CatalogManager; 39 import javax.xml.catalog.CatalogResolver; 40 import javax.xml.parsers.ParserConfigurationException; 41 import javax.xml.parsers.SAXParser; 42 import javax.xml.parsers.SAXParserFactory; 43 import javax.xml.stream.XMLInputFactory; 44 import javax.xml.stream.XMLStreamConstants; 45 import javax.xml.stream.XMLStreamReader; 46 import javax.xml.transform.Source; 47 import javax.xml.transform.Transformer; 48 import javax.xml.transform.TransformerFactory; 49 import javax.xml.transform.sax.SAXSource; 50 import javax.xml.transform.stream.StreamResult; 51 import javax.xml.transform.stream.StreamSource; 52 import javax.xml.validation.Schema; 53 import javax.xml.validation.SchemaFactory; 54 import javax.xml.validation.Validator; 55 import static jaxp.library.JAXPTestUtilities.clearSystemProperty; 56 import static jaxp.library.JAXPTestUtilities.setSystemProperty; 57 import org.testng.Assert; 58 import org.testng.annotations.BeforeClass; 59 import org.testng.annotations.DataProvider; 60 import org.testng.annotations.Listeners; 61 import org.testng.annotations.Test; 62 import org.xml.sax.Attributes; 63 import org.xml.sax.ErrorHandler; 64 import org.xml.sax.InputSource; 65 import org.xml.sax.SAXException; 66 import org.xml.sax.XMLReader; 67 import org.xml.sax.ext.DefaultHandler2; 68 69 /* 70 * @test 71 * @bug 8081248 8144966 8146606 8146237 8150969 8151162 8152527 8154220 8163232 72 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest 73 * @run testng/othervm -DrunSecMngr=true catalog.CatalogTest 74 * @run testng/othervm catalog.CatalogTest 75 * @summary Tests basic Catalog functions. 76 */ 77 @Listeners({jaxp.library.FilePolicy.class}) 78 public class CatalogTest extends CatalogSupportBase { 79 static final String KEY_FILES = "javax.xml.catalog.files"; 80 81 82 /* 83 * Initializing fields 84 */ 85 @BeforeClass 86 public void setUpClass() throws Exception { 87 super.setUp(); 88 } 89 90 /* 91 * @bug 8163232 92 * Verifies that the CatalogResolver supports the following XML Resolvers: 93 javax.xml.stream.XMLResolver 94 javax.xml.transform.URIResolver 95 org.w3c.dom.ls.LSResourceResolver 96 org.xml.sax.EntityResolver 97 * 98 * Plus, system and uri entries can equally be used. 99 */ 100 101 /* 102 * Verifies the support for org.xml.sax.EntityResolver. 103 * Expected: the parser returns the expected string. 104 */ 105 @Test(dataProvider = "supportXMLResolver") 106 public void supportEntityResolver(URI catalogFile, String xml, String expected) throws Exception { 107 String xmlSource = getClass().getResource(xml).getFile(); 108 109 CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); 110 MyCatalogHandler handler = new MyCatalogHandler(cr, elementInSystem); 111 SAXParser parser = getSAXParser(false, true, null); 112 parser.parse(xmlSource, handler); 113 114 Assert.assertEquals(handler.getResult().trim(), expected); 115 } 116 117 /* 118 * Verifies the support for javax.xml.stream.XMLResolver. 119 * Expected: the parser returns the expected string. 120 */ 121 @Test(dataProvider = "supportXMLResolver") 122 public void supportXMLResolver(URI catalogFile, String xml, String expected) throws Exception { 123 String xmlSource = getClass().getResource(xml).getFile(); 124 125 CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); 126 127 XMLInputFactory xifactory = XMLInputFactory.newInstance(); 128 xifactory.setProperty(XMLInputFactory.IS_COALESCING, true); 129 xifactory.setProperty(XMLInputFactory.RESOLVER, cr); 130 File file = new File(xmlSource); 131 String systemId = file.toURI().toASCIIString(); 132 InputStream entityxml = new FileInputStream(file); 133 XMLStreamReader streamReader = xifactory.createXMLStreamReader(systemId, entityxml); 134 String result = null; 135 while (streamReader.hasNext()) { 136 int eventType = streamReader.next(); 137 if (eventType == XMLStreamConstants.START_ELEMENT) { 138 eventType = streamReader.next(); 139 if (eventType == XMLStreamConstants.CHARACTERS) { 140 result = streamReader.getText(); 141 } 142 } 143 } 144 System.out.println(": expected [" + expected + "] <> actual [" + result.trim() + "]"); 145 146 Assert.assertEquals(result.trim(), expected); 147 } 148 149 /* 150 * Verifies the support for org.w3c.dom.ls.LSResourceResolver by ShemaFactory. 151 * Success: parsing goes through with no error 152 * Fail: throws Exception if references are not resolved (by the CatalogResolver) 153 */ 154 @Test(dataProvider = "supportLSResourceResolver") 155 public void supportLSResourceResolver(URI catalogFile, Source schemaSource) throws SAXException { 156 157 CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); 158 159 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 160 factory.setResourceResolver(cr); 161 Schema schema = factory.newSchema(schemaSource); 162 163 } 164 165 /* 166 * Verifies the support for org.w3c.dom.ls.LSResourceResolver by Validator. 167 * Success: parsing goes through with no error 168 * Fail: throws Exception if references are not resolved (by the CatalogResolver) 169 */ 170 @Test(dataProvider = "supportLSResourceResolver1") 171 public void supportLSResourceResolver1(URI catalogFile, Source source) throws Exception { 172 173 CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); 174 175 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 176 Validator validator = factory.newSchema().newValidator(); 177 validator.setResourceResolver(cr); 178 validator.validate(source); 179 } 180 181 /* 182 * Verifies the support for javax.xml.transform.URIResolver. 183 * Success: parsing goes through with no error 184 * Fail: throws Exception if references are not resolved (by the CatalogResolver) 185 */ 186 @Test(dataProvider = "supportURIResolver") 187 public void supportURIResolver(URI catalogFile, Source xsl, Source xml, String expected) throws Exception { 188 189 CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); 190 191 TransformerFactory factory = TransformerFactory.newInstance(); 192 factory.setURIResolver(cr); 193 Transformer transformer = factory.newTransformer(xsl); 194 StringWriter out = new StringWriter(); 195 transformer.transform(xml, new StreamResult(out)); 196 if (expected != null) { 197 Assert.assertTrue(out.toString().contains(expected), "supportURIResolver"); 198 } 199 } 200 201 /* 202 DataProvider: used to verify the support of XML Resolvers. 203 Data columns: 204 catalog filepath, xml source file, expected result 205 */ 206 @DataProvider(name = "supportXMLResolver") 207 public Object[][] supportXMLResolver() throws Exception { 208 URI catalogFile = getClass().getResource("catalog.xml").toURI(); 209 URI catalogFileUri = getClass().getResource("catalog_uri.xml").toURI(); 210 211 return new Object[][]{ 212 {catalogFile, "system.xml", "Test system entry"}, 213 {catalogFile, "rewritesystem.xml", "Test rewritesystem entry"}, 214 {catalogFile, "rewritesystem1.xml", "Test rewritesystem entry"}, 215 {catalogFile, "systemsuffix.xml", "Test systemsuffix entry"}, 216 {catalogFile, "delegatesystem.xml", "Test delegatesystem entry"}, 217 {catalogFile, "public.xml", "Test public entry"}, 218 {catalogFile, "delegatepublic.xml", "Test delegatepublic entry"}, 219 // using uri entries 220 {catalogFileUri, "system.xml", "Test system entry"}, 221 {catalogFileUri, "rewritesystem.xml", "Test rewritesystem entry"}, 222 {catalogFileUri, "rewritesystem1.xml", "Test rewritesystem entry"}, 223 {catalogFileUri, "systemsuffix.xml", "Test systemsuffix entry"}, 224 {catalogFileUri, "delegateuri.xml", "Test delegateuri entry"}, 225 {catalogFileUri, "public.xml", "Test public entry"}, 226 }; 227 } 228 229 /* 230 DataProvider: used to verify the support of LSResourceResolver by SchemaFactory. 231 Data columns: 232 catalog filepath, schema source file 233 */ 234 @DataProvider(name = "supportLSResourceResolver") 235 public Object[][] supportLSResourceResolver() throws Exception { 236 URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI(); 237 URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI(); 238 239 /* 240 * XMLSchema.xsd has a reference to XMLSchema.dtd which in turn refers to 241 * datatypes.dtd 242 */ 243 return new Object[][]{ 244 {catalogFile, new StreamSource(new StringReader(xsd_xmlSchema))}, 245 {catalogFile, new StreamSource(new StringReader(xsd_xmlSchema_import))}, 246 {catalogFile, new StreamSource(new StringReader(xsd_include_company))}, 247 {catalogFileUri, new StreamSource(new StringReader(xsd_xmlSchema))}, 248 {catalogFileUri, new StreamSource(new StringReader(xsd_xmlSchema_import))}, 249 {catalogFileUri, new StreamSource(new StringReader(xsd_include_company))}, 250 }; 251 } 252 253 /* 254 DataProvider: used to verify the support of LSResourceResolver by Validator. 255 Data columns: 256 catalog filepath, source file 257 */ 258 @DataProvider(name = "supportLSResourceResolver1") 259 public Object[][] supportLSResourceResolver1() throws Exception { 260 URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI(); 261 URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI(); 262 263 /* 264 * val_test.xml has a reference to system.dtd and val_test.xsd 265 */ 266 SAXSource ss = new SAXSource(new InputSource(xml_val_test)); 267 ss.setSystemId(xml_val_test_id); 268 269 return new Object[][]{ 270 {catalogFile, ss}, 271 {catalogFileUri, ss}, 272 }; 273 } 274 275 276 /* 277 DataProvider: used to verify the support of LSResourceResolver by Validator. 278 Data columns: 279 catalog filepath, xsl source, xml source file 280 */ 281 @DataProvider(name = "supportURIResolver") 282 public Object[][] supportURIResolver() throws Exception { 283 URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI(); 284 URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI(); 285 SAXSource xslSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString())); 286 287 /* 288 * val_test.xml has a reference to system.dtd and val_test.xsd 289 */ 290 SAXSource ss = new SAXSource(new InputSource(xml_val_test)); 291 ss.setSystemId(xml_val_test_id); 292 293 return new Object[][]{ 294 {catalogFile, new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString())), 295 new StreamSource(new File(xml_doc)), "Resolved by a catalog"}, 296 {catalogFileUri, new SAXSource(new InputSource(new StringReader(xsl_include))), 297 new StreamSource(new StringReader(xml_xsl)), null}, 298 }; 299 } 300 301 /* 302 * @bug 8150187 303 * NPE is expected if the systemId is null. The specification for systemId 304 * is as follows: 305 * A system identifier is required on all external entities. XML 306 * requires a system identifier on all external entities, so this value is 307 * always specified. 308 */ 309 @Test(expectedExceptions = NullPointerException.class) 310 public void sysIdCantBeNull() { 311 CatalogResolver catalogResolver = CatalogManager.catalogResolver(CatalogFeatures.defaults()); 312 InputSource is = catalogResolver.resolveEntity("-//FOO//DTD XML Dummy V0.0//EN", null); 313 } 314 315 /* 316 * @bug 8156845 317 * Verifies that an URI reference with a urn:publicid is correctly resolved 318 * with an uri entry with a publicId. 319 * 320 * @param expectedFile is not used in this test, it's kept since we're 321 * copying the JCK test and its dataProvider. This test may be reused for 322 * other cases in that test. 323 */ 324 @Test(dataProvider = "resolveUri") 325 public void testMatch1(String cFile, String href, String expectedFile, 326 String expectedUri, String msg) throws Exception { 327 URI catalogFile = getClass().getResource(cFile).toURI(); 328 CatalogResolver cur = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); 329 Source source = cur.resolve(href, null); 330 Assert.assertNotNull(source, "Source returned is null"); 331 Assert.assertEquals(expectedUri, source.getSystemId(), msg); 332 } 333 334 /* 335 * @bug 8154220 336 * Verifies that the file input is validated properly. Valid input includes 337 * multiple file paths separated by semicolon. 338 */ 339 @Test(dataProvider = "hierarchyOfCatFilesData") 340 public void hierarchyOfCatFiles2(String systemId, String expectedUri) { 341 String file1 = getClass().getResource("first_cat.xml").toExternalForm(); 342 String file2 = getClass().getResource("second_cat.xml").toExternalForm(); 343 String files = file1 + ";" + file2; 344 345 try { 346 setSystemProperty(KEY_FILES, files); 347 CatalogResolver catalogResolver = CatalogManager.catalogResolver(CatalogFeatures.defaults()); 348 String sysId = catalogResolver.resolveEntity(null, systemId).getSystemId(); 349 Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"), 350 "System ID match not right"); 351 } finally { 352 clearSystemProperty(KEY_FILES); 353 } 354 355 } 356 357 /* 358 * @bug 8152527 359 * This test is the same as the JDK test ResolveEntityTests:testMatch1. 360 * Verifies that the CatalogResolver resolves a publicId and/or systemId as 361 * expected. 362 */ 363 @Test(dataProvider = "resolveEntity") 364 public void testMatch1(String cfile, String prefer, String sysId, String pubId, 365 String expectedUri, String expectedFile, String msg) throws Exception { 366 URI catalogFile = getClass().getResource(cfile).toURI(); 367 CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(); 368 CatalogResolver catalogResolver = CatalogManager.catalogResolver(features, catalogFile); 369 InputSource is = catalogResolver.resolveEntity(pubId, sysId); 370 Assert.assertNotNull(is, msg); 371 String expected = (expectedUri == null) ? expectedFile : expectedUri; 372 Assert.assertEquals(expected, is.getSystemId(), msg); 373 } 374 375 /* 376 * @bug 8151162 377 * Verifies that the Catalog matches specified publicId or systemId and returns 378 * results as expected. 379 */ 380 @Test(dataProvider = "matchWithPrefer") 381 public void matchWithPrefer(String prefer, String cfile, String publicId, 382 String systemId, String expected) throws Exception { 383 URI catalogFile = getClass().getResource(cfile).toURI(); 384 Catalog c = CatalogManager.catalog( 385 CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(), 386 catalogFile); 387 String result; 388 if (publicId != null && publicId.length() > 0) { 389 result = c.matchPublic(publicId); 390 } else { 391 result = c.matchSystem(systemId); 392 } 393 Assert.assertEquals(expected, result); 394 } 395 396 /* 397 * @bug 8151162 398 * Verifies that the CatalogResolver resolves specified publicId or systemId 399 * in accordance with the prefer setting. 400 * prefer "system": resolves with a system entry. 401 * Exception: use the public entry when the catalog contains 402 * only public entry and only publicId is specified. 403 * prefer "public": attempts to resolve with a system entry; 404 * attempts to resolve with a public entry if no matching 405 * system entry is found. 406 */ 407 @Test(dataProvider = "resolveWithPrefer") 408 public void resolveWithPrefer(String prefer, String cfile, String publicId, 409 String systemId, String expected) throws Exception { 410 URI catalogFile = getClass().getResource(cfile).toURI(); 411 CatalogFeatures f = CatalogFeatures.builder() 412 .with(CatalogFeatures.Feature.PREFER, prefer) 413 .with(CatalogFeatures.Feature.RESOLVE, "ignore") 414 .build(); 415 CatalogResolver catalogResolver = CatalogManager.catalogResolver(f, catalogFile); 416 String result = catalogResolver.resolveEntity(publicId, systemId).getSystemId(); 417 Assert.assertEquals(expected, result); 418 } 419 420 /** 421 * @bug 8150969 422 * Verifies that the defer attribute set in the catalog file takes precedence 423 * over other settings, in which case, whether next and delegate Catalogs will 424 * be loaded is determined by the defer attribute. 425 */ 426 @Test(dataProvider = "invalidAltCatalogs", expectedExceptions = CatalogException.class) 427 public void testDeferAltCatalogs(String file) throws Exception { 428 URI catalogFile = getClass().getResource(file).toURI(); 429 CatalogFeatures features = CatalogFeatures.builder(). 430 with(CatalogFeatures.Feature.DEFER, "true") 431 .build(); 432 /* 433 Since the defer attribute is set to false in the specified catalog file, 434 the parent catalog will try to load the alt catalog, which will fail 435 since it points to an invalid catalog. 436 */ 437 Catalog catalog = CatalogManager.catalog(features, catalogFile); 438 } 439 440 441 /** 442 * @bug 8146237 443 * PREFER from Features API taking precedence over catalog file 444 */ 445 @Test 446 public void testJDK8146237() throws Exception { 447 URI catalogFile = getClass().getResource("JDK8146237_catalog.xml").toURI(); 448 449 try { 450 CatalogFeatures features = CatalogFeatures.builder() 451 .with(CatalogFeatures.Feature.PREFER, "system") 452 .build(); 453 Catalog catalog = CatalogManager.catalog(features, catalogFile); 454 CatalogResolver catalogResolver = CatalogManager.catalogResolver(catalog); 455 String actualSystemId = catalogResolver.resolveEntity( 456 "-//FOO//DTD XML Dummy V0.0//EN", 457 "http://www.oracle.com/alt1sys.dtd") 458 .getSystemId(); 459 Assert.assertTrue(actualSystemId.contains("dummy.dtd"), 460 "Resulting id should contain dummy.dtd, indicating a match by publicId"); 461 462 } catch (Exception e) { 463 Assert.fail(e.getMessage()); 464 } 465 } 466 467 /* 468 @bug 8146606 469 Verifies that the resulting systemId does not contain duplicate slashes 470 */ 471 @Test 472 public void testRewriteSystem() throws Exception { 473 URI catalog = getClass().getResource("rewriteCatalog.xml").toURI(); 474 475 try { 476 CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog); 477 String actualSystemId = resolver.resolveEntity(null, "http://remote.com/dtd/book.dtd").getSystemId(); 478 Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes"); 479 } catch (Exception e) { 480 Assert.fail(e.getMessage()); 481 } 482 483 } 484 485 /* 486 @bug 8146606 487 Verifies that the resulting systemId does not contain duplicate slashes 488 */ 489 @Test 490 public void testRewriteUri() throws Exception { 491 URI catalog = getClass().getResource("rewriteCatalog.xml").toURI(); 492 493 try { 494 495 CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog); 496 String actualSystemId = resolver.resolve("http://remote.com/import/import.xsl", null).getSystemId(); 497 Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes"); 498 } catch (Exception e) { 499 Assert.fail(e.getMessage()); 500 } 501 } 502 503 /* 504 @bug 8144966 505 Verifies that passing null as CatalogFeatures will result in a NPE. 506 */ 507 @Test(expectedExceptions = NullPointerException.class) 508 public void testFeatureNull() { 509 CatalogResolver resolver = CatalogManager.catalogResolver(null, null); 510 511 } 512 513 /* 514 @bug 8144966 515 Verifies that passing null as the URI will result in a NPE. 516 */ 517 @Test(expectedExceptions = NullPointerException.class) 518 public void testPathNull() { 519 URI uri = null; 520 CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), uri); 521 } 522 523 /* 524 Tests basic catalog feature by using a CatalogResolver instance to 525 resolve a DTD reference to a locally specified DTD file. If the resolution 526 is successful, the Handler shall return the value of the entity reference 527 that matches the expected value. 528 */ 529 @Test(dataProvider = "catalog") 530 public void testCatalogResolver(String test, String expected, String catalogFile, 531 String xml, SAXParser saxParser) throws Exception { 532 URI catalog = null; 533 if (catalogFile != null) { 534 catalog = getClass().getResource(catalogFile).toURI(); 535 } 536 String url = getClass().getResource(xml).getFile(); 537 try { 538 CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog); 539 XMLReader reader = saxParser.getXMLReader(); 540 reader.setEntityResolver(cr); 541 MyHandler handler = new MyHandler(saxParser); 542 reader.setContentHandler(handler); 543 reader.parse(url); 544 System.out.println(test + ": expected [" + expected + "] <> actual [" + handler.getResult() + "]"); 545 Assert.assertEquals(handler.getResult(), expected); 546 } catch (SAXException | IOException e) { 547 Assert.fail(e.getMessage()); 548 } 549 } 550 551 /* 552 Verifies that when there's no match, in this case only an invalid 553 catalog is provided, the resolver will throw an exception by default. 554 */ 555 @Test 556 public void testInvalidCatalog() throws Exception { 557 String expectedMsgId = "JAXP09040001"; 558 URI catalog = getClass().getResource("catalog_invalid.xml").toURI(); 559 560 try { 561 CatalogResolver resolver = CatalogManager.catalogResolver( 562 CatalogFeatures.defaults(), catalog); 563 String actualSystemId = resolver.resolveEntity( 564 null, 565 "http://remote/xml/dtd/sys/alice/docAlice.dtd") 566 .getSystemId(); 567 } catch (Exception e) { 568 String msg = e.getMessage(); 569 if (msg != null) { 570 Assert.assertTrue(msg.contains(expectedMsgId), 571 "Message shall contain the corrent message ID " + expectedMsgId); 572 } 573 } 574 } 575 576 /* 577 Verifies that if resolve is "ignore", an empty InputSource will be returned 578 when there's no match. The systemId is then null. 579 */ 580 @Test 581 public void testIgnoreInvalidCatalog() { 582 String catalog = getClass().getResource("catalog_invalid.xml").toExternalForm(); 583 CatalogFeatures f = CatalogFeatures.builder() 584 .with(Feature.FILES, catalog) 585 .with(Feature.PREFER, "public") 586 .with(Feature.DEFER, "true") 587 .with(Feature.RESOLVE, "ignore") 588 .build(); 589 590 String test = "testInvalidCatalog"; 591 try { 592 CatalogResolver resolver = CatalogManager.catalogResolver(f); 593 String actualSystemId = resolver.resolveEntity( 594 null, 595 "http://remote/xml/dtd/sys/alice/docAlice.dtd") 596 .getSystemId(); 597 System.out.println("testIgnoreInvalidCatalog: expected [null]"); 598 System.out.println("testIgnoreInvalidCatalog: expected [null]"); 599 System.out.println("actual [" + actualSystemId + "]"); 600 Assert.assertEquals(actualSystemId, null); 601 } catch (Exception e) { 602 Assert.fail(e.getMessage()); 603 } 604 } 605 606 607 /* 608 DataProvider: used to verify CatalogResolver's resolve function. 609 Data columns: 610 catalog, uri or publicId, expectedFile, expectedUri, msg 611 612 This DataProvider is copied from JCK ResolveTests' dataMatch1 613 */ 614 @DataProvider(name = "resolveUri") 615 public Object[][] getDataForUriResolver() { 616 return new Object[][]{ 617 {"uri.xml", 618 "urn:publicid:-:Acme,+Inc.:DTD+Book+Version+1.0", 619 null, 620 "http://local/base/dtd/book.dtd", 621 "Uri in publicId namespace is incorrectly unwrapped"}, 622 }; 623 } 624 625 /* 626 DataProvider: used to verify hierarchical catalogs. Refer to JCK test 627 hierarchyOfCatFiles2. 628 */ 629 @DataProvider(name = "hierarchyOfCatFilesData") 630 public Object[][] getHierarchyOfCatFilesData() { 631 return new Object[][]{ 632 {"http://www.oracle.com/sequence.dtd", "first.dtd"}, 633 {"http://www.oracle.com/sequence_next.dtd", "next.dtd"}, 634 {"http://www.oracle.com/sequence_second.dtd", "second.dtd"} 635 }; 636 } 637 638 /* 639 DataProvider: used to verify CatalogResolver's resolveEntity function. 640 Data columns: 641 catalog, prefer, systemId, publicId, expectedUri, expectedFile, msg 642 */ 643 @DataProvider(name = "resolveEntity") 644 public Object[][] getDataForMatchingBothIds() { 645 String expected = "http://www.groupxmlbase.com/dtds/rewrite.dtd"; 646 return new Object[][]{ 647 {"rewriteSystem_id.xml", 648 "system", 649 "http://www.sys00test.com/rewrite.dtd", 650 "PUB-404", 651 expected, 652 expected, 653 "Relative rewriteSystem with xml:base at group level failed"}, 654 }; 655 } 656 657 static String id = "http://openjdk.java.net/xml/catalog/dtd/system.dtd"; 658 /* 659 DataProvider: used to verify how prefer settings affect the result of the 660 Catalog's matching operation. 661 Data columns: 662 prefer, catalog, publicId, systemId, expected result 663 */ 664 @DataProvider(name = "matchWithPrefer") 665 public Object[][] getDataForMatch() { 666 return new Object[][]{ 667 {"public", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"}, 668 {"public", "sysOnly.xml", id, "", null}, 669 {"public", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"}, 670 {"system", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"}, 671 {"system", "sysOnly.xml", id, "", null}, 672 {"system", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"}, 673 {"public", "pubOnly.xml", "", id, null}, 674 {"public", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"}, 675 {"public", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"}, 676 {"system", "pubOnly.xml", "", id, null}, 677 {"system", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"}, 678 {"system", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"}, 679 }; 680 } 681 682 /* 683 DataProvider: used to verify how prefer settings affect the result of the 684 CatalogResolver's resolution operation. 685 Data columns: 686 prefer, catalog, publicId, systemId, expected result 687 */ 688 @DataProvider(name = "resolveWithPrefer") 689 public Object[][] getDataForResolve() { 690 return new Object[][]{ 691 {"system", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"}, 692 {"system", "pubOnly.xml", "", id, null}, 693 {"system", "pubOnly.xml", id, id, null}, 694 {"public", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"}, 695 {"public", "pubOnly.xml", "", id, null}, 696 {"public", "pubOnly.xml", id, id, "http://local/base/dtd/public.dtd"}, 697 {"system", "sysOnly.xml", id, "", null}, 698 {"system", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"}, 699 {"system", "sysOnly.xml", id, id, "http://local/base/dtd/system.dtd"}, 700 {"public", "sysOnly.xml", id, "", null}, 701 {"public", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"}, 702 {"public", "sysOnly.xml", id, id, "http://local/base/dtd/system.dtd"}, 703 {"system", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"}, 704 {"system", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"}, 705 {"system", "sysAndPub.xml", id, id, "http://local/base/dtd/system.dtd"}, 706 {"public", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"}, 707 {"public", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"}, 708 {"public", "sysAndPub.xml", id, id, "http://local/base/dtd/system.dtd"}, 709 }; 710 } 711 /* 712 DataProvider: catalogs that contain invalid next or delegate catalogs. 713 The defer attribute is set to false. 714 */ 715 @DataProvider(name = "invalidAltCatalogs") 716 public Object[][] getCatalogs() { 717 return new Object[][]{ 718 {"defer_false_2.xml"}, 719 {"defer_del_false.xml"} 720 }; 721 } 722 723 724 /* 725 DataProvider: provides test name, expected string, the catalog, and XML 726 document. 727 */ 728 @DataProvider(name = "catalog") 729 public Object[][] getCatalog() { 730 return new Object[][]{ 731 {"testSystem", "Test system entry", "catalog.xml", "system.xml", getParser()}, 732 {"testRewriteSystem", "Test rewritesystem entry", "catalog.xml", "rewritesystem.xml", getParser()}, 733 {"testRewriteSystem1", "Test rewritesystem entry", "catalog.xml", "rewritesystem1.xml", getParser()}, 734 {"testSystemSuffix", "Test systemsuffix entry", "catalog.xml", "systemsuffix.xml", getParser()}, 735 {"testDelegateSystem", "Test delegatesystem entry", "catalog.xml", "delegatesystem.xml", getParser()}, 736 {"testPublic", "Test public entry", "catalog.xml", "public.xml", getParser()}, 737 {"testDelegatePublic", "Test delegatepublic entry", "catalog.xml", "delegatepublic.xml", getParser()}, 738 }; 739 } 740 741 SAXParser getParser() { 742 SAXParser saxParser = null; 743 try { 744 SAXParserFactory factory = SAXParserFactory.newInstance(); 745 factory.setNamespaceAware(true); 746 saxParser = factory.newSAXParser(); 747 } catch (ParserConfigurationException | SAXException e) { 748 } 749 750 return saxParser; 751 } 752 753 /** 754 * SAX handler 755 */ 756 public class MyHandler extends DefaultHandler2 implements ErrorHandler { 757 758 StringBuilder textContent = new StringBuilder(); 759 SAXParser saxParser; 760 761 MyHandler(SAXParser saxParser) { 762 textContent.setLength(0); 763 this.saxParser = saxParser; 764 } 765 766 String getResult() { 767 return textContent.toString(); 768 } 769 770 @Override 771 public void startElement(String uri, String localName, String qName, Attributes attributes) 772 throws SAXException { 773 textContent.delete(0, textContent.length()); 774 try { 775 System.out.println("Element: " + uri + ":" + localName + " " + qName); 776 } catch (Exception e) { 777 throw new SAXException(e); 778 } 779 780 } 781 782 @Override 783 public void characters(char ch[], int start, int length) throws SAXException { 784 textContent.append(ch, start, length); 785 } 786 } 787 }