--- old/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java 2016-01-07 09:10:26.812492650 -0800 +++ new/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java 2016-01-07 09:10:26.636483905 -0800 @@ -32,7 +32,6 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -43,6 +42,7 @@ import static javax.xml.catalog.BaseEntry.CatalogEntryType; import static javax.xml.catalog.CatalogFeatures.DEFER_TRUE; import javax.xml.catalog.CatalogFeatures.Feature; +import static javax.xml.catalog.CatalogMessages.formatMessage; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -109,25 +109,20 @@ */ public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException { super(CatalogEntryType.CATALOG); - this.parent = parent; - if (parent == null) { - level = 0; - } else { - level = parent.level + 1; - } if (f == null) { - this.features = CatalogFeatures.defaults(); - } else { - this.features = f; + throw new NullPointerException( + formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"})); } - setPrefer(features.get(Feature.PREFER)); - setDeferred(features.get(Feature.DEFER)); - setResolve(features.get(Feature.RESOLVE)); + + if (file.length > 0) { + CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]); + } + + init(parent, f); //Path of catalog files String[] catalogFile = file; - if (level == 0 - && (file == null || (file.length == 0 || file[0] == null))) { + if (level == 0 && file.length == 0) { String files = features.get(Feature.FILES); if (files != null) { catalogFile = files.split(";[ ]*"); @@ -166,6 +161,23 @@ } } + private void init(CatalogImpl parent, CatalogFeatures f) { + this.parent = parent; + if (parent == null) { + level = 0; + } else { + level = parent.level + 1; + } + if (f == null) { + this.features = CatalogFeatures.defaults(); + } else { + this.features = f; + } + setPrefer(features.get(Feature.PREFER)); + setDeferred(features.get(Feature.DEFER)); + setResolve(features.get(Feature.RESOLVE)); + } + /** * Resets the Catalog instance to its initial state. */ --- old/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java 2016-01-07 09:10:27.308517297 -0800 +++ new/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java 2016-01-07 09:10:27.152509545 -0800 @@ -38,33 +38,38 @@ } /** - * Creates a Catalog object using the specified feature settings and path to - * a catalog file. If the features is null, the default features will be used. - * If the path is empty, System property {@code javax.xml.catalog.files} will - * be read to locate the initial list of catalog files. + * Creates a {@code Catalog} object using the specified feature settings and + * path to one or more catalog files. *

- * If more than one catalog files are specified through the path argument or + * If {@code paths} is empty, system property {@code javax.xml.catalog.files} + * will be read to locate the initial list of catalog files. + *

+ * If more than one catalog files are specified through the paths argument or * {@code javax.xml.catalog.files} property, the first entry is considered * the main catalog, while others are treated as alternative catalogs after * those referenced by the {@code nextCatalog} elements in the main catalog. + *

+ * As specified in + * + * XML Catalogs, OASIS Standard V1.1, invalid path entries will be ignored. + * No error will be reported. In case all entries are invalid, the resolver + * will return as no mapping is found. * * @param features the catalog features - * @param path path(s) to one or more catalogs. + * @param paths path(s) to one or more catalogs. * - * @return a catalog instance - * @throws CatalogException If no catalog can be found whether through the - * specified path or the System property {@code javax.xml.catalog.files}, or - * an error occurs while parsing the catalog + * @return an instance of a {@code Catalog} + * @throws CatalogException If an error occurs while parsing the catalog */ - public static Catalog catalog(CatalogFeatures features, String... path) { - return new CatalogImpl(features, path); + public static Catalog catalog(CatalogFeatures features, String... paths) { + return new CatalogImpl(features, paths); } /** - * Creates an instance of a CatalogResolver using the specified catalog. + * Creates an instance of a {@code CatalogResolver} using the specified catalog. * * @param catalog the catalog instance - * @return an instance of a CatalogResolver + * @return an instance of a {@code CatalogResolver} */ public static CatalogResolver catalogResolver(Catalog catalog) { if (catalog == null) CatalogMessages.reportNPEOnNull("catalog", null); @@ -72,10 +77,10 @@ } /** - * Creates an instance of a CatalogUriResolver using the specified catalog. + * Creates an instance of a {@code CatalogUriResolver} using the specified catalog. * * @param catalog the catalog instance - * @return an instance of a CatalogResolver + * @return an instance of a {@code CatalogResolver} */ public static CatalogUriResolver catalogUriResolver(Catalog catalog) { if (catalog == null) CatalogMessages.reportNPEOnNull("catalog", null); @@ -83,50 +88,60 @@ } /** - * Creates an instance of a CatalogResolver using the specified feature settings - * and path to a catalog file. If the features is null, the default features will - * be used. If the path is empty, System property {@code javax.xml.catalog.files} + * Creates an instance of a {@code CatalogResolver} using the specified feature + * settings and path to one or more catalog files. + *

+ * If {@code paths} is empty, system property {@code javax.xml.catalog.files} * will be read to locate the initial list of catalog files. *

- * If more than one catalog files are specified through the path argument or + * If more than one catalog files are specified through the paths argument or * {@code javax.xml.catalog.files} property, the first entry is considered * the main catalog, while others are treated as alternative catalogs after * those referenced by the {@code nextCatalog} elements in the main catalog. + *

+ * As specified in + * + * XML Catalogs, OASIS Standard V1.1, invalid path entries will be ignored. + * No error will be reported. In case all entries are invalid, the resolver + * will return as no mapping is found. * * @param features the catalog features - * @param path the path(s) to one or more catalogs + * @param paths the path(s) to one or more catalogs * - * @return an instance of a CatalogResolver - * @throws CatalogException If no catalog can be found whether through the - * specified path or the System property {@code javax.xml.catalog.files}, or - * an error occurs while parsing the catalog + * @return an instance of a {@code CatalogResolver} + * @throws CatalogException If an error occurs while parsing the catalog */ - public static CatalogResolver catalogResolver(CatalogFeatures features, String... path) { - Catalog catalog = catalog(features, path); + public static CatalogResolver catalogResolver(CatalogFeatures features, String... paths) { + Catalog catalog = catalog(features, paths); return new CatalogResolverImpl(catalog); } /** - * Creates an instance of a CatalogUriResolver using the specified feature settings - * and path to a catalog file. If the features is null, the default features will - * be used. If the path is empty, System property {@code javax.xml.catalog.files} + * Creates an instance of a {@code CatalogUriResolver} using the specified + * feature settings and path to one or more catalog files. + *

+ * If {@code paths} is empty, system property {@code javax.xml.catalog.files} * will be read to locate the initial list of catalog files. *

- * If more than one catalog files are specified through the path argument or + * If more than one catalog files are specified through the paths argument or * {@code javax.xml.catalog.files} property, the first entry is considered * the main catalog, while others are treated as alternative catalogs after * those referenced by the {@code nextCatalog} elements in the main catalog. + *

+ * As specified in + * + * XML Catalogs, OASIS Standard V1.1, invalid path entries will be ignored. + * No error will be reported. In case all entries are invalid, the resolver + * will return as no mapping is found. * * @param features the catalog features - * @param path the path(s) to one or more catalogs + * @param paths the path(s) to one or more catalogs * - * @return an instance of a CatalogResolver - * @throws CatalogException If no catalog can be found whether through the - * specified path or the System property {@code javax.xml.catalog.files}, or - * an error occurs while parsing the catalog + * @return an instance of a {@code CatalogUriResolver} + * @throws CatalogException If an error occurs while parsing the catalog */ - public static CatalogUriResolver catalogUriResolver(CatalogFeatures features, String... path) { - Catalog catalog = catalog(features, path); + public static CatalogUriResolver catalogUriResolver(CatalogFeatures features, String... paths) { + Catalog catalog = catalog(features, paths); return new CatalogUriResolverImpl(catalog); } } --- old/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java 2016-01-07 09:10:27.824542937 -0800 +++ new/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java 2016-01-07 09:10:27.712537372 -0800 @@ -43,9 +43,9 @@ * absolute if the absolute URI is required * * @return a {@link javax.xml.transform.Source} object if a mapping is found. - * If no mapping is found, returns a {@link javax.xml.transform.Source} object - * containing an empty {@link java.io.Reader} if the - * {@code javax.xml.catalog.resolve} property is set to {@code ignore}; + * If no mapping is found, returns an empty {@link javax.xml.transform.Source} + * object if the {@code javax.xml.catalog.resolve} property is set to + * {@code ignore}; * returns a {@link javax.xml.transform.Source} object with the original URI * (href, or href resolved with base if base is not null) if the * {@code javax.xml.catalog.resolve} property is set to {@code continue}. --- old/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java 2016-01-07 09:10:28.348568975 -0800 +++ new/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java 2016-01-07 09:10:28.196561422 -0800 @@ -56,23 +56,14 @@ @DataProvider(name = "catalog-countOfLoadedCatalogFile") private Object[][] data() { - return new Object[][] { - // This catalog specifies null catalog explicitly, - // and the count of loaded catalogs should be 0. - { createCatalog(null), 0 }, - - // This catalog specifies null catalog implicitly, - // and the count of loaded catalogs should be 0. - { createCatalog(CatalogFeatures.defaults()), 0 }, - - // This catalog loads null catalog with true DEFER, - // and the count of loaded catalogs should be 0. - { createCatalog(createDeferFeature(DEFER_TRUE)), 0 }, - - // This catalog loads null catalog with false DEFER. - // It should load all of none-current catalogs and the - // count of loaded catalogs should be 3. - { createCatalog(createDeferFeature(DEFER_FALSE)), 3 } }; + return new Object[][]{ + // By default, alternative catalogs are not loaded. + {createCatalog(CatalogFeatures.defaults()), 0}, + // Alternative catalogs are not loaded when DEFER is set to true. + {createCatalog(createDeferFeature(DEFER_TRUE)), 0}, + // The 3 alternative catalogs are not pre-loaded + //when DEFER is set to false. + {createCatalog(createDeferFeature(DEFER_FALSE)), 3}}; } private CatalogFeatures createDeferFeature(String defer) { --- old/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java 2016-01-07 09:10:28.864594616 -0800 +++ new/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java 2016-01-07 09:10:28.724587660 -0800 @@ -83,7 +83,7 @@ * Creates CatalogResolver with a set of catalogs. */ static CatalogResolver catalogResolver(String... catalogName) { - return catalogResolver(null, catalogName); + return catalogResolver(CatalogFeatures.defaults(), catalogName); } /* @@ -91,15 +91,16 @@ */ static CatalogResolver catalogResolver(CatalogFeatures features, String... catalogName) { - return CatalogManager.catalogResolver(features, - getCatalogPaths(catalogName)); + return (catalogName == null) ? + CatalogManager.catalogResolver(features) : + CatalogManager.catalogResolver(features, getCatalogPaths(catalogName)); } /* * Creates catalogUriResolver with a set of catalogs. */ static CatalogUriResolver catalogUriResolver(String... catalogName) { - return catalogUriResolver(null, catalogName); + return catalogUriResolver(CatalogFeatures.defaults(), catalogName); } /* @@ -107,8 +108,9 @@ */ static CatalogUriResolver catalogUriResolver( CatalogFeatures features, String... catalogName) { - return CatalogManager.catalogUriResolver(features, - getCatalogPaths(catalogName)); + return (catalogName == null) ? + CatalogManager.catalogUriResolver(features) : + CatalogManager.catalogUriResolver(features, getCatalogPaths(catalogName)); } // Gets the paths of the specified catalogs. --- old/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java 2016-01-07 09:10:29.300616281 -0800 +++ new/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java 2016-01-07 09:10:29.184610515 -0800 @@ -89,7 +89,7 @@ /** * BOM table for storing BOM header. */ - private final static Map bom = new HashMap(); + private final static Map bom = new HashMap<>(); /** * Initialize all BOM headers. --- old/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java 2016-01-07 09:10:29.816641921 -0800 +++ new/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java 2016-01-07 09:10:29.628632580 -0800 @@ -42,12 +42,32 @@ import org.xml.sax.ext.DefaultHandler2; /* - * @bug 8081248 + * @bug 8081248, 8144966 * @summary Tests basic Catalog functions. */ public class CatalogTest { /* + @bug 8144966 + Verifies that passing null as CatalogFeatures will result in a NPE. + */ + @Test(expectedExceptions = NullPointerException.class) + public void testFeatureNull() { + CatalogResolver resolver = CatalogManager.catalogResolver(null, ""); + + } + + /* + @bug 8144966 + Verifies that passing null as the path will result in a NPE. + */ + @Test(expectedExceptions = NullPointerException.class) + public void testPathNull() { + String path = null; + CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), path); + } + + /* Tests basic catalog feature by using a CatalogResolver instance to resolve a DTD reference to a locally specified DTD file. If the resolution is successful, the Handler shall return the value of the entity reference @@ -61,7 +81,7 @@ } String url = getClass().getResource(xml).getFile(); try { - CatalogResolver cr = CatalogManager.catalogResolver(null, catalog); + CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog); XMLReader reader = saxParser.getXMLReader(); reader.setEntityResolver(cr); MyHandler handler = new MyHandler(saxParser); @@ -84,7 +104,7 @@ String test = "testInvalidCatalog"; try { - CatalogResolver resolver = CatalogManager.catalogResolver(null, catalog); + CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog); String actualSystemId = resolver.resolveEntity(null, "http://remote/xml/dtd/sys/alice/docAlice.dtd").getSystemId(); } catch (Exception e) { String msg = e.getMessage();