zongaro 2003/12/04 08:44:50
Modified: java/src/org/apache/xalan/transformer
TransformerIdentityImpl.java
java/src/org/apache/xalan/xsltc/trax TrAXFilter.java
java/src/org/apache/xml/dtm/ref DTMManagerDefault.java
Added: java/src/org/apache/xml/utils XMLReaderManager.java
Log:
Moved code for caching XMLReader objects from XSLTC's TransformerFactoryImpl
to
a new org.apache.xml.utils.XMLReaderManager class.
It is now the responsibility of the DTMManagerDefault class to request one of
these cached XMLReader objects, so the benefit of reusing an XMLReader is now
conferred upon both XSLTC and Xalan-J Interpretive, as well as upon references
to the document() function.
Revision Changes Path
1.28 +27 -47
xml-xalan/java/src/org/apache/xalan/transformer/TransformerIdentityImpl.java
Index: TransformerIdentityImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerIdentityImpl.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- TransformerIdentityImpl.java 22 Oct 2003 18:45:57 -0000 1.27
+++ TransformerIdentityImpl.java 4 Dec 2003 16:44:49 -0000 1.28
@@ -77,19 +77,21 @@
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
-import org.apache.xml.serializer.Serializer;
-import org.apache.xml.serializer.SerializerFactory;
-import org.apache.xml.serializer.Method;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.templates.OutputProperties;
+import org.apache.xml.serializer.Serializer;
+import org.apache.xml.serializer.SerializerFactory;
+import org.apache.xml.serializer.Method;
import org.apache.xml.utils.DOMBuilder;
import org.apache.xml.utils.TreeWalker;
+import org.apache.xml.utils.XMLReaderManager;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
+
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
@@ -99,7 +101,6 @@
import org.xml.sax.XMLReader;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
/**
* This class implements an identity transformer for
@@ -407,56 +408,31 @@
if (null != xmlSource.getSystemId())
m_systemID = xmlSource.getSystemId();
+ XMLReader reader = null;
+ boolean managedReader = false;
+
try
{
- XMLReader reader = null;
-
- if (source instanceof SAXSource)
+ if (source instanceof SAXSource) {
reader = ((SAXSource) source).getXMLReader();
+ }
- if (null == reader)
- {
-
- // Use JAXP1.1 ( if possible )
- try
- {
- javax.xml.parsers.SAXParserFactory factory =
- javax.xml.parsers.SAXParserFactory.newInstance();
-
- factory.setNamespaceAware(true);
-
- javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
-
- reader = jaxpParser.getXMLReader();
+ if (null == reader) {
+ try {
+ reader = XMLReaderManager.getInstance().getXMLReader();
+ managedReader = true;
+ } catch (SAXException se) {
+ throw new TransformerException(se);
}
- catch (javax.xml.parsers.ParserConfigurationException ex)
- {
- throw new org.xml.sax.SAXException(ex);
+ } else {
+ try {
+
reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
+ true);
+ } catch (org.xml.sax.SAXException se) {
+ // We don't care.
}
- catch (javax.xml.parsers.FactoryConfigurationError ex1)
- {
- throw new org.xml.sax.SAXException(ex1.toString());
- }
- catch (NoSuchMethodError ex2){}
- catch (AbstractMethodError ame){}
}
-
- if (null == reader)
- {
- reader = XMLReaderFactory.createXMLReader();
- }
-
- try
- {
- reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
- true);
- }
- catch (org.xml.sax.SAXException se)
- {
-
- // We don't care.
- }
-
+
// Get the input content handler, which will handle the
// parse events and create the source tree.
ContentHandler inputHandler = this;
@@ -513,6 +489,10 @@
catch (IOException ioe)
{
throw new TransformerException(ioe);
+ } finally {
+ if (managedReader) {
+ XMLReaderManager.getInstance().releaseXMLReader(reader);
+ }
}
}
finally
1.7 +20 -9
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TrAXFilter.java
Index: TrAXFilter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TrAXFilter.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TrAXFilter.java 24 Jun 2003 13:26:59 -0000 1.6
+++ TrAXFilter.java 4 Dec 2003 16:44:49 -0000 1.7
@@ -76,6 +76,8 @@
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXResult;
+import org.apache.xml.utils.XMLReaderManager;
+
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -128,17 +130,26 @@
public void parse (InputSource input) throws SAXException, IOException
{
- if (getParent() == null) {
- try {
- createParent();
- }
- catch (SAXException e) {
+ XMLReader managedReader = null;
+
+ try {
+ if (getParent() == null) {
+ try {
+ managedReader = XMLReaderManager.getInstance()
+ .getXMLReader();
+ setParent(managedReader);
+ } catch (SAXException e) {
throw new SAXException(e.toString());
}
- }
+ }
- // call parse on the parent
- getParent().parse(input);
+ // call parse on the parent
+ getParent().parse(input);
+ } finally {
+ if (managedReader != null) {
+
XMLReaderManager.getInstance().releaseXMLReader(managedReader);
+ }
+ }
}
public void parse (String systemId) throws SAXException, IOException
1.49 +38 -43
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java
Index: DTMManagerDefault.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- DTMManagerDefault.java 22 Oct 2003 19:01:56 -0000 1.48
+++ DTMManagerDefault.java 4 Dec 2003 16:44:49 -0000 1.49
@@ -76,12 +76,14 @@
import org.apache.xml.res.XMLMessages;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.SystemIDResolver;
+import org.apache.xml.utils.XMLReaderManager;
import org.apache.xml.utils.XMLStringFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
@@ -143,6 +145,12 @@
int m_dtm_offsets[] = new int[256];
/**
+ * The cache for XMLReader objects to be used if the user did not
+ * supply an XMLReader for a SAXSource or supplied a StreamSource.
+ */
+ protected XMLReaderManager m_readerManager = null;
+
+ /**
* Add a DTM to the DTM table. This convenience call adds it as the
* "base DTM ID", with offset 0. The other version of addDTM should
* be used if you want to add "extended" DTM IDs with nonzero offsets.
@@ -477,18 +485,20 @@
try
{
reader.parse(xmlSource);
+
+ releaseXMLReader(reader);
}
catch (RuntimeException re)
{
-
dtm.clearCoRoutine();
+ releaseXMLReader(reader);
throw re;
}
catch (Exception e)
{
-
dtm.clearCoRoutine();
+ releaseXMLReader(reader);
throw new org.apache.xml.utils.WrappedRuntimeException(e);
}
@@ -617,8 +627,9 @@
* obtained from this URI.
* It may return null if any SAX2-conformant XML parser can be used,
* or if getInputSource() will also return null. The parser must
- * be free for use (i.e.
- * not currently in use for another parse().
+ * be free for use (i.e., not currently in use for another parse().
+ * After use of the parser is completed, the releaseXMLReader(XMLReader)
+ * must be called.
*
* @param inputSource The value returned from the URIResolver.
* @return a SAX2 XMLReader to use to resolve the inputSource argument.
@@ -633,51 +644,35 @@
XMLReader reader = (inputSource instanceof SAXSource)
? ((SAXSource) inputSource).getXMLReader() : null;
- if (null == reader)
- {
- try
- {
- javax.xml.parsers.SAXParserFactory factory =
- javax.xml.parsers.SAXParserFactory.newInstance();
-
- factory.setNamespaceAware(true);
-
- javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
-
- reader = jaxpParser.getXMLReader();
- }
- catch (javax.xml.parsers.ParserConfigurationException ex)
- {
- throw new org.xml.sax.SAXException(ex);
- }
- catch (javax.xml.parsers.FactoryConfigurationError ex1)
- {
- throw new org.xml.sax.SAXException(ex1.toString());
+ // If user did not supply a reader, ask for one from the reader manager
+ if (null == reader) {
+ if (m_readerManager == null) {
+ m_readerManager = XMLReaderManager.getInstance();
}
- catch (NoSuchMethodError ex2){}
- catch (AbstractMethodError ame){}
- if (null == reader)
- reader = XMLReaderFactory.createXMLReader();
- }
-
- try
- {
- reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
- true);
- }
- catch (org.xml.sax.SAXException se)
- {
-
- // What can we do?
- // TODO: User diagnostics.
+ reader = m_readerManager.getXMLReader();
}
return reader;
- }
- catch (org.xml.sax.SAXException se)
- {
+
+ } catch (SAXException se) {
throw new DTMException(se.getMessage(), se);
+ }
+ }
+
+ /**
+ * Indicates that the XMLReader object is no longer in use for the
transform.
+ *
+ * Note that the getXMLReader method may return an XMLReader that was
+ * specified on the SAXSource object by the application code. Such a
+ * reader should still be passed to releaseXMLReader, but the reader
manager
+ * will only re-use XMLReaders that it created.
+ *
+ * @param reader The XMLReader to be released.
+ */
+ synchronized public void releaseXMLReader(XMLReader reader) {
+ if (m_readerManager != null) {
+ m_readerManager.releaseXMLReader(reader);
}
}
1.1
xml-xalan/java/src/org/apache/xml/utils/XMLReaderManager.java
Index: XMLReaderManager.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* 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
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* 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,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
import java.util.Hashtable;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.SAXException;
/**
* Creates XMLReader objects and caches them for re-use.
* This class follows the singleton pattern.
*/
public class XMLReaderManager {
private static final String NAMESPACES_FEATURE =
"http://xml.org/sax/features/namespaces";
private static final String NAMESPACE_PREFIXES_FEATURE =
"http://xml.org/sax/features/namespace-prefixes";
private static final XMLReaderManager m_singletonManager =
new XMLReaderManager();
/**
* Parser factory to be used to construct XMLReader objects
*/
private static SAXParserFactory m_parserFactory;
/**
* Cache of XMLReader objects
*/
private ThreadLocal m_readers;
/**
* Keeps track of whether an XMLReader object is in use.
*/
private Hashtable m_inUse;
/**
* Hidden constructor
*/
private XMLReaderManager() {
}
/**
* Retrieves the singleton reader manager
*/
public static XMLReaderManager getInstance() {
return m_singletonManager;
}
/**
* Retrieves a cached XMLReader for this thread, or creates a new
* XMLReader, if the existing reader is in use. When the caller no
* longer needs the reader, it must release it with a call to
* [EMAIL PROTECTED] releaseXMLReader}.
*/
public synchronized XMLReader getXMLReader() throws SAXException {
XMLReader reader;
boolean readerInUse;
if (m_readers == null) {
// When the m_readers.get() method is called for the first time
// on a thread, a new XMLReader will automatically be created.
m_readers = new ThreadLocal();
}
if (m_inUse == null) {
m_inUse = new Hashtable();
}
// If the cached reader for this thread is in use, construct a new
// one; otherwise, return the cached reader.
reader = (XMLReader) m_readers.get();
boolean threadHasReader = (reader != null);
if (!threadHasReader || m_inUse.get(reader) == Boolean.TRUE) {
try {
try {
// According to JAXP 1.2 specification, if a SAXSource
// is created using a SAX InputSource the Transformer or
// TransformerFactory creates a reader via the
// XMLReaderFactory if setXMLReader is not used
reader = XMLReaderFactory.createXMLReader();
} catch (Exception e) {
try {
// If unable to create an instance, let's try to use
// the XMLReader from JAXP
if (m_parserFactory == null) {
m_parserFactory = SAXParserFactory.newInstance();
m_parserFactory.setNamespaceAware(true);
}
reader =
m_parserFactory.newSAXParser().getXMLReader();
} catch (ParserConfigurationException pce) {
throw pce; // pass along pce
}
}
try {
reader.setFeature(NAMESPACES_FEATURE, true);
reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
} catch (SAXException se) {
// Try to carry on if we've got a parser that
// doesn't know about namespace prefixes.
}
} catch (ParserConfigurationException ex) {
throw new SAXException(ex);
} catch (FactoryConfigurationError ex1) {
throw new SAXException(ex1.toString());
} catch (NoSuchMethodError ex2) {
} catch (AbstractMethodError ame) {
}
// Cache the XMLReader if this is the first time we've created
// a reader for this thread.
if (!threadHasReader) {
m_readers.set(reader);
m_inUse.put(reader, Boolean.TRUE);
}
} else {
m_inUse.put(reader, Boolean.TRUE);
}
return reader;
}
/**
* Mark the cached XMLReader as available. If the reader was not
* actually in the cache, do nothing.
*
* @param reader The XMLReader that's being released.
*/
public synchronized void releaseXMLReader(XMLReader reader) {
// If the reader that's being released is the cached reader
// for this thread, mark it as no longer being in use.
if (m_readers.get() == reader) {
m_inUse.put(reader, Boolean.FALSE);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]