snichol     2002/11/21 08:36:58

  Modified:    java/src/org/apache/soap Utils.java
               java/src/org/apache/soap/messaging Message.java
               java/src/org/apache/soap/rpc Call.java
               java/src/org/apache/soap/server DeploymentDescriptor.java
                        ServiceManager.java ServiceManagerClient.java
                        XMLConfigManager.java
               java/src/org/apache/soap/server/http
                        MessageRouterServlet.java RPCRouterServlet.java
               java/src/org/apache/soap/transport FilterTransport.java
               java/src/org/apache/soap/util/xml XMLParserUtils.java
  Log:
  1. Disable lazy expansion of DOM nodes for Xerces.
  2. Push XML parsing into XMLParserUtils, so that clients (a) need not be
     aware of pooling, (b) don't carry around their own DocumentBuilder
     instances (which affects which pooling algorithms can be used), and (c)
     can benefit from any parsing improvements, such as the use of transforms
     or parser-specific options.  The servlets still get and return instances
     from the pools, but that may be removed with time, as well.
  3. Use more restrictive import statements for the util.xml package as part
     of the general move toward explicit specification of which classes are
     imported.
  4. Add comments in the servlets regarding how "optimistic" it is to think
     that the parser specified in the servlet config will be the one actually
     used, since this can be set from any piece of code.  It is currently set
     up as "last servlet to load wins" if only servlet loading sets this.
  
  Revision  Changes    Path
  1.12      +11 -7     xml-soap/java/src/org/apache/soap/Utils.java
  
  Index: Utils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/Utils.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Utils.java        6 Sep 2002 17:50:26 -0000       1.11
  +++ Utils.java        21 Nov 2002 16:36:56 -0000      1.12
  @@ -57,11 +57,16 @@
   
   package org.apache.soap;
   
  -import java.io.*;
  -import java.util.*;
  -import javax.xml.parsers.*;
  -import org.w3c.dom.*;
  -import org.apache.soap.util.xml.*;
  +import java.io.PrintWriter;
  +import java.io.StringWriter;
  +import java.io.Writer;
  +import java.util.Vector;
  +import org.w3c.dom.Document;
  +import org.w3c.dom.Element;
  +import org.w3c.dom.Node;
  +import org.w3c.dom.Text;
  +import org.apache.soap.util.xml.DOM2Writer;
  +import org.apache.soap.util.xml.XMLParserUtils;
   
   /**
    * <em>SOAP</em> utilities.
  @@ -117,8 +122,7 @@
     public static Vector buildFaultDetailsFromThrowable (Throwable t)
     {
       Vector details = new Vector();
  -    DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
  -    Document doc = xdb.newDocument();
  +    Document doc = XMLParserUtils.newDocument();
       Element elem = doc.createElement("stackTrace");
       StringWriter sw = new StringWriter();
       PrintWriter pw = new PrintWriter(sw);
  
  
  
  1.13      +4 -5      xml-soap/java/src/org/apache/soap/messaging/Message.java
  
  Index: Message.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/messaging/Message.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Message.java      19 Nov 2002 02:47:38 -0000      1.12
  +++ Message.java      21 Nov 2002 16:36:56 -0000      1.13
  @@ -64,9 +64,9 @@
   import org.w3c.dom.*;
   import org.xml.sax.*;
   import org.apache.soap.util.*;
  -import org.apache.soap.util.xml.*;
  -import org.apache.soap.rpc.SOAPContext;
  +import org.apache.soap.util.xml.XMLParserUtils;
   import org.apache.soap.rpc.Call;
  +import org.apache.soap.rpc.SOAPContext;
   import org.apache.soap.*;
   import org.apache.soap.transport.*;
   import org.apache.soap.transport.http.*;
  @@ -85,11 +85,11 @@
    *
    * @author Sanjiva Weerawarana ([EMAIL PROTECTED])
    * @author Pavel Ausianik &lt;[EMAIL PROTECTED]&gt;
  + * @author Scott Nichol ([EMAIL PROTECTED])
    */
   public class Message {
     SOAPTransport st;
     SOAPContext reqCtx = new SOAPContext (), resCtx = null;
  -  DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
   
     public Message () {
     }
  @@ -164,8 +164,7 @@
           return null;
         String payloadStr = Call.getEnvelopeString (st);
   
  -      Document doc = 
  -          xdb.parse(new InputSource(new StringReader(payloadStr)));
  +      Document doc = XMLParserUtils.parse(payloadStr);
   
         if (doc == null) {
           throw new SOAPException (Constants.FAULT_CODE_CLIENT,
  
  
  
  1.26      +3 -64     xml-soap/java/src/org/apache/soap/rpc/Call.java
  
  Index: Call.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/rpc/Call.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- Call.java 20 Nov 2002 22:27:10 -0000      1.25
  +++ Call.java 21 Nov 2002 16:36:57 -0000      1.26
  @@ -175,7 +175,7 @@
     }
   
     /**
  -   * Set timeout in our MessageContext.
  +   * Set timeout in our SOAPTransport.
      * 
      * @param value the maximum amount of time, in milliseconds
      */
  @@ -184,7 +184,7 @@
     }
       
     /**
  -   * Get timeout from our MessageContext.
  +   * Get timeout from our SOAPTransport.
      * 
      * @return value the maximum amount of time, in milliseconds
      */
  @@ -334,7 +334,7 @@
         String payloadStr = getEnvelopeString(st);
   
         // Parse the incoming response stream.
  -      Document respDoc = parsePayload(payloadStr);
  +      Document respDoc = XMLParserUtils.parse(payloadStr, useDocumentBuilder);
         Element payload = null;
   
         if (respDoc != null)
  @@ -382,66 +382,5 @@
         throw new SOAPException(Constants.FAULT_CODE_PROTOCOL,
                                 e.getMessage(), e);
       }
  -  }
  -
  -  /**
  -   * Parses the payload into a DOM.  Depending on what JAXP facilities are
  -   * available at run-time, this will either use the DOM parser or the SAX
  -   * parser plus a transformation.
  -   */
  -  private Document parsePayload(String payload) throws IOException, SAXException {
  -     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");
  -        Class transformerFactoryClass = 
Class.forName("javax.xml.transform.TransformerFactory");
  -        Class transformerClass = Class.forName("javax.xml.transform.Transformer");
  -        Class saxSourceClass = Class.forName("javax.xml.transform.sax.SAXSource");
  -        Class sourceClass = Class.forName("javax.xml.transform.Source");
  -        Class resultClass = Class.forName("javax.xml.transform.Result");
  -
  -         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[]{});
  -        method = transformerFactoryClass.getDeclaredMethod("newTransformer", new 
Class[]{});
  -         Object idTransform = method.invoke(xformFactory, new Object[]{});
  -
  -        // Set input source for SAX source
  -        method = saxSourceClass.getDeclaredMethod("setInputSource", new 
Class[]{InputSource.class});
  -        method.invoke(source, new Object[]{input});
  -
  -        // Transform from SAX source to DOM result
  -        method = transformerClass.getDeclaredMethod("transform", new 
Class[]{sourceClass, resultClass});
  -        method.invoke(idTransform, new Object[]{source, output});
  -
  -        // Grab document node from DOM result
  -        method = domResultClass.getDeclaredMethod("getNode", new Class[]{});
  -
  -        // If all has worked, we return here; for exceptions,
  -        // we fall through to the DOM parser.
  -         return (Document) method.invoke(output, new Object[]{});
  -      } catch (ClassNotFoundException e) {
  -      } catch (NoSuchMethodException e) {
  -      } catch (InvocationTargetException e) {
  -      } catch (InstantiationException e) {
  -      } catch (IllegalAccessException e) {
  -      }
  -    }
  -
  -    // if the DOM parser hasn't been created yet, do it now
  -    DocumentBuilder  xdb = XMLParserUtils.getXMLDocBuilderFromPool();
  -    Document doc = null;
  -    // if the DOM parser hasn't been created yet, do it now
  -    try {
  -        doc = xdb.parse(input);
  -    }
  -    finally {
  -        XMLParserUtils.returnDocumentBuilderToPool(xdb);
  -    }
  -    return doc;
     }
   }
  
  
  
  1.36      +6 -4      
