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