|
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 |
|
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 |
|
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 */ |
|
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 */ |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
292 public void breakLine( boolean preserveSpace ) |
|
293 throws IOException |
|
294 { |
|
295 breakLine(); |
|
296 } |
|
297 |
|
298 |
|
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 */ |
|
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 |
|
336 public void indent() |
|
337 { |
|
338 // NOOP |
|
339 } |
|
340 |
|
341 |
|
342 public void unindent() |
|
343 { |
|
344 // NOOP |
|
345 } |
|
346 |
|
347 |
|
348 public int getNextIndent() |
|
349 { |
|
350 return 0; |
|
351 } |
|
352 |
|
353 |
|
354 public void setNextIndent( int indent ) |
|
355 { |
|
356 } |
|
357 |
|
358 |
|
359 public void setThisIndent( int indent ) |
|
360 { |
|
361 } |
|
362 |
|
363 |
|
364 } |