This commit is contained in:
Lana Steuck 2016-09-02 02:41:56 +00:00
commit dca7f93316
17 changed files with 275 additions and 65 deletions

View File

@ -31,6 +31,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@ -72,9 +73,6 @@ class CatalogImpl extends GroupEntry implements Catalog {
//System Id for this catalog //System Id for this catalog
String systemId; String systemId;
//The parent
CatalogImpl parent = null;
/* /*
A list of catalog entry files from the input, excluding the current catalog. A list of catalog entry files from the input, excluding the current catalog.
Paths in the List are normalized. Paths in the List are normalized.
@ -107,7 +105,7 @@ class CatalogImpl extends GroupEntry implements Catalog {
* catalog file. * catalog file.
*/ */
public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException { public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException {
super(CatalogEntryType.CATALOG); super(CatalogEntryType.CATALOG, parent);
if (f == null) { if (f == null) {
throw new NullPointerException( throw new NullPointerException(
formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"})); formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"}));
@ -117,7 +115,7 @@ class CatalogImpl extends GroupEntry implements Catalog {
CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]); CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]);
} }
init(parent, f); init(f);
//Path of catalog files //Path of catalog files
String[] catalogFile = file; String[] catalogFile = file;
@ -159,19 +157,34 @@ class CatalogImpl extends GroupEntry implements Catalog {
} }
} }
} }
if (systemId != null) {
parse(systemId);
}
} }
} }
private void init(CatalogImpl parent, CatalogFeatures f) { /**
this.parent = parent; * Loads the catalog
*/
void load() {
if (systemId != null) {
parse(systemId);
}
//save this catalog before loading the next
loadedCatalogs.put(systemId, this);
//Load delegate and alternative catalogs if defer is false.
if (!isDeferred()) {
loadDelegateCatalogs();
loadNextCatalogs();
}
}
private void init(CatalogFeatures f) {
if (parent == null) { if (parent == null) {
level = 0; level = 0;
} else { } else {
level = parent.level + 1; level = parent.level + 1;
this.loadedCatalogs = parent.loadedCatalogs;
this.catalogsSearched = parent.catalogsSearched;
} }
if (f == null) { if (f == null) {
this.features = CatalogFeatures.defaults(); this.features = CatalogFeatures.defaults();
@ -196,11 +209,6 @@ class CatalogImpl extends GroupEntry implements Catalog {
entries.stream().filter((entry) -> (entry.type == CatalogEntryType.GROUP)).forEach((entry) -> { entries.stream().filter((entry) -> (entry.type == CatalogEntryType.GROUP)).forEach((entry) -> {
((GroupEntry) entry).reset(); ((GroupEntry) entry).reset();
}); });
if (parent != null) {
this.loadedCatalogs = parent.loadedCatalogs;
this.catalogsSearched = parent.catalogsSearched;
}
} }
/** /**
@ -421,16 +429,16 @@ class CatalogImpl extends GroupEntry implements Catalog {
void loadNextCatalogs() { void loadNextCatalogs() {
//loads catalogs specified in nextCatalogs //loads catalogs specified in nextCatalogs
if (nextCatalogs != null) { if (nextCatalogs != null) {
for (NextCatalog next : nextCatalogs) { nextCatalogs.stream().forEach((next) -> {
getCatalog(next.getCatalogURI()); getCatalog(next.getCatalogURI());
} });
} }
//loads catalogs from the input list //loads catalogs from the input list
if (inputFiles != null) { if (inputFiles != null) {
for (String file : inputFiles) { inputFiles.stream().forEach((file) -> {
getCatalog(getSystemId(file)); getCatalog(getSystemId(file));
} });
} }
} }
@ -445,14 +453,14 @@ class CatalogImpl extends GroupEntry implements Catalog {
return null; return null;
} }
Catalog c = null; CatalogImpl c = null;
String path = uri.toASCIIString(); String path = uri.toASCIIString();
if (verifyCatalogFile(uri)) { if (verifyCatalogFile(uri)) {
c = getLoadedCatalog(path); c = getLoadedCatalog(path);
if (c == null) { if (c == null) {
c = new CatalogImpl(this, features, path); c = new CatalogImpl(this, features, path);
saveLoadedCatalog(path, c); c.load();
} }
} }
return c; return c;
@ -464,7 +472,7 @@ class CatalogImpl extends GroupEntry implements Catalog {
* @param catalogId the catalogId associated with the Catalog object * @param catalogId the catalogId associated with the Catalog object
* @param c the Catalog to be saved * @param c the Catalog to be saved
*/ */
void saveLoadedCatalog(String catalogId, Catalog c) { void saveLoadedCatalog(String catalogId, CatalogImpl c) {
loadedCatalogs.put(catalogId, c); loadedCatalogs.put(catalogId, c);
} }

View File

@ -62,7 +62,9 @@ public final class CatalogManager {
* @throws CatalogException If an error occurs while parsing the catalog * @throws CatalogException If an error occurs while parsing the catalog
*/ */
public static Catalog catalog(CatalogFeatures features, String... paths) { public static Catalog catalog(CatalogFeatures features, String... paths) {
return new CatalogImpl(features, paths); CatalogImpl catalog = new CatalogImpl(features, paths);
catalog.load();
return catalog;
} }
/** /**

View File

@ -259,15 +259,6 @@ class CatalogReader extends DefaultHandler implements EntityResolver, URIResolve
CatalogEntryType type = CatalogEntryType.getType(localName); CatalogEntryType type = CatalogEntryType.getType(localName);
if (type == CatalogEntryType.GROUP) { if (type == CatalogEntryType.GROUP) {
inGroup = false; inGroup = false;
} else if (type == CatalogEntryType.CATALOGENTRY) {
/*
Done reading the catalog file.
Load delegate and alternative catalogs if defer is false.
*/
if (!catalog.isDeferred()) {
catalog.loadDelegateCatalogs();
catalog.loadNextCatalogs();
}
} }
} }

