Hello,

Please see what I propose to solve problem with many allocated
DocumentBuilders (Sorry, but I propose revert back changes proposed by
Sanjiva).
Other classes were DocumentBuilder is used can be easily adopted in the same
way as Call is.


Best regards,
Pavel

Index: XMLParserUtils.java
===================================================================
RCS file: 
/home/cvspublic/xml-soap/java/src/org/apache/soap/util/xml/XMLParserUtils.java,v
retrieving revision 1.6
diff -u -r1.6 XMLParserUtils.java
--- XMLParserUtils.java 28 Oct 2002 16:37:02 -0000      1.6
+++ XMLParserUtils.java 29 Oct 2002 15:38:07 -0000
@@ -2,7 +2,7 @@
  * The Apache Software License, Version 1.1
  *
  *
- * Copyright (c) 2000 The Apache Software Foundation.  All rights 
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -10,7 +10,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
@@ -18,7 +18,7 @@
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:  
+ *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
@@ -26,7 +26,7 @@
  *
  * 4. The names "SOAP" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written 
+ *    software without prior written permission. For written
  *    permission, please contact [EMAIL PROTECTED]
  *
  * 5. Products derived from this software may not be called "Apache",
@@ -57,7 +57,8 @@
 
 package org.apache.soap.util.xml;
 
-import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
 import javax.xml.parsers.*;
 import org.xml.sax.*;
 import org.xml.sax.helpers.*;
@@ -72,8 +73,9 @@
  * @author Matthew J. Duftler ([EMAIL PROTECTED])
  */
 public class XMLParserUtils {
+
   private static DocumentBuilderFactory dbf = null;
-  private static HashMap docBuilderTable = new HashMap ();
+  private static List allocatedBuildersList = new ArrayList(10);
 
   static {
     // Create a default instance.
@@ -91,7 +93,7 @@
    * @param factoryClassName the fully-qualified name of a class
    * that implemements DocumentBuilderFactory. If this argument
    * is null, the default (platform-specific) implementation is
-   * used. Basically, if this argument is not null, the 
+   * used. Basically, if this argument is not null, the
    * javax.xml.parsers.DocumentBuilderFactory system property
    * is set (with the specified value) before the
    * DocumentBuilderFactory.newInstance() method is invoked.
@@ -121,32 +123,59 @@
       and reused to create any number of DocumentBuilder instances
       with the same configuration options.
     */
+    allocatedBuildersList.clear();
   }
 
   /**
-   * Use this method to get a JAXP document builder.  
-   * This method creates a namespace aware, nonvalidating 
+   * Use this method to get a JAXP document builder.
+   * This method creates a namespace aware, nonvalidating
    * instance of the XML parser.
    *
-   * @return DocumentBuilder an instance of a document builder, 
+   * @return DocumentBuilder an instance of a document builder,
    * or null if a ParserConfigurationException was thrown.
    */
   synchronized public static DocumentBuilder getXMLDocBuilder()
     throws IllegalArgumentException {
-    // if a document builder has already been created for this thread 
-    // then just reuse that. otherwise create a new one and remember it.
-    Thread t = Thread.currentThread ();
-    DocumentBuilder db = (DocumentBuilder) docBuilderTable.get (t);
-    if (db != null) {
-      return db;
-    } else {
       try {
-        db = dbf.newDocumentBuilder();
-        docBuilderTable.put (t, db);
-        return db;
+        return dbf.newDocumentBuilder();
       } catch (ParserConfigurationException pce) {
         throw new IllegalArgumentException(pce.toString());
       }
-    }
   }
+
+
+  /**
+   * Use this method to get a JAXP document builder.
+   * This method either returns a previosly allocated DocumentBuilder
+   * or creates a namespace aware, nonvalidating
+   * instance of the XML parser.
+   *
+   * @return DocumentBuilder an instance of a document builder,
+   * or null if a ParserConfigurationException was thrown.
+   */
+  synchronized public static DocumentBuilder getXMLDocBuilderFromPool() {
+      // First check if we have DocBuider available
+      DocumentBuilder  builder = null;
+      int size = allocatedBuildersList.size();
+      if ( size > 0) {
+          builder = (DocumentBuilder)allocatedBuildersList.get(size-1);
+          allocatedBuildersList.remove(size-1);
+      } else
+          // Not available - create a new DocumentBuilder
+          builder = XMLParserUtils.getXMLDocBuilder();
+
+      return builder;
+  }
+
+  /**
+   * Return a JAXP document builder, previosly allocated by method
+   * getXMLDocBuilderFromPool() for further reuse
+   *
+   * @param builder a DocumentBuilder to release
+   */
+  synchronized public static void returnDocumentBuilderToPool(DocumentBuilder 
+builder) {
+      if (builder != null)
+          allocatedBuildersList.add(builder);
+  }
+
 }
