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