sboag 01/02/22 17:18:34
Modified: java/src/org/apache/xalan/transformer TransformerImpl.java
Log:
Fix for bug originally reported by Daryl Beattie <[EMAIL PROTECTED]>
on 02/14/2001 04:16 PM. A hang was occuring inside the use
of a Result Tree Fragment. When the result tree fragement was
being created, the Redirect extension was being called, which
called createResultContentHandler which set the ContentHandler
in the Transformer, but not in the ResultTreeHandler. Then, Redirect
called Transformer#executeChildTemplates(
ElemTemplateElement elem, Node sourceNode, QName mode,
ContentHandler handler)
which saves the reference to the original content handler in
the transformer, and then sets the new one by calling setContentHandler,
which sets the ContentHandler in the ResultTreeHandler as well
as the Transformer. When it tried to restore the old ContentHandler,
it restored the value in the ResultTreeHandler to a Serializer, instead
of the correct ContentHandler. When transformToRTF then called
endDocument on it's resultTreeFragment, the event was sent
to the Serializer instead of the SourceTreeHandler, and thus the
isComplete flag was not set, and thus the hang. (whew!)
The fix is in executeChildTemplates save the value of the
resultTreeHandler's contentHandler as well as Transformer's
content handler, and restore them both. A more architectual fix
could be made, but not without high risk, so I think this is the best
and safest way to fix it.
Revision Changes Path
1.85 +27 -13
xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
Index: TransformerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -r1.84 -r1.85
--- TransformerImpl.java 2001/02/13 20:28:59 1.84
+++ TransformerImpl.java 2001/02/23 01:18:33 1.85
@@ -1335,7 +1335,6 @@
public void setSerializer(Serializer s)
{
m_serializer = s;
- ;
}
/**
@@ -1696,7 +1695,6 @@
return m_outputContentHandler;
}
-
/**
* <meta name="usage" content="advanced"/>
* Given a stylesheet element, create a result tree fragment from it's
@@ -1727,7 +1725,8 @@
((SourceTreeHandler)rtfHandler).setUseMultiThreading(false);
((SourceTreeHandler)rtfHandler).setShouldTransformAtEnd(false);
// Create a ResultTreeFrag object.
- resultFragment =
(DocumentFragment)((SourceTreeHandler)rtfHandler).getRoot();;
+ resultFragment =
(DocumentFragment)((SourceTreeHandler)rtfHandler).getRoot();
+ //
((org.apache.xalan.stree.DocumentFragmentImpl)resultFragment).setComplete(true);
}
else
{
@@ -1762,20 +1761,25 @@
ResultTreeHandler savedRTreeHandler = this.m_resultTreeHandler;
// And make a new handler for the RTF.
- this.m_resultTreeHandler = new ResultTreeHandler(this, rtfHandler);
-
+ m_resultTreeHandler = new ResultTreeHandler(this, rtfHandler);
+ ResultTreeHandler rth = m_resultTreeHandler;
try
{
- m_resultTreeHandler.startDocument();
+ rth.startDocument();
- // Do the transformation of the child elements.
- executeChildTemplates(templateParent, sourceNode, mode, true);
-
- // Make sure everything is flushed!
- this.m_resultTreeHandler.flushPending();
-
- m_resultTreeHandler.endDocument();
+ try
+ {
+ // Do the transformation of the child elements.
+ executeChildTemplates(templateParent, sourceNode, mode, true);
+
+ // Make sure everything is flushed!
+ rth.flushPending();
+ }
+ finally
+ {
+ rth.endDocument();
+ }
}
catch(org.xml.sax.SAXException se)
{
@@ -2059,6 +2063,12 @@
throws TransformerException
{
+ ResultTreeHandler rth = this.getResultTreeHandler();
+
+ // These may well not be the same! In this case when calling
+ // the Redirect extension, it has already set the ContentHandler
+ // in the Transformer.
+ ContentHandler savedRTHHandler = rth.getContentHandler();
ContentHandler savedHandler = this.getContentHandler();
try
@@ -2074,6 +2084,10 @@
finally
{
this.setContentHandler(savedHandler);
+
+ // This fixes a bug where the ResultTreeHandler's ContentHandler
+ // was being reset to the wrong ContentHandler.
+ rth.setContentHandler(savedRTHHandler);
}
}