View Javadoc

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