1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Copyright 1999-2002,2004 The Apache Software Foundation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 
22 // Sep 14, 2000:
23 //  Fixed serializer to report IO exception directly, instead at
24 //  the end of document processing.
25 //  Reported by Patrick Higgins <phiggins@transzap.com>
26 
27 
28 package com.sun.org.apache.xml.internal.serialize;
29 
30 
31 import java.io.Writer;
32 import java.io.StringWriter;
33 import java.io.IOException;
34 
35 
36 /**
37  * The printer is responsible for sending text to the output stream
38  * or writer. This class performs direct writing for efficiency.
39  * {@link IndentPrinter} supports indentation and line wrapping by
40  * extending this class.
41  *
42  * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
43  */
44 public class Printer
45 {
46 
47 
48     /**
49      * The output format associated with this serializer. This will never
50      * be a null reference. If no format was passed to the constructor,
51      * the default one for this document type will be used. The format
52      * object is never changed by the serializer.
53      */
54     protected final OutputFormat _format;
55 
56 
57     /**
58      * The writer to which the document is written.
59      */
60     protected Writer             _writer;
61 
62 
63     /**
64      * The DTD writer. When we switch to DTD mode, all output is
65      * accumulated in this DTD writer. When we switch out of it,
66      * the output is obtained as a string. Must not be reset to
67      * null until we're done with the document.
68      */
69     protected StringWriter       _dtdWriter;
70 
71 
72     /**
73      * Holds a reference to the document writer while we are
74      * in DTD mode.
75      */
76     protected Writer          _docWriter;
77 
78 
79     /**
80      * Holds the exception thrown by the serializer.  Exceptions do not cause
81      * the serializer to quit, but are held and one is thrown at the end.
82      */
83     protected IOException     _exception;
84 
85 
86     /**
87      * The size of the output buffer.
88      */
89     private static final int BufferSize = 4096;
90 
91 
92     /**
93      * Output buffer.
94      */
95     private final char[]  _buffer = new char[ BufferSize ];
96 
97 
98     /**
99      * Position within the output buffer.
100      */
101     private int           _pos = 0;
102 
103 
Printer( Writer writer, OutputFormat format)104     public Printer( Writer writer, OutputFormat format)
105     {
106         _writer = writer;
107         _format = format;
108         _exception = null;
109         _dtdWriter = null;
110         _docWriter = null;
111         _pos = 0;
112     }
113 
114 
getException()115     public IOException getException()
116     {
117         return _exception;
118     }
119 
120 
121     /**
122      * Called by any of the DTD handlers to enter DTD mode.
123      * Once entered, all output will be accumulated in a string
124      * that can be printed as part of the document's DTD.
125      * This method may be called any number of time but will only
126      * have affect the first time it's called. To exist DTD state
127      * and get the accumulated DTD, call {@link #leaveDTD}.
128      */
enterDTD()129     public void enterDTD()
130         throws IOException
131     {
132         // Can only enter DTD state once. Once we're out of DTD
133         // state, can no longer re-enter it.
134         if ( _dtdWriter == null ) {
135             flushLine( false );
136 
137                         _dtdWriter = new StringWriter();
138             _docWriter = _writer;
139             _writer = _dtdWriter;
140         }
141     }
142 
143 
144     /**
145      * Called by the root element to leave DTD mode and if any
146      * DTD parts were printer, will return a string with their
147      * textual content.
148      */
leaveDTD()149     public String leaveDTD()
150         throws IOException
151     {
152         // Only works if we're going out of DTD mode.
153         if ( _writer == _dtdWriter ) {
154             flushLine( false );
155 
156                         _writer = _docWriter;
157             return _dtdWriter.toString();
158         } else
159             return null;
160     }
161 
162 
printText( String text )163     public void printText( String text )
164         throws IOException
165     {
166         try {
167             int length = text.length();
168             for ( int i = 0 ; i < length ; ++i ) {
169                 if ( _pos == BufferSize ) {
170                     _writer.write( _buffer );
171                     _pos = 0;
172                 }
173                 _buffer[ _pos ] = text.charAt( i );
174                 ++_pos;
175             }
176         } catch ( IOException except ) {
177             // We don't throw an exception, but hold it
178             // until the end of the document.
179             if ( _exception == null )
180                 _exception = except;
181             throw except;
182         }
183     }
184 
185 
printText( StringBuffer text )186     public void printText( StringBuffer text )
187         throws IOException
188     {
189         try {
190             int length = text.length();
191             for ( int i = 0 ; i < length ; ++i ) {
192                 if ( _pos == BufferSize ) {
193                     _writer.write( _buffer );
194                     _pos = 0;
195                 }
196                 _buffer[ _pos ] = text.charAt( i );
197                 ++_pos;
198             }
199         } catch ( IOException except ) {
200             // We don't throw an exception, but hold it
201             // until the end of the document.
202             if ( _exception == null )
203                 _exception = except;
204             throw except;
205         }
206     }
207 
208 
printText( char[] chars, int start, int length )209     public void printText( char[] chars, int start, int length )
210         throws IOException
211     {
212         try {
213             while ( length-- > 0 ) {
214                 if ( _pos == BufferSize ) {
215                     _writer.write( _buffer );
216                     _pos = 0;
217                 }
218                 _buffer[ _pos ] = chars[ start ];
219                 ++start;
220                 ++_pos;
221             }
222         } catch ( IOException except ) {
223             // We don't throw an exception, but hold it
224             // until the end of the document.
225             if ( _exception == null )
226                 _exception = except;
227             throw except;
228         }
229     }
230 
231 
printText( char ch )232     public void printText( char ch )
233         throws IOException
234     {
235         try {
236             if ( _pos == BufferSize ) {
237                 _writer.write( _buffer );
238                 _pos = 0;
239             }
240             _buffer[ _pos ] = ch;
241             ++_pos;
242         } catch ( IOException except ) {
243             // We don't throw an exception, but hold it
244             // until the end of the document.
245             if ( _exception == null )
246                 _exception = except;
247             throw except;
248         }
249     }
250 
251 
printSpace()252     public void printSpace()
253         throws IOException
254     {
255         try {
256             if ( _pos == BufferSize ) {
257                 _writer.write( _buffer );
258                 _pos = 0;
259             }
260             _buffer[ _pos ] = ' ';
261             ++_pos;
262         } catch ( IOException except ) {
263             // We don't throw an exception, but hold it
264             // until the end of the document.
265             if ( _exception == null )
266                 _exception = except;
267             throw except;
268         }
269     }
270 
271 
breakLine()272     public void breakLine()
273         throws IOException
274     {
275         try {
276             if ( _pos == BufferSize ) {
277                 _writer.write( _buffer );
278                 _pos = 0;
279             }
280             _buffer[ _pos ] = '\n';
281             ++_pos;
282         } catch ( IOException except ) {
283             // We don't throw an exception, but hold it
284             // until the end of the document.
285             if ( _exception == null )
286                 _exception = except;
287             throw except;
288         }
289     }
290 
291 
breakLine( boolean preserveSpace )292     public void breakLine( boolean preserveSpace )
293         throws IOException
294     {
295         breakLine();
296     }
297 
298 
flushLine( boolean preserveSpace )299     public void flushLine( boolean preserveSpace )
300         throws IOException
301     {
302         // Write anything left in the buffer into the writer.
303         try {
304             _writer.write( _buffer, 0, _pos );
305         } catch ( IOException except ) {
306             // We don't throw an exception, but hold it
307             // until the end of the document.
308             if ( _exception == null )
309                 _exception = except;
310         }
311         _pos = 0;
312     }
313 
314 
315     /**
316      * Flush the output stream. Must be called when done printing
317      * the document, otherwise some text might be buffered.
318      */
flush()319     public void flush()
320         throws IOException
321     {
322         try {
323             _writer.write( _buffer, 0, _pos );
324             _writer.flush();
325         } catch ( IOException except ) {
326             // We don't throw an exception, but hold it
327             // until the end of the document.
328             if ( _exception == null )
329                 _exception = except;
330             throw except;
331         }
332         _pos = 0;
333     }
334 
335 
indent()336     public void indent()
337     {
338         // NOOP
339     }
340 
341 
unindent()342     public void unindent()
343     {
344         // NOOP
345     }
346 
347 
getNextIndent()348     public int getNextIndent()
349     {
350         return 0;
351     }
352 
353 
setNextIndent( int indent )354     public void setNextIndent( int indent )
355     {
356     }
357 
358 
setThisIndent( int indent )359     public void setThisIndent( int indent )
360     {
361     }
362 
363 
364 }
365