You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2008/10/18 23:15:18 UTC

svn commit: r705924 - /incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java

Author: etnu
Date: Sat Oct 18 14:15:17 2008
New Revision: 705924

URL: http://svn.apache.org/viewvc?rev=705924&view=rev
Log:
Switched to using a ThreadLocal instead of a builder pool when threading is available. The pool was originally thought to be a better option, but in practice the total number of threads in a container remains fairly constant due to the use of thread pools on both executors and servlet containers.

The need for the reusability check may no longer be relevant since we now have a hard dependency on xerces 2.9, which supports reusable builders.


Modified:
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java

Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java?rev=705924&r1=705923&r2=705924&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java Sat Oct 18 14:15:17 2008
@@ -19,8 +19,6 @@
 
 import org.apache.shindig.common.uri.Uri;
 
-import com.google.common.collect.Lists;
-
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
@@ -31,7 +29,6 @@
 
 import java.io.IOException;
 import java.io.StringReader;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -60,11 +57,24 @@
     }
   };
 
-  private static final List<DocumentBuilder> builderPool = Lists.newArrayList();
-  private static boolean canUsePooling = false;
+  private static boolean canReuseBuilders = false;
 
   private static final DocumentBuilderFactory builderFactory
       = DocumentBuilderFactory.newInstance();
+
+  private static final ThreadLocal<DocumentBuilder> reusableBuilder
+      = new ThreadLocal<DocumentBuilder>() {
+          @Override
+          protected DocumentBuilder initialValue() {
+            try {
+              LOG.info("Created a new document builder");
+              return builderFactory.newDocumentBuilder();
+            } catch (ParserConfigurationException e) {
+              throw new RuntimeException(e);
+            }
+          }
+        };
+
   static {
     // Disable various insecure and/or expensive options.
     builderFactory.setValidating(false);
@@ -76,6 +86,7 @@
           "http://xml.org/sax/features/external-general-entities", false);
     } catch (IllegalArgumentException e) {
       // Not supported by some very old parsers.
+      LOG.info("XML parsers will load external general entities.");
     }
 
     try {
@@ -83,6 +94,7 @@
           "http://xml.org/sax/features/external-parameter-entities", false);
     } catch (IllegalArgumentException e) {
       // Not supported by some very old parsers.
+      LOG.info("XML parsers will load external parameter entities.");
     }
 
     try {
@@ -90,24 +102,29 @@
           "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
     } catch (IllegalArgumentException e) {
       // Only supported by Apache's XML parsers.
+      LOG.info("XML parsers will load external DTDs.");
     }
 
     try {
       builderFactory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
     } catch (IllegalArgumentException e) {
       // Not supported by older parsers.
+      LOG.info("Not using secure XML processing.");
     }
 
     try {
       DocumentBuilder builder = builderFactory.newDocumentBuilder();
       builder.reset();
-      canUsePooling = true;
+      canReuseBuilders = true;
+      LOG.info("Reusing document builders");
     } catch (UnsupportedOperationException e) {
       // Only supported by newer parsers (xerces 2.8.x+ for instance).
-      canUsePooling = false;
+      canReuseBuilders = false;
+      LOG.info("Not reusing document builders");
     } catch (ParserConfigurationException e) {
       // Only supported by newer parsers (xerces 2.8.x+ for instance).
-      canUsePooling = false;
+      canReuseBuilders = false;
+      LOG.info("Not reusing document builders");
     }
   }
 
@@ -248,7 +265,7 @@
     return getIntAttribute(node, attr, 0);
   }
 
-  /** 
+  /**
    * @return first child node matching the specified name
    */
   public static Node getFirstNamedChildNode(Node root, String nodeName) {
@@ -265,18 +282,11 @@
   /**
    * Fetch a builder from the pool, creating a new one only if necessary.
    */
-  private static DocumentBuilder getBuilderFromPool() throws ParserConfigurationException {
+  private static DocumentBuilder getBuilder() throws ParserConfigurationException {
     DocumentBuilder builder;
-    if (canUsePooling) {
-      synchronized (builderPool) {
-        int size = builderPool.size();
-        if (size > 0) {
-          builder = builderPool.remove(size - 1);
-          builder.reset();
-        } else {
-          builder = builderFactory.newDocumentBuilder();
-        }
-      }
+    if (canReuseBuilders) {
+      builder = reusableBuilder.get();
+      builder.reset();
     } else {
       builder = builderFactory.newDocumentBuilder();
     }
@@ -285,19 +295,6 @@
   }
 
   /**
-   * Return a builder to the pool, allowing it to be re-used by future operations.
-   */
-  private static void returnBuilderToPool(DocumentBuilder builder) {
-    if (canUsePooling) {
-      synchronized (builderPool) {
-        builderPool.add(builder);
-      }
-    }
-  }
-
-
-
-  /**
    * Attempts to parse the input xml into a single element.
    * @param xml
    * @return The document object
@@ -305,10 +302,9 @@
    */
   public static Element parse(String xml) throws XmlException {
     try {
-      DocumentBuilder builder = getBuilderFromPool();
+      DocumentBuilder builder = getBuilder();
       InputSource is = new InputSource(new StringReader(xml.trim()));
       Element element = builder.parse(is).getDocumentElement();
-      returnBuilderToPool(builder);
       return element;
     } catch (SAXParseException e) {
       throw new XmlException(