You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2001/03/23 00:33:49 UTC

[Bug 1083] New - OutputStream or Writer inside StreamResult always get flushed by Transformer.transform()

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1083

*** shadow/1083	Thu Mar 22 15:33:48 2001
--- shadow/1083.tmp.27569	Thu Mar 22 15:33:48 2001
***************
*** 0 ****
--- 1,146 ----
+ +============================================================================+
+ | OutputStream or Writer inside StreamResult always get flushed by Transform |
+ +----------------------------------------------------------------------------+
+ |        Bug #: 1083                        Product: XalanJ2                 |
+ |       Status: NEW                         Version: 2.0.1                   |
+ |   Resolution:                            Platform: PC                      |
+ |     Severity: Normal                   OS/Version: Windows NT/2K           |
+ |     Priority:                           Component: org.apache.xalan.serial |
+ +----------------------------------------------------------------------------+
+ |  Assigned To: xalan-dev@xml.apache.org                                     |
+ |  Reported By: czhao@commonvision.com                                       |
+ |      CC list: Cc:                                                          |
+ +----------------------------------------------------------------------------+
+ |          URL:                                                              |
+ +============================================================================+
+ |                              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 {
+ 							System.out.println
+ ("\nflush called on OutputStream:");
+ 							Thread.dumpStack();
+ 							super.flush();
+ 						}
+ 				};
+ 		transformer.transform(new StreamSource("birds.xml"), new 
+ StreamResult(myOutputStream) );
+ 		myOutputStream.flush();
+ 
+ 		BufferedWriter myWriter =
+ 				new BufferedWriter( new FileWriter
+ ("birds.out") ) {
+ 						public void flush() throws 
+ IOException {
+ 							System.out.println
+ ("flush called on Writer:");
+ 							Thread.dumpStack();
+ 							super.flush();
+ 						}
+ 				};
+ 		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.