xml-soap/java/src/org/apache/soap/server/DeploymentDescriptor.java
  
  Index: DeploymentDescriptor.java
  ===================================================================
  RCS file: 
/home/cvs/xml-soap/java/src/org/apache/soap/server/DeploymentDescriptor.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- DeploymentDescriptor.java 30 Aug 2002 03:22:54 -0000      1.35
  +++ DeploymentDescriptor.java 21 Nov 2002 16:36:57 -0000      1.36
  @@ -59,14 +59,17 @@
   
   import java.io.*;
   import java.util.*;
  -import javax.xml.parsers.*;
   import org.w3c.dom.*;
   import org.xml.sax.*;
   import org.apache.soap.Constants;
   import org.apache.soap.encoding.*;
   import org.apache.soap.rpc.*;
   import org.apache.soap.server.http.*;
  -import org.apache.soap.util.xml.*;
  +import org.apache.soap.util.xml.Deserializer;
  +import org.apache.soap.util.xml.DOMUtils;
  +import org.apache.soap.util.xml.QName;
  +import org.apache.soap.util.xml.Serializer;
  +import org.apache.soap.util.xml.XMLParserUtils;
   
   /**
    * This class represents the deployment information about a SOAP service.
  @@ -445,8 +448,7 @@
       }
   
       try {
  -      DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
  -      Document        doc = xdb.parse(new InputSource(rd));
  +      Document doc = XMLParserUtils.parse(rd);
   
         if (doc != null) {
           Element root = doc.getDocumentElement();
  
  
  
  1.19      +3 -4      xml-soap/java/src/org/apache/soap/server/ServiceManager.java
  
  Index: ServiceManager.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/ServiceManager.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- ServiceManager.java       10 Sep 2002 07:02:02 -0000      1.18
  +++ ServiceManager.java       21 Nov 2002 16:36:57 -0000      1.19
  @@ -60,11 +60,11 @@
   import java.util.*;
   import java.io.*;
   import javax.servlet.*;
  -import javax.xml.parsers.*;
   import org.apache.soap.*;
   import org.apache.soap.server.http.*;
   import org.apache.soap.util.* ;
  -import org.apache.soap.util.xml.*;
  +import org.apache.soap.util.xml.QName;
  +import org.apache.soap.util.xml.XMLParserUtils;
   import org.apache.soap.rpc.SOAPContext ;
   import org.w3c.dom.*;
   import org.xml.sax.*;
  @@ -80,7 +80,6 @@
     protected DeploymentDescriptor smsdd;  // Svc Mgmnt Svc's Dep Descriptor
     protected ConfigManager        configMgr = null;
     protected ServletContext       context = null;
  -  protected DocumentBuilder      xdb = XMLParserUtils.getXMLDocBuilder();
     protected boolean              soapInterfaceEnabled = true;
   
     public ServiceManager (ServletContext context, String configFilename) {
  @@ -151,7 +150,7 @@
           ServerHTTPUtils.getFileFromNameAndContext(configFilename, context);
   
         reader = new FileReader(configFile);
  -      doc = xdb.parse(new InputSource(reader));
  +      doc = XMLParserUtils.parse(reader);
         elem = doc.getDocumentElement();
         if ( !"soapServer".equals(elem.getTagName()) )
           throw new Exception( "Root element must be 'soapServer'" );
  
  
  
  1.11      +13 -8     
xml-soap/java/src/org/apache/soap/server/ServiceManagerClient.java
  
  Index: ServiceManagerClient.java
  ===================================================================
  RCS file: 
/home/cvs/xml-soap/java/src/org/apache/soap/server/ServiceManagerClient.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ServiceManagerClient.java 5 Sep 2002 16:50:52 -0000       1.10
  +++ ServiceManagerClient.java 21 Nov 2002 16:36:57 -0000      1.11
  @@ -57,17 +57,23 @@
   
   package org.apache.soap.server;
   
  -import java.net.URL;
   import java.io.*;
  +import java.net.URL;
   import java.util.*;
  -import javax.xml.parsers.*;
  -import org.w3c.dom.*;
   import org.xml.sax.*;
  -import org.apache.soap.util.xml.*;
  -import org.apache.soap.*;
  +import org.w3c.dom.*;
  +import org.apache.soap.Constants;
  +import org.apache.soap.Fault;
  +import org.apache.soap.SOAPException;
   import org.apache.soap.encoding.SOAPMappingRegistry;
  +import org.apache.soap.rpc.Call;
  +import org.apache.soap.rpc.Parameter;
  +import org.apache.soap.rpc.Response;
   import org.apache.soap.transport.http.SOAPHTTPConnection;
  -import org.apache.soap.rpc.*;
  +import org.apache.soap.util.xml.Deserializer;
  +import org.apache.soap.util.xml.QName;
  +import org.apache.soap.util.xml.Serializer;
  +import org.apache.soap.util.xml.XMLParserUtils;
   
   /**
    * This is a client to talk to an Apache SOAP ServiceManager to manage services
  @@ -224,8 +230,7 @@
           badUsage ();
         }
         FileReader fr = new FileReader (args[base+2]);
  -      DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
  -      Document doc = xdb.parse(new InputSource(fr));
  +      Document doc = XMLParserUtils.parse(fr);
         smc.deploy (DeploymentDescriptor.fromXML (doc.getDocumentElement ()));
       } else if (op.equals ("undeploy")) {
         if (args.length != base+3) {
  
  
  
  1.4       +2 -4      xml-soap/java/src/org/apache/soap/server/XMLConfigManager.java
  
  Index: XMLConfigManager.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/XMLConfigManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLConfigManager.java     17 May 2001 18:25:54 -0000      1.3
  +++ XMLConfigManager.java     21 Nov 2002 16:36:57 -0000      1.4
  @@ -66,7 +66,6 @@
   import javax.servlet.http.* ;
   
   // XML Classes
  -import javax.xml.parsers.* ;
   import org.w3c.dom.* ;
   import org.xml.sax.* ;
   
  @@ -76,7 +75,7 @@
   import org.apache.soap.server.* ;
   import org.apache.soap.server.http.* ;
   import org.apache.soap.util.* ;
  -import org.apache.soap.util.xml.* ;
  +import org.apache.soap.util.xml.XMLParserUtils;
   
   /**
    * An <code>XMLConfigManager</code> ...
  @@ -97,7 +96,6 @@
    */
   public class XMLConfigManager extends BaseConfigManager
             implements ConfigManager {
  -  protected DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
   
     /** The name of the deployment file. */
     protected String filename = "DeployedServices.xml";
  @@ -129,7 +127,7 @@
         Element root = null;
   
         try {
  -        doc  = xdb.parse(new InputSource(rd));
  +        doc  = XMLParserUtils.parse(rd);
           root = doc.getDocumentElement();
         } catch (Exception e) {
           e.printStackTrace();
  
  
  
  1.38      +21 -11    
xml-soap/java/src/org/apache/soap/server/http/MessageRouterServlet.java
  
  Index: MessageRouterServlet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-soap/java/src/org/apache/soap/server/http/MessageRouterServlet.java,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- MessageRouterServlet.java 6 Sep 2002 06:14:10 -0000       1.37
  +++ MessageRouterServlet.java 21 Nov 2002 16:36:58 -0000      1.38
  @@ -69,7 +69,7 @@
   import org.apache.soap.server.*;
   import org.apache.soap.encoding.*;
   import org.apache.soap.util.*;
  -import org.apache.soap.util.xml.*;
  +import org.apache.soap.util.xml.XMLParserUtils;
   import org.apache.soap.transport.*;
   import org.apache.soap.encoding.soapenc.SoapEncUtils;
   
  @@ -198,6 +198,10 @@
       tempStr = servletConfig.getInitParameter(Constants.XML_PARSER);
   
       // Is there a user-specified JAXP implementation?
  +    // Note: this is extremely lame, since XMLParserUtils could be
  +    // "refreshed" with another implementation at any time.  The
  +    // value in the configuration must be viewed as just a hopeful
  +    // suggestion.
       if (tempStr != null) {
         XMLParserUtils.refreshDocumentBuilderFactory(tempStr,
                                                      true,  // namespaceAware
  @@ -251,6 +255,7 @@
   
       SOAPContext reqCtx = new SOAPContext() ;
       SOAPContext resCtx = new SOAPContext() ;
  +    Envelope msgEnv = null;
   
       reqCtx.setClassLoader( ServerHTTPUtils.
                                getServletClassLoaderFromContext(context) );
  @@ -265,16 +270,21 @@
     
           // Generate Envelope after the incoming message is translated by
           // EnvelopeEditor
  -        // Note: XMLParser that is specified by init-param isused in
  -        // this process.
  -        DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
  -        Envelope msgEnv =
  -          ServerHTTPUtils.readEnvelopeFromRequest(xdb,
  -                                                  req.getContentType(),
  -                                                  req.getContentLength(),
  -                                                  req.getInputStream(),
  -                                                  editor, res, reqCtx,
  -                                                  ServerHTTPUtils.getHeaders(req));
  +        // Note: XMLParser that is specified by init-param is used in
  +        // this process, unless some other piece of code specifies
  +        // a different parser!
  +        DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilderFromPool();
  +        try {
  +          msgEnv =
  +            ServerHTTPUtils.readEnvelopeFromRequest(xdb,
  +                                                    req.getContentType(),
  +                                                    req.getContentLength(),
  +                                                    req.getInputStream(),
  +                                                    editor, res, reqCtx,
  +                                                    
ServerHTTPUtils.getHeaders(req));
  +        } finally {
  +          XMLParserUtils.returnDocumentBuilderToPool(xdb);
  +        }
           if (msgEnv == null)
               return;
     
  
  
  
  1.45      +7 -2      
xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java
  
  Index: RPCRouterServlet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- RPCRouterServlet.java     20 Nov 2002 21:54:25 -0000      1.44
  +++ RPCRouterServlet.java     21 Nov 2002 16:36:58 -0000      1.45
  @@ -70,7 +70,7 @@
   import org.apache.soap.encoding.*;
   import org.apache.soap.transport.*;
   import org.apache.soap.util.*;
  -import org.apache.soap.util.xml.*;
  +import org.apache.soap.util.xml.XMLParserUtils;
   import org.apache.soap.transport.EnvelopeEditor;
   import org.apache.soap.transport.EnvelopeEditorFactory;
   import org.apache.soap.encoding.soapenc.SoapEncUtils;
  @@ -232,6 +232,10 @@
         tempStr = servletContext.getInitParameter(Constants.XML_PARSER);
   
       // Is there a user-specified JAXP implementation?
  +    // Note: this is extremely lame, since XMLParserUtils could be
  +    // "refreshed" with another implementation at any time.  The
  +    // value in the configuration must be viewed as just a hopeful
  +    // suggestion.
       if (tempStr != null) {
         XMLParserUtils.refreshDocumentBuilderFactory(tempStr,
                                                      true,  // namespaceAware
  @@ -306,7 +310,8 @@
             // Generate Envelope after the incoming message is translated by
             // EnvelopeEditor
             // Note: XMLParser that is specified by init-param isused in
  -          // this process.
  +          // this process, unless some other piece of code specifies
  +          // a different parser!
             DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilderFromPool();
   
             try {
  
  
  
  1.7       +2 -4      xml-soap/java/src/org/apache/soap/transport/FilterTransport.java
  
  Index: FilterTransport.java
  ===================================================================
  RCS file: 
/home/cvs/xml-soap/java/src/org/apache/soap/transport/FilterTransport.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- FilterTransport.java      17 May 2001 18:26:07 -0000      1.6
  +++ FilterTransport.java      21 Nov 2002 16:36:58 -0000      1.7
  @@ -63,11 +63,10 @@
   import java.io.*;
   import java.net.*;
   import java.util.*;
  -import javax.xml.parsers.*;
   import org.w3c.dom.*;
   import org.xml.sax.*;
   import org.apache.soap.util.net.*;
  -import org.apache.soap.util.xml.*;
  +import org.apache.soap.util.xml.XMLParserUtils;
   import org.apache.soap.*;
   import org.apache.soap.rpc.SOAPContext;
   import org.apache.soap.encoding.*;
  @@ -122,8 +121,7 @@
           sin = new StringReader(sout.getBuffer().toString());
         }
   
  -      DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
  -      Element docElem = xdb.parse(new InputSource(sin)).getDocumentElement();
  +      Element docElem = XMLParserUtils.parse(sin).getDocumentElement();
   
         Envelope env2 = Envelope.unmarshall(docElem);
         transport.send(sendTo, action, headers, env2, smr, ctx);
  
  
  
  1.9       +140 -2    xml-soap/java/src/org/apache/soap/util/xml/XMLParserUtils.java
  
  Index: XMLParserUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/xml/XMLParserUtils.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XMLParserUtils.java       20 Nov 2002 21:54:25 -0000      1.8
  +++ XMLParserUtils.java       21 Nov 2002 16:36:58 -0000      1.9
  @@ -57,9 +57,16 @@
   
   package org.apache.soap.util.xml;
   
  -import java.util.List;
  +import java.io.IOException;
  +import java.io.Reader;
  +import java.io.StringReader;
  +import java.lang.reflect.InvocationTargetException;
  +import java.lang.reflect.Method;
   import java.util.ArrayList;
  -import javax.xml.parsers.*;
  +import java.util.List;
  +import javax.xml.parsers.DocumentBuilder;
  +import javax.xml.parsers.DocumentBuilderFactory;
  +import javax.xml.parsers.ParserConfigurationException;
   import org.xml.sax.*;
   import org.xml.sax.helpers.*;
   import org.w3c.dom.*;
  @@ -71,6 +78,8 @@
    *
    * @author Ruth Bergman ([EMAIL PROTECTED])
    * @author Matthew J. Duftler ([EMAIL PROTECTED])
  + * @author Scott Nichol ([EMAIL PROTECTED])
  + * @author Pavel Ausianik ([EMAIL PROTECTED])
    */
   public class XMLParserUtils {
     private static DocumentBuilderFactory dbf = null;
  @@ -151,6 +160,13 @@
       dbf.setValidating(validating);
       dbf.setExpandEntityReferences(expandEntityReferences);
   
  +    try {
  +      dbf.setAttribute("http://apache.org/xml/features/dom/defer-node-expansion";,
  +                       Boolean.FALSE);
  +    } catch (IllegalArgumentException e) {
  +      // parsers that do not support this option with throw this exception
  +    }
  +
       /*
         At this point the DocumentBuilderFactory instance can be saved
         and reused to create any number of DocumentBuilder instances
  @@ -208,5 +224,127 @@
     synchronized public static void returnDocumentBuilderToPool(DocumentBuilder 
builder) {
         if (builder != null)
             allocatedBuildersList.add(builder);
  +  }
  +
  +  /**
  +   * Gets a new XML DOM.
  +   *
  +   * @return The new XML DOM.
  +   */
  +  public static Document newDocument() {
  +    DocumentBuilder xdb = getXMLDocBuilderFromPool();
  +    Document doc = null;
  +    try {
  +      doc = xdb.newDocument();
  +    } finally {
  +      XMLParserUtils.returnDocumentBuilderToPool(xdb);
  +    }
  +    return doc;
  +  }
  +
  +  /**
  +   * Parses XML text from a Reader into an XML DOM.
  +   *
  +   * @param xmlReader XML reader.
  +   * @return The XML in DOM form.
  +   * @exception IOException For errors reading the XML.
  +   * @exception SAXException For errors parsing the XML.
  +   */
  +  public static Document parse(Reader xmlReader)
  +                               throws IOException, SAXException {
  +    return parse(new InputSource(xmlReader), true);
  +  }
  +
  +  /**
  +   * Parses XML text into an XML DOM.
  +   *
  +   * @param xmlText XML text.
  +   * @return The XML in DOM form.
  +   * @exception IOException For errors reading the XML.
  +   * @exception SAXException For errors parsing the XML.
  +   */
  +  public static Document parse(String xmlText)
  +                               throws IOException, SAXException {
  +    return parse(new InputSource(xmlText), true);
  +  }
  +
  +  /**
  +   * Parses XML text into an XML DOM.
  +   *
  +   * @param xmlString XML text.
  +   * @param useDocumentBuilder True to use a document builder, false to use
  +   *                           a transform.  If the transform classes cannot
  +   *                           be loaded, a document builder will be used.
  +   * @return The XML in DOM form.
  +   * @exception IOException For errors reading the XML.
  +   * @exception SAXException For errors parsing the XML.
  +   */
  +  public static Document parse(String xmlText, boolean useDocumentBuilder)
  +                               throws IOException, SAXException {
  +    return parse(new InputSource(new StringReader(xmlText)), useDocumentBuilder);
  +  }
  +
  +  /**
  +   * Parses an XML source into an XML DOM.
  +   *
  +   * @param xmlSource The source of the XML.
  +   * @param useDocumentBuilder True to use a document builder, false to use
  +   *                           a transform.  If the transform classes cannot
  +   *                           be loaded, a document builder will be used.
  +   * @return The XML in DOM form.
  +   * @exception IOException For errors reading the XML.
  +   * @exception SAXException For errors parsing the XML.
  +   */
  +  public static Document parse(InputSource xmlSource, boolean useDocumentBuilder)
  +                               throws IOException, SAXException {
  +     if (!useDocumentBuilder) {
  +      try {
  +        // If classes required for transformation are all present, use that method
  +        Class domResultClass = Class.forName("javax.xml.transform.dom.DOMResult");
  +        Class transformerFactoryClass = 
Class.forName("javax.xml.transform.TransformerFactory");
  +        Class transformerClass = Class.forName("javax.xml.transform.Transformer");
  +        Class saxSourceClass = Class.forName("javax.xml.transform.sax.SAXSource");
  +        Class sourceClass = Class.forName("javax.xml.transform.Source");
  +        Class resultClass = Class.forName("javax.xml.transform.Result");
  +
  +         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[]{});
  +        method = transformerFactoryClass.getDeclaredMethod("newTransformer", new 
Class[]{});
  +         Object idTransform = method.invoke(xformFactory, new Object[]{});
  +
  +        // Set input source for SAX source
  +        method = saxSourceClass.getDeclaredMethod("setInputSource", new 
Class[]{InputSource.class});
  +        method.invoke(source, new Object[]{xmlSource});
  +
  +        // Transform from SAX source to DOM result
  +        method = transformerClass.getDeclaredMethod("transform", new 
Class[]{sourceClass, resultClass});
  +        method.invoke(idTransform, new Object[]{source, output});
  +
  +        // Grab document node from DOM result
  +        method = domResultClass.getDeclaredMethod("getNode", new Class[]{});
  +
  +        // If all has worked, we return here; for exceptions,
  +        // we fall through to the DOM parser.
  +         return (Document) method.invoke(output, new Object[]{});
  +      } catch (ClassNotFoundException e) {
  +      } catch (NoSuchMethodException e) {
  +      } catch (InvocationTargetException e) {
  +      } catch (InstantiationException e) {
  +      } catch (IllegalAccessException e) {
  +      }
  +    }
  +
  +    DocumentBuilder xdb = getXMLDocBuilderFromPool();
  +    Document doc = null;
  +    try {
  +      doc = xdb.parse(xmlSource);
  +    } finally {
  +      returnDocumentBuilderToPool(xdb);
  +    }
  +    return doc;
     }
   }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to