You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2018/06/04 10:31:54 UTC
svn commit: r1832811 -
/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java
Author: coheigea
Date: Mon Jun 4 10:31:54 2018
New Revision: 1832811
URL: http://svn.apache.org/viewvc?rev=1832811&view=rev
Log:
Replacing ThreadLocals in XMLUtils with a cache again
Modified:
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java?rev=1832811&r1=1832810&r2=1832811&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/utils/XMLUtils.java Mon Jun 4 10:31:54 2018
@@ -25,12 +25,14 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Base64;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.WeakHashMap;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -55,15 +57,9 @@ public final class XMLUtils {
private static boolean ignoreLineBreaks =
AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () -> Boolean.getBoolean("org.apache.xml.security.ignoreLineBreaks"));
-
- @SuppressWarnings("unchecked")
- private static final ThreadLocal<DocumentBuilder> tl[][] = new ThreadLocal[2][2];
- static {
- tl[0][0] = new MyThreadLocal(false, false);
- tl[0][1] = new MyThreadLocal(false, true);
- tl[1][0] = new MyThreadLocal(true, false);
- tl[1][1] = new MyThreadLocal(true, true);
- }
+
+ private static final Map<ClassLoader, DocumentBuilder[][]> DOCUMENT_BUILDERS =
+ Collections.synchronizedMap(new WeakHashMap<ClassLoader, DocumentBuilder[][]>());
private static volatile String dsPrefix = "ds";
private static volatile String ds11Prefix = "dsig11";
@@ -1061,9 +1057,9 @@ public final class XMLUtils {
public static DocumentBuilder createDocumentBuilder(
boolean validating, boolean disAllowDocTypeDeclarations
) throws ParserConfigurationException {
- DocumentBuilder documentBuilder = tl[validating ? 1 : 0][disAllowDocTypeDeclarations ? 1 : 0].get();
- documentBuilder.reset();
- return documentBuilder;
+ DocumentBuilder db = getDocumentBuilder(validating, disAllowDocTypeDeclarations);
+ db.reset();
+ return db;
}
/**
@@ -1120,32 +1116,64 @@ public final class XMLUtils {
return resizedBytes;
}
-
- private static final class MyThreadLocal extends ThreadLocal<DocumentBuilder> {
- private final boolean validating;
- private final boolean disAllowDocTypeDeclarations;
-
- public MyThreadLocal(boolean validating, boolean disAllowDocTypeDeclarations) {
- this.validating = validating;
- this.disAllowDocTypeDeclarations = disAllowDocTypeDeclarations;
+
+ private static DocumentBuilder getDocumentBuilder(boolean validating, boolean disAllowDocTypeDeclarations) throws ParserConfigurationException {
+ ClassLoader loader = getContextClassLoader();
+ if (loader == null) {
+ loader = getClassLoader(XMLUtils.class);
+ }
+ if (loader == null) {
+ return newDocumentBuilder(validating, disAllowDocTypeDeclarations);
}
- @Override
- protected DocumentBuilder initialValue() {
- try {
- DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
- dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
- if (disAllowDocTypeDeclarations) {
- dfactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ DocumentBuilder[][] cacheValue = DOCUMENT_BUILDERS.get(loader);
+ if (cacheValue == null) {
+ cacheValue = new DocumentBuilder[2][2];
+ DOCUMENT_BUILDERS.put(loader, cacheValue);
+ }
+
+ DocumentBuilder db = cacheValue[validating ? 1 : 0][disAllowDocTypeDeclarations ? 1 : 0];
+ if (db == null) {
+ db = newDocumentBuilder(validating, disAllowDocTypeDeclarations);
+ cacheValue[validating ? 1 : 0][disAllowDocTypeDeclarations ? 1 : 0] = db;
+ }
+
+ return db;
+ }
+
+ private static DocumentBuilder newDocumentBuilder(boolean validating, boolean disAllowDocTypeDeclarations) throws ParserConfigurationException {
+ DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+ f.setNamespaceAware(true);
+ f.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ if (disAllowDocTypeDeclarations) {
+ f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ }
+ f.setValidating(validating);
+ return f.newDocumentBuilder();
+ }
+
+ private static ClassLoader getContextClassLoader() {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
}
- dfactory.setValidating(validating);
- dfactory.setNamespaceAware(true);
-
- return dfactory.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- throw new RuntimeException(e);
- }
+ });
+ }
+ return Thread.currentThread().getContextClassLoader();
+ }
+
+ private static ClassLoader getClassLoader(final Class<?> clazz) {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return clazz.getClassLoader();
+ }
+ });
}
+ return clazz.getClassLoader();
}
}