KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > system > configuration > IndentPrinter


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. 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 JavaDoc;
26 import java.io.StringWriter JavaDoc;
27 import java.io.IOException JavaDoc;
28
29
30 /**
31  * Extends {@link Printer} and adds support for indentation and line
32  * wrapping.
33  *
34  * @version $Revision: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
35  * @author <a HREF="mailto:arkin@intalio.com">Assaf Arkin</a>
36  */

37 public class IndentPrinter
38     extends Printer
39 {
40
41
42     /**
43      * Holds the currently accumulating text line. This buffer will constantly
44      * be reused by deleting its contents instead of reallocating it.
45      */

46     private StringBuffer JavaDoc _line;
47
48
49     /**
50      * Holds the currently accumulating text that follows {@link #_line}.
51      * When the end of the part is identified by a call to {@link #printSpace}
52      * or {@link #breakLine}, this part is added to the accumulated line.
53      */

54     private StringBuffer JavaDoc _text;
55
56
57     /**
58      * Counts how many white spaces come between the accumulated line and the
59      * current accumulated text. Multiple spaces at the end of the a line
60      * will not be printed.
61      */

62     private int _spaces;
63
64
65     /**
66      * Holds the indentation for the current line that is now accumulating in
67      * memory and will be sent for printing shortly.
68      */

69     private int _thisIndent;
70     
71     
72     /**
73      * Holds the indentation for the next line to be printed. After this line is
74      * printed, {@link #_nextIndent} is assigned to {@link #_thisIndent}.
75      */

76     private int _nextIndent;
77
78
79     IndentPrinter( Writer JavaDoc writer, OutputFormat format)
80     {
81         super( writer, format );
82         // Initialize everything for a first/second run.
83
_line = new StringBuffer JavaDoc( 80 );
84         _text = new StringBuffer JavaDoc( 20 );
85         _spaces = 0;
86         _thisIndent = _nextIndent = 0;
87     }
88
89
90     /**
91      * Called by any of the DTD handlers to enter DTD mode.
92      * Once entered, all output will be accumulated in a string
93      * that can be printed as part of the document's DTD.
94      * This method may be called any number of time but will only
95      * have affect the first time it's called. To exist DTD state
96      * and get the accumulated DTD, call {@link #leaveDTD}.
97      */

98     public void enterDTD()
99     {
100         // Can only enter DTD state once. Once we're out of DTD
101
// state, can no longer re-enter it.
102
if ( dtdWriter == null ) {
103             _line.append( _text );
104             _text = new StringBuffer JavaDoc( 20 );
105             flushLine( false );
106             dtdWriter = new StringWriter JavaDoc();
107             docWriter = writer;
108             writer = dtdWriter;
109         }
110     }
111     
112     
113     /**
114      * Called by the root element to leave DTD mode and if any
115      * DTD parts were printer, will return a string with their
116      * textual content.
117      */

118     public String JavaDoc leaveDTD()
119     {
120         // Only works if we're going out of DTD mode.
121
if ( writer == dtdWriter ) {
122             _line.append( _text );
123             _text = new StringBuffer JavaDoc( 20 );
124             flushLine( false );
125             writer = docWriter;
126             return dtdWriter.toString();
127         } else
128             return null;
129     }
130     
131     
132     /**
133      * Called to print additional text. Each time this method is called
134      * it accumulates more text. When a space is printed ({@link
135      * #printSpace}) all the accumulated text becomes one part and is
136      * added to the accumulate line. When a line is long enough, it can
137      * be broken at its text boundary.
138      *
139      * @param text The text to print
140      */

141     public void printText( String JavaDoc text )
142     {
143         _text.append( text );
144     }
145     
146     
147     public void printText( StringBuffer JavaDoc text )
148     {
149         _text.append( text );
150     }
151
152
153     public void printText( char ch )
154     {
155         _text.append( ch );
156     }
157
158
159     public void printText( char[] chars, int start, int length )
160     {
161         _text.append( chars, start, length );
162     }
163     
164
165     /**
166      * Called to print a single space between text parts that may be
167      * broken into separate lines. Must not be called to print a space
168      * when preserving spaces. The text accumulated so far with {@link
169      * #printText} will be added to the accumulated line, and a space
170      * separator will be counted. If the line accumulated so far is
171      * long enough, it will be printed.
172      */

173     public void printSpace()
174     {
175         // The line consists of the text accumulated in _line,
176
// followed by one or more spaces as counted by _spaces,
177
// followed by more space accumulated in _text:
178
// - Text is printed and accumulated into _text.
179
// - A space is printed, so _text is added to _line and
180
// a space is counted.
181
// - More text is printed and accumulated into _text.
182
// - A space is printed, the previous spaces are added
183
// to _line, the _text is added to _line, and a new
184
// space is counted.
185

186         // If text was accumulated with printText(), then the space
187
// means we have to move that text into the line and
188
// start accumulating new text with printText().
189
if ( _text.length() > 0 ) {
190             // If the text breaks a line bounary, wrap to the next line.
191
// The printed line size consists of the indentation we're going
192
// to use next, the accumulated line so far, some spaces and the
193
// accumulated text so far.
194
if ( format.getLineWidth() > 0 &&
195                  _thisIndent + _line.length() + _spaces + _text.length() > format.getLineWidth() ) {
196                 flushLine( false );
197                 try {
198                     // Print line and new line, then zero the line contents.
199
writer.write( format.getLineSeparator() );
200                 } catch ( IOException JavaDoc except ) {
201                     // We don't throw an exception, but hold it
202
// until the end of the document.
203
if ( exception == null )
204                         exception = except;
205                 }
206             }
207             
208             // Add as many spaces as we accumulaed before.
209
// At the end of this loop, _spaces is zero.
210
while ( _spaces > 0 ) {
211                 _line.append( ' ' );
212                 --_spaces;
213             }
214             _line.append( _text );
215             _text = new StringBuffer JavaDoc( 20 );
216         }
217         // Starting a new word: accumulate the text between the line
218
// and this new word; not a new word: just add another space.
219
++_spaces;
220     }
221
222
223     /**
224      * Called to print a line consisting of the text accumulated so
225      * far. This is equivalent to calling {@link #printSpace} but
226      * forcing the line to print and starting a new line ({@link
227      * #printSpace} will only start a new line if the current line
228      * is long enough).
229      */

230     public void breakLine()
231     {
232         breakLine( false );
233     }
234
235
236     public void breakLine( boolean preserveSpace )
237     {
238         // Equivalent to calling printSpace and forcing a flushLine.
239
if ( _text.length() > 0 ) {
240             while ( _spaces > 0 ) {
241                 _line.append( ' ' );
242                 --_spaces;
243             }
244             _line.append( _text );
245             _text = new StringBuffer JavaDoc( 20 );
246         }
247         flushLine( preserveSpace );
248         try {
249             // Print line and new line, then zero the line contents.
250
writer.write( format.getLineSeparator() );
251         } catch ( IOException JavaDoc except ) {
252             // We don't throw an exception, but hold it
253
// until the end of the document.
254
if ( exception == null )
255                 exception = except;
256         }
257     }
258     
259
260     /**
261      * Flushes the line accumulated so far to the writer and get ready
262      * to accumulate the next line. This method is called by {@link
263      * #printText} and {@link #printSpace} when the accumulated line plus
264      * accumulated text are two long to fit on a given line. At the end of
265      * this method {@link #_line} is empty and {@link #_spaces} is zero.
266      */

267     public void flushLine( boolean preserveSpace )
268     {
269         int indent;
270         
271         if ( _line.length() > 0 ) {
272             try {
273                 
274                 if ( format.getIndenting() && ! preserveSpace ) {
275                     // Make sure the indentation does not blow us away.
276
indent = _thisIndent;
277                     if ( ( 2 * indent ) > format.getLineWidth() && format.getLineWidth() > 0 )
278                         indent = format.getLineWidth() / 2;
279                     // Print the indentation as spaces and set the current
280
// indentation to the next expected indentation.
281
while ( indent > 0 ) {
282                         writer.write( ' ' );
283                         --indent;
284                     }
285                 }
286                 _thisIndent = _nextIndent;
287                 
288                 // There is no need to print the spaces at the end of the line,
289
// they are simply stripped and replaced with a single line
290
// separator.
291
_spaces = 0;
292                 writer.write( _line.toString() );
293                 
294                 _line = new StringBuffer JavaDoc( 40 );
295             } catch ( IOException JavaDoc except ) {
296                 // We don't throw an exception, but hold it
297
// until the end of the document.
298
if ( exception == null )
299                     exception = except;
300             }
301         }
302     }
303     
304     
305     /**
306      * Flush the output stream. Must be called when done printing
307      * the document, otherwise some text might be buffered.
308      */

309     public void flush()
310     {
311         if ( _line.length() > 0 || _text.length() > 0 )
312             breakLine();
313         try {
314             writer.flush();
315         } catch ( IOException JavaDoc except ) {
316             // We don't throw an exception, but hold it
317
// until the end of the document.
318
if ( exception == null )
319                 exception = except;
320         }
321     }
322
323
324     /**
325      * Increment the indentation for the next line.
326      */

327     public void indent()
328     {
329         _nextIndent += format.getIndent();
330     }
331
332
333     /**
334      * Decrement the indentation for the next line.
335      */

336     public void unindent()
337     {
338         _nextIndent -= format.getIndent();
339         if ( _nextIndent < 0 )
340             _nextIndent = 0;
341         // If there is no current line and we're de-identing then
342
// this indentation level is actually the next level.
343
if ( ( _line.length() + _spaces + _text.length() ) == 0 )
344             _thisIndent = _nextIndent;
345     }
346
347
348     public int getNextIndent()
349     {
350         return _nextIndent;
351     }
352
353
354     public void setNextIndent( int indent )
355     {
356         _nextIndent = indent;
357     }
358
359
360     public void setThisIndent( int indent )
361     {
362         _thisIndent = indent;
363     }
364
365
366 }
367
Popular Tags