# HG changeset patch
# User joehw
# Date 1460497463 25200
# Node ID c7d898d8da1238e966bbbb87619c377c3951e272
# Parent c84d0cce090e161d736de69e941830adf8c2f87a
8151162: Public entries not searched when prefer='system'
Reviewed-by: lancea
diff -r c84d0cce090e -r c7d898d8da12 jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java Wed Jul 05 21:33:32 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java Tue Apr 12 14:44:23 2016 -0700
@@ -52,8 +52,8 @@
@Override
public InputSource resolveEntity(String publicId, String systemId) {
//Normalize publicId and systemId
- systemId = Normalizer.normalizeURI(systemId);
- publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(publicId));
+ systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId));
+ publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
//check whether systemId is an urn
if (systemId != null && systemId.startsWith("urn:publicid:")) {
@@ -87,7 +87,17 @@
}
/**
- * Resolves the publicId or systemId to one specified in the catalog.
+ * Resolves the publicId or systemId using public or system entries in the catalog.
+ *
+ * The resolution follows the following rules determined by the prefer setting:
+ *
+ * prefer "system": attempts to resolve with a system entry;
+ * attempts to resolve with a public entry when only
+ * publicId is specified.
+ *
+ * prefer "public": attempts to resolve with a system entry;
+ * attempts to resolve with a public entry if no matching
+ * system entry is found.
* @param catalog the catalog
* @param publicId the publicId
* @param systemId the systemId
@@ -99,9 +109,14 @@
//search the current catalog
catalog.reset();
if (systemId != null) {
+ /*
+ If a system identifier is specified, it is used no matter how
+ prefer is set.
+ */
resolvedSystemId = catalog.matchSystem(systemId);
}
- if (resolvedSystemId == null) {
+
+ if (resolvedSystemId == null && publicId != null) {
resolvedSystemId = catalog.matchPublic(publicId);
}
diff -r c84d0cce090e -r c7d898d8da12 jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolverImpl.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolverImpl.java Wed Jul 05 21:33:32 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolverImpl.java Tue Apr 12 14:44:23 2016 -0700
@@ -60,6 +60,9 @@
@Override
public Source resolve(String href, String base) {
+ href = Util.getNotNullOrEmpty(href);
+ base = Util.getNotNullOrEmpty(base);
+
if (href == null) return null;
CatalogImpl c = (CatalogImpl)catalog;
diff -r c84d0cce090e -r c7d898d8da12 jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Wed Jul 05 21:33:32 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Tue Apr 12 14:44:23 2016 -0700
@@ -82,6 +82,9 @@
//The length of the longest match of a suffix type
int longestSuffixMatch = 0;
+ //Indicate whether a system entry has been searched
+ boolean systemEntrySearched = false;
+
/**
* PreferType represents possible values of the prefer property
*/
@@ -156,6 +159,7 @@
longestRewriteMatch = 0;
suffixMatch = null;
longestSuffixMatch = 0;
+ systemEntrySearched = false;
}
/**
* Constructs a group entry.
@@ -212,6 +216,7 @@
* @return An URI string if a mapping is found, or null otherwise.
*/
public String matchSystem(String systemId) {
+ systemEntrySearched = true;
String match = null;
for (BaseEntry entry : entries) {
switch (entry.type) {
@@ -277,11 +282,13 @@
* @return An URI string if a mapping is found, or null otherwise.
*/
public String matchPublic(String publicId) {
- //as the specification required
- if (!isPreferPublic) {
+ /*
+ When both public and system identifiers are specified, and prefer is
+ not public (that is, system), only system entry will be used.
+ */
+ if (!isPreferPublic && systemEntrySearched) {
return null;
}
-
//match public entries
String match = null;
for (BaseEntry entry : entries) {
diff -r c84d0cce090e -r c7d898d8da12 jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java Wed Jul 05 21:33:32 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java Tue Apr 12 14:44:23 2016 -0700
@@ -122,4 +122,25 @@
}
return null;
}
+
+ /**
+ * Checks whether the specified string is null or empty, returns the original
+ * string with leading and trailing spaces removed if not.
+ * @param test the string to be tested
+ * @return the original string with leading and trailing spaces removed,
+ * or null if it is null or empty
+ *
+ */
+ static String getNotNullOrEmpty(String test) {
+ if (test == null) {
+ return test;
+ } else {
+ String temp = test.trim();
+ if (temp.length() == 0) {
+ return null;
+ } else {
+ return temp;
+ }
+ }
+ }
}
diff -r c84d0cce090e -r c7d898d8da12 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Wed Jul 05 21:33:32 2017 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Tue Apr 12 14:44:23 2016 -0700
@@ -43,10 +43,48 @@
import org.xml.sax.ext.DefaultHandler2;
/*
- * @bug 8081248, 8144966, 8146606, 8146237, 8151154, 8150969
+ * @bug 8081248, 8144966, 8146606, 8146237, 8151154, 8150969, 8151162
* @summary Tests basic Catalog functions.
*/
public class CatalogTest {
+ /*
+ * @bug 8151162
+ * Verifies that the Catalog matches specified publicId or systemId and returns
+ * results as expected.
+ */
+ @Test(dataProvider = "matchWithPrefer")
+ public void matchWithPrefer(String prefer, String cfile, String publicId, String systemId, String expected) {
+ String catalogFile = getClass().getResource(cfile).getFile();
+ Catalog c = CatalogManager.catalog(CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(), catalogFile);
+ String result;
+ if (publicId != null && publicId.length() > 0) {
+ result = c.matchPublic(publicId);
+ } else {
+ result = c.matchSystem(systemId);
+ }
+ Assert.assertEquals(expected, result);
+ }
+
+ /*
+ * @bug 8151162
+ * Verifies that the CatalogResolver resolves specified publicId or systemId
+ * in accordance with the prefer setting.
+ * prefer "system": resolves with a system entry.
+ * Exception: use the public entry when the catalog contains
+ * only public entry and only publicId is specified.
+ * prefer "public": attempts to resolve with a system entry;
+ * attempts to resolve with a public entry if no matching
+ * system entry is found.
+ */
+ @Test(dataProvider = "resolveWithPrefer")
+ public void resolveWithPrefer(String prefer, String cfile, String publicId, String systemId, String expected) {
+ String catalogFile = getClass().getResource(cfile).getFile();
+ CatalogFeatures f = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).with(CatalogFeatures.Feature.RESOLVE, "ignore").build();
+ CatalogResolver catalogResolver = CatalogManager.catalogResolver(f, catalogFile);
+ String result = catalogResolver.resolveEntity(publicId, systemId).getSystemId();
+ Assert.assertEquals(expected, result);
+ }
+
/**
* @bug 8150969
* Verifies that the defer attribute set in the catalog file takes precedence
@@ -232,6 +270,60 @@
}
}
+ static String id = "http://openjdk.java.net/xml/catalog/dtd/system.dtd";
+ /*
+ DataProvider: used to verify how prefer settings affect the result of the
+ Catalog's matching operation.
+ Data columns:
+ prefer, catalog, publicId, systemId, expected result
+ */
+ @DataProvider(name = "matchWithPrefer")
+ Object[][] getDataForMatch() {
+ return new Object[][]{
+ {"public", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"public", "sysOnly.xml", id, "", null},
+ {"public", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"system", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"system", "sysOnly.xml", id, "", null},
+ {"system", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"public", "pubOnly.xml", "", id, null},
+ {"public", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"public", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"system", "pubOnly.xml", "", id, null},
+ {"system", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"system", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"},
+ };
+ }
+
+ /*
+ DataProvider: used to verify how prefer settings affect the result of the
+ CatalogResolver's resolution operation.
+ Data columns:
+ prefer, catalog, publicId, systemId, expected result
+ */
+ @DataProvider(name = "resolveWithPrefer")
+ Object[][] getDataForResolve() {
+ return new Object[][]{
+ {"system", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"system", "pubOnly.xml", "", id, null},
+ {"system", "pubOnly.xml", id, id, null},
+ {"public", "pubOnly.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"public", "pubOnly.xml", "", id, null},
+ {"public", "pubOnly.xml", id, id, "http://local/base/dtd/public.dtd"},
+ {"system", "sysOnly.xml", id, "", null},
+ {"system", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"system", "sysOnly.xml", id, id, "http://local/base/dtd/system.dtd"},
+ {"public", "sysOnly.xml", id, "", null},
+ {"public", "sysOnly.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"public", "sysOnly.xml", id, id, "http://local/base/dtd/system.dtd"},
+ {"system", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"system", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"system", "sysAndPub.xml", id, id, "http://local/base/dtd/system.dtd"},
+ {"public", "sysAndPub.xml", id, "", "http://local/base/dtd/public.dtd"},
+ {"public", "sysAndPub.xml", "", id, "http://local/base/dtd/system.dtd"},
+ {"public", "sysAndPub.xml", id, id, "http://local/base/dtd/system.dtd"},
+ };
+ }
/*
DataProvider: catalogs that contain invalid next or delegate catalogs.
The defer attribute is set to false.
diff -r c84d0cce090e -r c7d898d8da12 jaxp/test/javax/xml/jaxp/unittest/catalog/pubOnly.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/pubOnly.xml Tue Apr 12 14:44:23 2016 -0700
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r c84d0cce090e -r c7d898d8da12 jaxp/test/javax/xml/jaxp/unittest/catalog/sysAndPub.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/sysAndPub.xml Tue Apr 12 14:44:23 2016 -0700
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r c84d0cce090e -r c7d898d8da12 jaxp/test/javax/xml/jaxp/unittest/catalog/sysOnly.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/sysOnly.xml Tue Apr 12 14:44:23 2016 -0700
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file