Details
-
Bug
-
Status: Closed
-
Resolution: Won't Fix
-
2.0.1
-
None
-
Security Level: No security risk; visible to anyone (Ordinary problems in Xalan projects. Anybody can view the issue.)
-
None
-
Operating System: Windows NT/2K
Platform: PC
-
1083
Description
This test class is based on the sample SimpleTransform class. I enxtended
BufferedOutputStream and BufferedWriter so we know when they get flushed.
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;
public class TestXalanFlush {
public static void main(String[] args)
throws TransformerException, TransformerConfigurationException,
FileNotFoundException,
IOException
{
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new
StreamSource("birds.xsl"));
OutputStream myOutputStream =
new BufferedOutputStream ( new FileOutputStream
("birds.out") ) {
public void flush() throws
IOException
};
transformer.transform(new StreamSource("birds.xml"), new
StreamResult(myOutputStream) );
myOutputStream.flush();
BufferedWriter myWriter =
new BufferedWriter( new FileWriter
("birds.out") ) {
public void flush() throws
IOException
};
transformer.transform(new StreamSource("birds.xml"), new
StreamResult(myWriter) );
myWriter.flush();
}
}
The output is:
flush called on OutputStream:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:993)
at TestXalanFlush$1.flush(TestXalanFlush.java:16)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:245)
at org.apache.xalan.serialize.SerializerToXML.flushWriter
(SerializerToXML.java:147
1)
at org.apache.xalan.serialize.SerializerToXML.endDocument
(SerializerToXML.java:662
)
at org.apache.xalan.transformer.ResultTreeHandler.endDocument
(ResultTreeHandler.ja
va:193)
at org.apache.xalan.transformer.TransformerImpl.transformNode
(TransformerImpl.java
:1224)
at org.apache.xalan.transformer.TransformerImpl.run
(TransformerImpl.java:2942)
at java.lang.Thread.run(Thread.java:484)
flush called on OutputStream:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:993)
at TestXalanFlush$1.flush(TestXalanFlush.java:16)
at TestXalanFlush.main(TestXalanFlush.java:22)
flush called on Writer:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:993)
at TestXalanFlush$2.flush(TestXalanFlush.java:28)
at org.apache.xalan.serialize.SerializerToXML.flushWriter
(SerializerToXML.java:147
1)
at org.apache.xalan.serialize.SerializerToXML.endDocument
(SerializerToXML.java:662
)
at org.apache.xalan.transformer.ResultTreeHandler.endDocument
(ResultTreeHandler.ja
va:193)
at org.apache.xalan.transformer.TransformerImpl.transformNode
(TransformerImpl.java
:1224)
at org.apache.xalan.transformer.TransformerImpl.run
(TransformerImpl.java:2942)
at java.lang.Thread.run(Thread.java:484)
flush called on Writer:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:993)
at TestXalanFlush$2.flush(TestXalanFlush.java:28)
at TestXalanFlush.main(TestXalanFlush.java:34)
We see that the OutputStream and Writer are automatically flushed by
org.apache.xalan.serialize.SerializerToXML.flushWriter(). This should not
happen.
In terms of the Writer, the SerializerToXML class has a flag m_shouldFlush
which tells if flushWriter() should flush the writer, and its init(Writer,
Properties) method does set the flag to false. However, when
Transformer.tranform(StreamSource, StreamResult) method is called the
SerializeToXML.init(Writer, Properties) method is never called, instead
setWriter(Writer) is called, which does nothing with the flag. And the
m_shouldFlush flag defaults to true. Thus the flush. I think the fix should
be to add
m_shouldFlush = false;
to setWriter(Writer) method. (Or does it make more sense to let m_shouldFlush
flag default to false?)
In terms of the OutputStream, org.apache.xalan.serialize.Encodings.getWriter
(OutputStream output, String encoding) method is called to construct a writer
to wrap around the OutputStream, and certainly SerializerToXML should flush the
writer. However the constructed wrapper Writer is of class
java.io.OutputStreamWriter, whose flush() method calls flush() on the
underlying OutputStream. It is arguable if this is desirable. If this is
considered acceptable, then it should be documented that any OutputStream
passed in SerializerToXML or StreamResult will be flushed automatically in the
end. If this is considered unacceptable, then we should implement our own
version of OutputStreamWriter which in its flush() method does not call flush()
on the underlying OutputStream.