Index: Call.java
===================================================================
RCS file: /home/cvspublic/xml-soap/java/src/org/apache/soap/rpc/Call.java,v
retrieving revision 1.18
diff -u -r1.18 Call.java
--- Call.java   18 Oct 2002 13:36:00 -0000      1.18
+++ Call.java   29 Oct 2002 15:38:56 -0000
@@ -87,7 +87,6 @@
  */
 public class Call extends RPCMessage
 {
-  private DocumentBuilder     xdb;
   private SOAPMappingRegistry smr = null;
   private SOAPTransport       st  = null;;
   private int                 to  = 0;
@@ -149,7 +148,7 @@
   {
     this.st = st;
   }
-   
+
   public SOAPTransport getSOAPTransport()
   {
     return st;
@@ -157,16 +156,16 @@
 
   /**
    * Set timeout in our MessageContext.
-   * 
+   *
    * @param value the maximum amount of time, in milliseconds
    */
   public void setTimeout (int value) {
     to = value;
   }
-    
+
   /**
    * Get timeout from our MessageContext.
-   * 
+   *
    * @return value the maximum amount of time, in milliseconds
    */
   public int getTimeout () {
@@ -188,7 +187,7 @@
   public void setUseDocumentBuilder(boolean useDocumentBuilder) {
     this.useDocumentBuilder = useDocumentBuilder;
   }
-    
+
   /**
    * Add a MIME BodyPart.
    *
@@ -294,7 +293,7 @@
         st = new SOAPHTTPConnection();
 
       // set the timeout
-      if (to != 0 && st instanceof SOAPHTTPConnection) 
+      if (to != 0 && st instanceof SOAPHTTPConnection)
         ((SOAPHTTPConnection)st).setTimeout(to);
 
       // Post the call envelope.
@@ -349,7 +348,7 @@
     {
       throw new SOAPException(Constants.FAULT_CODE_CLIENT,
                               "Parsing error, response was:\n" +e.getMessage(),
-                                         e);
+                                          e);
     }
     catch (IOException e)
     {
@@ -364,8 +363,8 @@
    * parser plus a transformation.
    */
   private Document parsePayload(String payload) throws IOException, SAXException {
-       InputSource input = new InputSource(new StringReader(payload));
-       if (!useDocumentBuilder) {
+          InputSource input = new InputSource(new StringReader(payload));
+          if (!useDocumentBuilder) {
       try {
         // If classes required for transformation are all present, use that method
         Class domResultClass = Class.forName("javax.xml.transform.dom.DOMResult");
@@ -375,14 +374,14 @@
         Class sourceClass = Class.forName("javax.xml.transform.Source");
         Class resultClass = Class.forName("javax.xml.transform.Result");
 
-           Object output = domResultClass.newInstance();
+            Object output = domResultClass.newInstance();
         Object source = saxSourceClass.newInstance();
 
         // Create factory and use to create transformer
         Method method = transformerFactoryClass.getDeclaredMethod("newInstance", new 
Class[]{});
-           Object xformFactory = method.invoke(null, new Object[]{});
+            Object xformFactory = method.invoke(null, new Object[]{});
         method = transformerFactoryClass.getDeclaredMethod("newTransformer", new 
Class[]{});
-           Object idTransform = method.invoke(xformFactory, new Object[]{});
+            Object idTransform = method.invoke(xformFactory, new Object[]{});
 
         // Set input source for SAX source
         method = saxSourceClass.getDeclaredMethod("setInputSource", new 
Class[]{InputSource.class});
@@ -397,7 +396,7 @@
 
         // If all has worked, we return here; for exceptions,
         // we fall through to the DOM parser.
-           return (Document) method.invoke(output, new Object[]{});
+            return (Document) method.invoke(output, new Object[]{});
       } catch (ClassNotFoundException e) {
       } catch (NoSuchMethodException e) {
       } catch (InvocationTargetException e) {
@@ -406,9 +405,16 @@
       }
     }
 
+    DocumentBuilder  xdb = XMLParserUtils.getXMLDocBuilderFromPool();
+    Document doc = null;
     // if the DOM parser hasn't been created yet, do it now
-    if (xdb == null)
-      xdb = XMLParserUtils.getXMLDocBuilder();
-    return xdb.parse(input);
+    try {
+        doc = xdb.parse(input);
+    }
+    finally {
+        XMLParserUtils.returnDocumentBuilderToPool(xdb);
+    }
+    return doc;
+
   }
 }

--
To unsubscribe, e-mail:   <mailto:soap-dev-unsubscribe@;xml.apache.org>
For additional commands, e-mail: <mailto:soap-dev-help@;xml.apache.org>

Reply via email to