View File

@ -119,6 +119,10 @@ final class CatalogResolverImpl implements CatalogResolver {
String result = null; String result = null;
CatalogImpl c = (CatalogImpl)catalog; CatalogImpl c = (CatalogImpl)catalog;
String uri = Normalizer.normalizeURI(href); String uri = Normalizer.normalizeURI(href);
if (uri == null) {
return null;
}
//check whether uri is an urn //check whether uri is an urn
if (uri != null && uri.startsWith(Util.URN)) { if (uri != null && uri.startsWith(Util.URN)) {
String publicId = Normalizer.decodeURN(uri); String publicId = Normalizer.decodeURN(uri);

View File

@ -48,6 +48,9 @@ class GroupEntry extends BaseEntry {
//Value of the prefer attribute //Value of the prefer attribute
boolean isPreferPublic = true; boolean isPreferPublic = true;
//The parent of the catalog instance
CatalogImpl parent = null;
//The catalog instance this group belongs to //The catalog instance this group belongs to
CatalogImpl catalog; CatalogImpl catalog;
@ -55,10 +58,10 @@ class GroupEntry extends BaseEntry {
List<BaseEntry> entries = new ArrayList<>(); List<BaseEntry> entries = new ArrayList<>();
//loaded delegated catalog by system id //loaded delegated catalog by system id
Map<String, Catalog> delegateCatalogs = new HashMap<>(); Map<String, CatalogImpl> delegateCatalogs = new HashMap<>();
//A list of all loaded Catalogs, including this, and next catalogs //A list of all loaded Catalogs, including this, and next catalogs
Map<String, Catalog> loadedCatalogs = new HashMap<>(); Map<String, CatalogImpl> loadedCatalogs = new HashMap<>();
/* /*
A list of Catalog Ids that have already been searched in a matching A list of Catalog Ids that have already been searched in a matching
@ -136,8 +139,9 @@ class GroupEntry extends BaseEntry {
* *
* @param type The type of the entry * @param type The type of the entry
*/ */
public GroupEntry(CatalogEntryType type) { public GroupEntry(CatalogEntryType type, CatalogImpl parent) {
super(type); super(type);
this.parent = parent;
} }
/** /**
@ -163,7 +167,7 @@ class GroupEntry extends BaseEntry {
} }
/** /**
* Constructs a group entry. * Constructs a group entry.
* @param catalog The parent catalog * @param catalog The catalog this GroupEntry belongs
* @param base The baseURI attribute * @param base The baseURI attribute
* @param attributes The attributes * @param attributes The attributes
*/ */
@ -445,13 +449,14 @@ class GroupEntry extends BaseEntry {
* @param catalogId the catalog Id * @param catalogId the catalog Id
*/ */
Catalog loadCatalog(URI catalogURI) { Catalog loadCatalog(URI catalogURI) {
Catalog delegateCatalog = null; CatalogImpl delegateCatalog = null;
if (catalogURI != null) { if (catalogURI != null) {
String catalogId = catalogURI.toASCIIString(); String catalogId = catalogURI.toASCIIString();
delegateCatalog = getLoadedCatalog(catalogId); delegateCatalog = getLoadedCatalog(catalogId);
if (delegateCatalog == null) { if (delegateCatalog == null) {
if (verifyCatalogFile(catalogURI)) { if (verifyCatalogFile(catalogURI)) {
delegateCatalog = new CatalogImpl(catalog, features, catalogId); delegateCatalog = new CatalogImpl(catalog, features, catalogId);
delegateCatalog.load();
delegateCatalogs.put(catalogId, delegateCatalog); delegateCatalogs.put(catalogId, delegateCatalog);
} }
} }
@ -467,8 +472,8 @@ class GroupEntry extends BaseEntry {
* @return a Catalog object previously loaded, or null if none in the saved * @return a Catalog object previously loaded, or null if none in the saved
* list * list
*/ */
Catalog getLoadedCatalog(String catalogId) { CatalogImpl getLoadedCatalog(String catalogId) {
Catalog c = null; CatalogImpl c = null;
//checl delegate Catalogs //checl delegate Catalogs
c = delegateCatalogs.get(catalogId); c = delegateCatalogs.get(catalogId);
@ -504,7 +509,7 @@ class GroupEntry extends BaseEntry {
} }
String catalogId = catalogURI.toASCIIString(); String catalogId = catalogURI.toASCIIString();
if (catalogsSearched.contains(catalogId)) { if (catalogsSearched.contains(catalogId) || isCircular(catalogId)) {
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_CIRCULAR_REFERENCE, CatalogMessages.reportRunTimeError(CatalogMessages.ERR_CIRCULAR_REFERENCE,
new Object[]{CatalogMessages.sanitize(catalogId)}); new Object[]{CatalogMessages.sanitize(catalogId)});
} }
@ -512,4 +517,20 @@ class GroupEntry extends BaseEntry {
return true; return true;
} }
/**
* Checks whether the catalog is circularly referenced
* @param systemId the system identifier of the catalog to be loaded
* @return true if is circular, false otherwise
*/
boolean isCircular(String systemId) {
if (parent == null) {
return false;
}
if (parent.systemId.equals(systemId)) {
return true;
}
return parent.isCircular(systemId);
}
} }

View File

@ -42,6 +42,9 @@ public class JdkXmlFeatures {
ORACLE_JAXP_PROPERTY_PREFIX + "enableExtensionFunctions"; ORACLE_JAXP_PROPERTY_PREFIX + "enableExtensionFunctions";
public static final String SP_ENABLE_EXTENSION_FUNCTION = public static final String SP_ENABLE_EXTENSION_FUNCTION =
"javax.xml.enableExtensionFunctions"; "javax.xml.enableExtensionFunctions";
// This is the correct name by the spec
public static final String SP_ENABLE_EXTENSION_FUNCTION_SPEC =
"jdk.xml.enableExtensionFunctions";
public static final String CATALOG_FEATURES = "javax.xml.catalog.catalogFeatures"; public static final String CATALOG_FEATURES = "javax.xml.catalog.catalogFeatures";
public final static String PROPERTY_USE_CATALOG = XMLConstants.USE_CATALOG; public final static String PROPERTY_USE_CATALOG = XMLConstants.USE_CATALOG;
@ -49,11 +52,11 @@ public class JdkXmlFeatures {
public static enum XmlFeature { public static enum XmlFeature {
/** /**
* Feature enableExtensionFunctions * Feature enableExtensionFunctions
* FSP: extension function is enforced by FSP. When FSP is on, entension * FSP: extension function is enforced by FSP. When FSP is on, extension
* function is disabled. * function is disabled.
*/ */
ENABLE_EXTENSION_FUNCTION(ORACLE_ENABLE_EXTENSION_FUNCTION, ENABLE_EXTENSION_FUNCTION(ORACLE_ENABLE_EXTENSION_FUNCTION,
SP_ENABLE_EXTENSION_FUNCTION, true, false, true, true), SP_ENABLE_EXTENSION_FUNCTION_SPEC, true, false, true, true),
/** /**
* The {@link javax.xml.XMLConstants.USE_CATALOG} feature. * The {@link javax.xml.XMLConstants.USE_CATALOG} feature.
* FSP: USE_CATALOG is not enforced by FSP. * FSP: USE_CATALOG is not enforced by FSP.
@ -148,6 +151,30 @@ public class JdkXmlFeatures {
} }
/**
* Maps old property names with the new ones. This map is used to keep track of
* name changes so that old or incorrect names continue to be supported for compatibility.
*/
public static enum NameMap {
ENABLE_EXTENSION_FUNCTION(SP_ENABLE_EXTENSION_FUNCTION_SPEC, SP_ENABLE_EXTENSION_FUNCTION);
final String newName;
final String oldName;
NameMap(String newName, String oldName) {
this.newName = newName;
this.oldName = oldName;
}
String getOldName(String newName) {
if (newName.equals(this.newName)) {
return oldName;
}
return null;
}
}
/** /**
* States of the settings of a property, in the order: default value, value * States of the settings of a property, in the order: default value, value
* set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system
@ -316,6 +343,15 @@ public class JdkXmlFeatures {
private void readSystemProperties() { private void readSystemProperties() {
for (XmlFeature feature : XmlFeature.values()) { for (XmlFeature feature : XmlFeature.values()) {
getSystemProperty(feature, feature.systemProperty()); getSystemProperty(feature, feature.systemProperty());
if (!getSystemProperty(feature, feature.systemProperty())) {
//if system property is not found, try the older form if any
for (NameMap nameMap : NameMap.values()) {
String oldName = nameMap.getOldName(feature.systemProperty());
if (oldName != null) {
getSystemProperty(feature, oldName);
}
}
}
} }
} }

View File

@ -24,7 +24,3 @@
########################################################################### ###########################################################################
javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.sh 8147431 generic-all javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.sh 8147431 generic-all
javax/xml/jaxp/unittest/common/TransformationWarningsTest.java 8150145 generic-all
javax/xml/jaxp/unittest/common/ValidationWarningsTest.java 8150145 generic-all

View File

@ -64,12 +64,12 @@ public class DeferFeatureTest {
public Object[][] data() { public Object[][] data() {
return new Object[][]{ return new Object[][]{
// By default, alternative catalogs are not loaded. // By default, alternative catalogs are not loaded.
{createCatalog(CatalogFeatures.defaults()), 0}, {createCatalog(CatalogFeatures.defaults()), 1},
// Alternative catalogs are not loaded when DEFER is set to true. // Alternative catalogs are not loaded when DEFER is set to true.
{createCatalog(createDeferFeature(DEFER_TRUE)), 0}, {createCatalog(createDeferFeature(DEFER_TRUE)), 1},
// The 3 alternative catalogs are not pre-loaded // The 3 alternative catalogs are pre-loaded along with the parent
//when DEFER is set to false. //when DEFER is set to false.
{createCatalog(createDeferFeature(DEFER_FALSE)), 3}}; {createCatalog(createDeferFeature(DEFER_FALSE)), 4}};
} }
private CatalogFeatures createDeferFeature(String defer) { private CatalogFeatures createDeferFeature(String defer) {

View File

@ -93,7 +93,7 @@ public class BasicModularXMLParserTest {
*/ */
public void testWithOneProvider() throws Exception { public void testWithOneProvider() throws Exception {
int exitValue int exitValue
= executeTestJava("-mp", MOD_DIR1.toString(), = executeTestJava("--module-path", MOD_DIR1.toString(),
"-cp", CLASSES_DIR.toString(), "-cp", CLASSES_DIR.toString(),
"Main", "xmlprovider1") "Main", "xmlprovider1")
.outputTo(System.out) .outputTo(System.out)
@ -108,7 +108,7 @@ public class BasicModularXMLParserTest {
*/ */
public void testWithTwoProvider() throws Exception { public void testWithTwoProvider() throws Exception {
int exitValue int exitValue
= executeTestJava("-mp", MOD_DIR1.toString() + File.pathSeparator + MOD_DIR2.toString(), = executeTestJava("--module-path", MOD_DIR1.toString() + File.pathSeparator + MOD_DIR2.toString(),
"-cp", CLASSES_DIR.toString(), "-cp", CLASSES_DIR.toString(),
"Main", "xmlprovider1", "xmlprovider2") "Main", "xmlprovider1", "xmlprovider2")
.outputTo(System.out) .outputTo(System.out)

View File

@ -92,6 +92,34 @@ public class CatalogTest extends CatalogSupportBase {
super.setUp(); super.setUp();
} }
/*
* @bug 8162431
* Verifies that circular references are caught and
* CatalogException is thrown.
*/
@Test(dataProvider = "getFeatures", expectedExceptions = CatalogException.class)
public void testCircularRef(CatalogFeatures cf, String xml) {
CatalogResolver catalogResolver = CatalogManager.catalogResolver(
cf,
getClass().getResource(xml).getFile());
catalogResolver.resolve("anyuri", "");
}
/*
DataProvider: used to verify circular reference
Data columns: CatalogFeatures, catalog
*/
@DataProvider(name = "getFeatures")
public Object[][] getFeatures() {
return new Object[][]{
{CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
"catalogReferCircle-itself.xml"},
{CatalogFeatures.defaults(), "catalogReferCircle-itself.xml"},
{CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
"catalogReferCircle-left.xml"},
{CatalogFeatures.defaults(), "catalogReferCircle-left.xml"},};
}
/* /*
* @bug 8163232 * @bug 8163232

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<nextCatalog catalog="catalogReferCircle-itself.xml" />
</catalog>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<nextCatalog catalog="catalogReferCircle-right.xml" />
</catalog>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<nextCatalog catalog="catalogReferCircle-left.xml" />
</catalog>

View File

@ -42,12 +42,13 @@ import org.testng.annotations.Test;
* @test * @test
* @bug 8144593 * @bug 8144593
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @compile -XDignore.symbol.file TestSAXDriver.java
* @run testng/othervm -DrunSecMngr=true common.TransformationWarningsTest * @run testng/othervm -DrunSecMngr=true common.TransformationWarningsTest
* @run testng/othervm common.TransformationWarningsTest * @run testng/othervm common.TransformationWarningsTest
* @summary Check that warnings about unsupported properties from parsers * @summary Check that warnings about unsupported properties from parsers
* are suppressed during the transformation process. * are suppressed during the transformation process.
*/ */
@Listeners({jaxp.library.BasePolicy.class}) @Listeners({jaxp.library.BasePolicy.class, jaxp.library.InternalAPIPolicy.class})
public class TransformationWarningsTest extends WarningsTestBase { public class TransformationWarningsTest extends WarningsTestBase {
@BeforeClass @BeforeClass
@ -80,7 +81,12 @@ public class TransformationWarningsTest extends WarningsTestBase {
Source xslsrc = new StreamSource(new StringReader(xsl)); Source xslsrc = new StreamSource(new StringReader(xsl));
// Create factory and transformer // Create factory and transformer
TransformerFactory tf = TransformerFactory.newInstance(); TransformerFactory tf;
// newTransformer() method doc states that different transformer
// factories can be used concurrently by different Threads.
synchronized (TransformerFactory.class) {
tf = TransformerFactory.newInstance();
}
Transformer t = tf.newTransformer(xslsrc); Transformer t = tf.newTransformer(xslsrc);
// Set URI Resolver to return the newly constructed xml // Set URI Resolver to return the newly constructed xml

View File

@ -46,6 +46,7 @@ import org.xml.sax.InputSource;
* @bug 8144593 * @bug 8144593
* @key intermittent * @key intermittent
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @compile -XDignore.symbol.file TestSAXDriver.java
* @run testng/othervm -DrunSecMngr=true common.ValidationWarningsTest * @run testng/othervm -DrunSecMngr=true common.ValidationWarningsTest
* @run testng/othervm common.ValidationWarningsTest * @run testng/othervm common.ValidationWarningsTest
* @summary Check that warnings about unsupported properties from SAX * @summary Check that warnings about unsupported properties from SAX

View File

@ -23,11 +23,15 @@
package common; package common;
import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -58,25 +62,27 @@ public abstract class WarningsTestBase {
PrintStream defStdErr = System.err; PrintStream defStdErr = System.err;
//Set new byte array stream as standard error stream //Set new byte array stream as standard error stream
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(5000); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(5000);
System.setErr(new PrintStream(byteStream)); runWithAllPerm(() -> System.setErr(new PrintStream(byteStream)));
//Execute multiple TestWorker tasks //Execute multiple TestWorker tasks
for (int id = 0; id < THREADS_COUNT; id++) { for (int id = 0; id < THREADS_COUNT; id++) {
EXECUTOR.execute(new TestWorker(id)); EXECUTOR.execute(new TestWorker(id));
} }
//Initiate shutdown of previously submitted task //Initiate shutdown of previously submitted task
EXECUTOR.shutdown(); runWithAllPerm(EXECUTOR::shutdown);
//Wait for termination of submitted tasks //Wait for termination of submitted tasks
if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) { if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) {
//If not all tasks terminates during the time out force them to shutdown //If not all tasks terminates during the time out force them to shutdown
EXECUTOR.shutdownNow(); runWithAllPerm(EXECUTOR::shutdownNow);
} }
//Restore default standard error stream //Restore default standard error stream
System.setErr(defStdErr); runWithAllPerm(() -> System.setErr(defStdErr));
//Print tasks stderr output //Print tasks stderr output
String errContent = byteStream.toString(); String errContent = byteStream.toString();
System.out.println("Standard error output content:"); System.out.println("Standard error output content:");
System.out.println(errContent); System.out.println(errContent);
//Check tasks stderr output for quatity of warning messages //Check if uncaught exceptions were observed by one or more threads
Assert.assertFalse(uncaughtExceptions);
//Check tasks stderr output for quantity of warning messages
Assert.assertTrue(warningPrintedOnce(XMLConstants.ACCESS_EXTERNAL_DTD, errContent)); Assert.assertTrue(warningPrintedOnce(XMLConstants.ACCESS_EXTERNAL_DTD, errContent));
Assert.assertTrue(warningPrintedOnce(ENT_EXP_PROPERTY, errContent)); Assert.assertTrue(warningPrintedOnce(ENT_EXP_PROPERTY, errContent));
Assert.assertTrue(warningPrintedOnce(XMLConstants.FEATURE_SECURE_PROCESSING, errContent)); Assert.assertTrue(warningPrintedOnce(XMLConstants.FEATURE_SECURE_PROCESSING, errContent));
@ -123,6 +129,25 @@ public abstract class WarningsTestBase {
} }
} }
// Thread factory that handles uncaughtExceptions and prints them
// to stdout instead of stderr.
private static class TestThreadFactory implements ThreadFactory {
public Thread newThread(final Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable thr) {
thr.printStackTrace(System.out);
uncaughtExceptions = true;
}
});
return t;
}
}
//Flag that indicates if one or more threads from thread pool caught unhandled exception
private static boolean uncaughtExceptions = false;
//Entity expansion limit property name //Entity expansion limit property name
private static final String ENT_EXP_PROPERTY = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit"; private static final String ENT_EXP_PROPERTY = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
//Number of simultaneous test threads //Number of simultaneous test threads
@ -130,7 +155,7 @@ public abstract class WarningsTestBase {
//Number of iterations per one thread //Number of iterations per one thread
private static final int ITERATIONS_PER_THREAD = 4; private static final int ITERATIONS_PER_THREAD = 4;
//Test thread pool //Test thread pool
private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(); private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(new TestThreadFactory());
//Cyclic barrier for threads startup synchronisation //Cyclic barrier for threads startup synchronization
private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT); private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT);
} }

View File

@ -34,11 +34,16 @@ import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
import org.testng.Assert;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import static jaxp.library.JAXPTestUtilities.getSystemProperty;
/* /*
* @test * @test
@ -49,9 +54,65 @@ import static org.testng.Assert.assertEquals;
* @summary This class contains tests for XSLT functions. * @summary This class contains tests for XSLT functions.
*/ */
//@Listeners({jaxp.library.BasePolicy.class}) //uncomment this line after 8161454 is resolved @Listeners({jaxp.library.BasePolicy.class})
public class XSLTFunctionsTest { public class XSLTFunctionsTest {
/**
* @bug 8161454
* Verifies that the new / correct name is supported, as is the old / incorrect
* one for compatibility
*/
@Test
public void testNameChange() {
boolean feature;
TransformerFactory tf = TransformerFactory.newInstance();
feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION);
System.out.println("Default setting: " + feature);
// The default: true if no SecurityManager, false otherwise
Assert.assertTrue(feature == getDefault());
setSystemProperty(SP_ENABLE_EXTENSION_FUNCTION, getDefaultOpposite());
tf = TransformerFactory.newInstance();
feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION);
System.out.println("After setting " + SP_ENABLE_EXTENSION_FUNCTION + ": " + feature);
clearSystemProperty(SP_ENABLE_EXTENSION_FUNCTION);
// old/incorrect name is still supported
Assert.assertTrue(feature != getDefault());
setSystemProperty(SP_ENABLE_EXTENSION_FUNCTION_SPEC, getDefaultOpposite());
tf = TransformerFactory.newInstance();
feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION);
System.out.println("After setting " + SP_ENABLE_EXTENSION_FUNCTION_SPEC + ": " + feature);
clearSystemProperty(SP_ENABLE_EXTENSION_FUNCTION_SPEC);
// new/correct name is effective
Assert.assertTrue(feature != getDefault());
}
final boolean isSecure;
{
String runSecMngr = getSystemProperty("runSecMngr");
isSecure = runSecMngr != null && runSecMngr.equals("true");
}
// The default: true if no SecurityManager, false otherwise
private boolean getDefault() {
if (isSecure) {
return false;
} else {
return true;
}
}
// Gets a String value that is opposite to the default value
private String getDefaultOpposite() {
if (isSecure) {
return "true";
} else {
return "false";
}
}
/** /**
* @bug 8062518 8153082 * @bug 8062518 8153082
* Verifies that a reference to the DTM created by XSLT document function is * Verifies that a reference to the DTM created by XSLT document function is
@ -72,7 +133,9 @@ public class XSLTFunctionsTest {
// Create factory and transformer // Create factory and transformer
TransformerFactory tf = TransformerFactory.newInstance(); TransformerFactory tf = TransformerFactory.newInstance();
tf.setFeature("http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions", true); tf.setFeature(ORACLE_ENABLE_EXTENSION_FUNCTION, true);
tf.setAttribute(EXTENSION_CLASS_LOADER,
runWithAllPerm(() -> Thread.currentThread().getContextClassLoader()));
Transformer t = tf.newTransformer( xslsrc ); Transformer t = tf.newTransformer( xslsrc );
t.setErrorListener(tf.getErrorListener()); t.setErrorListener(tf.getErrorListener());
@ -133,5 +196,16 @@ public class XSLTFunctionsTest {
static final String documentTesteExpectedResult = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" static final String documentTesteExpectedResult = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<root>[Test:Doc][Test:External Doc]</root>"; + "<root>[Test:Doc][Test:External Doc]</root>";
}
public static final String ORACLE_JAXP_PROPERTY_PREFIX =
"http://www.oracle.com/xml/jaxp/properties/";
/**
* Feature enableExtensionFunctions
*/
public static final String ORACLE_ENABLE_EXTENSION_FUNCTION =
ORACLE_JAXP_PROPERTY_PREFIX + "enableExtensionFunctions";
static final String SP_ENABLE_EXTENSION_FUNCTION = "javax.xml.enableExtensionFunctions";
// This is the correct name by the spec
static final String SP_ENABLE_EXTENSION_FUNCTION_SPEC = "jdk.xml.enableExtensionFunctions";
private static final String EXTENSION_CLASS_LOADER = "jdk.xml.transform.extensionClassLoader";
}