[maven-release-plugin] copy for tag xmlsec-2.0.11
git-svn-id: https://svn.apache.org/repos/asf/santuario/xml-security-java/tags/xmlsec-2.0.11@1833053 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 8f761f2..727dbbb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -573,6 +573,12 @@
<version>${bcprov.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.carrotsearch</groupId>
+ <artifactId>junit-benchmarks</artifactId>
+ <version>0.7.2</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<distributionManagement>
diff --git a/src/main/java/org/apache/xml/security/utils/XMLUtils.java b/src/main/java/org/apache/xml/security/utils/XMLUtils.java
index e627db8..9aa9919 100644
--- a/src/main/java/org/apache/xml/security/utils/XMLUtils.java
+++ b/src/main/java/org/apache/xml/security/utils/XMLUtils.java
@@ -23,14 +23,12 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
-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;
@@ -61,8 +59,14 @@
}
});
- private static final Map<ClassLoader, DocumentBuilder[][]> DOCUMENT_BUILDERS =
- Collections.synchronizedMap(new WeakHashMap<ClassLoader, DocumentBuilder[][]>());
+ @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 volatile String dsPrefix = "ds";
private static volatile String ds11Prefix = "dsig11";
@@ -1057,9 +1061,9 @@
public static DocumentBuilder createDocumentBuilder(
boolean validating, boolean disAllowDocTypeDeclarations
) throws ParserConfigurationException {
- DocumentBuilder db = getDocumentBuilder(validating, disAllowDocTypeDeclarations);
- db.reset();
- return db;
+ DocumentBuilder documentBuilder = tl[validating ? 1 : 0][disAllowDocTypeDeclarations ? 1 : 0].get();
+ documentBuilder.reset();
+ return documentBuilder;
}
/**
@@ -1072,63 +1076,31 @@
return true;
}
- 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);
+ 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;
}
- 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();
+ @Override
+ protected DocumentBuilder initialValue() {
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ try {
+ dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+ if (disAllowDocTypeDeclarations) {
+ dfactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
}
- });
- }
- return Thread.currentThread().getContextClassLoader();
- }
+ dfactory.setValidating(validating);
+ dfactory.setNamespaceAware(true);
- 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 dfactory.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ }
}
- return clazz.getClassLoader();
}
}
diff --git a/src/test/java/org/apache/xml/security/test/dom/utils/XMLUtilsPerformanceTest.java b/src/test/java/org/apache/xml/security/test/dom/utils/XMLUtilsPerformanceTest.java
new file mode 100644
index 0000000..3d896bb
--- /dev/null
+++ b/src/test/java/org/apache/xml/security/test/dom/utils/XMLUtilsPerformanceTest.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.xml.security.test.dom.utils;
+
+import java.io.StringReader;
+
+import org.apache.xml.security.utils.XMLUtils;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+
+import com.carrotsearch.junitbenchmarks.AbstractBenchmark;
+import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
+
+/**
+ * Some benchmark tests for the caching logic in XMLUtils
+ */
+public class XMLUtilsPerformanceTest extends AbstractBenchmark {
+
+ @BenchmarkOptions(callgc = false, benchmarkRounds = 100000, warmupRounds = 100)
+ @Test
+ public void testCreateDocumentBuilder() throws Exception {
+ InputSource inputSource = new InputSource(new StringReader("<xml>123</xml>"));
+ XMLUtils.createDocumentBuilder(false).parse(inputSource);
+ }
+
+}