View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
42   */
43  package org.exolab.javasource;
44  
45  import java.io.Writer;
46  
47  /**
48   * The writer used by the javasource classes.
49   *
50   * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a>
51   * @version $Revision$ $Date: 2005-03-30 03:29:24 -0700 (Wed, 30 Mar 2005) $
52   */
53  public final class JSourceWriter extends Writer {
54      //--------------------------------------------------------------------------
55  
56      /** The default character to use for indentation. */
57      public static final char DEFAULT_CHAR = ' ';
58      
59      /** The default indentation size. */
60      public static final short DEFAULT_SIZE = 4;
61  
62      //--------------------------------------------------------------------------
63  
64      /** The line separator to use for the writeln methods. */
65      private String _lineSeparator = System.getProperty("line.separator");
66      
67      /** Flag for indicating whether we need to add the whitespace to beginning
68       *  of next write call. */
69      private boolean _addIndentation = true;
70      
71      /** A flag indicating whether this JSourceWriter should perform autoflush at
72       *  the end of a new line. */
73      private boolean _autoflush = false;
74      
75      /** The tab (indentation) size. */
76      private short _tabSize = DEFAULT_SIZE;
77      
78      /** The tab representation. */
79      private char[] _tab;
80      
81      /** The character to use for indentation. */
82      private char _tabChar = DEFAULT_CHAR;
83      
84      /** The current tab level. */
85      private short _tabLevel = 0;
86      
87      /** The writer to send all output to. */
88      private Writer _out = null;
89  
90      //--------------------------------------------------------------------------
91  
92      /**
93       * Creates a new JSourceWriter.
94       *
95       * @param out The Writer to write the actual output to.
96       */
97      public JSourceWriter(final Writer out) {
98          this(out, DEFAULT_SIZE, DEFAULT_CHAR, false);
99      }
100 
101     /**
102      * Creates a new JSourceWriter.
103      *
104      * @param out The Writer to write the actual output to.
105      * @param autoflush A boolean indicating whether or not to perform automatic
106      *        flush at the end of a line.
107      */
108     public JSourceWriter(final Writer out, final boolean autoflush) {
109         this(out, DEFAULT_SIZE, DEFAULT_CHAR, autoflush);
110     }
111 
112     /**
113      * Creates a new JSourceWriter.
114      *
115      * @param out The Writer to write the actual output to.
116      * @param tabSize The size of each indentation.
117      * @param autoflush A boolean indicating whether or not to perform automatic
118      *        flush at the end of a line.
119      */
120     public JSourceWriter(final Writer out, final short tabSize, final boolean autoflush) {
121         this(out, tabSize, DEFAULT_CHAR, autoflush);
122     }
123 
124     /**
125      * Creates a new JSourceWriter.
126      *
127      * @param out The Writer to write the actual output to.
128      * @param tabSize The size of each indentation.
129      * @param tabChar The character to use for indentation.
130      * @param autoflush A boolean indicating whether or not to perform an automatic
131      *        flush at the end of each line.
132      */
133     public JSourceWriter(final Writer out, final short tabSize, final char tabChar,
134             final boolean autoflush) {
135         _out = out;
136         _autoflush = autoflush;
137         _tabChar = tabChar;
138         _tabSize = tabSize;
139         createTab();
140     }
141 
142     //--------------------------------------------------------------------------
143 
144     /**
145      * Returns the line separator being used by this JSourceWriter.
146      *
147      * @return The line separator being used by this JSourceWriter.
148      */
149     public String getLineSeparator() {
150         return _lineSeparator;
151     }
152 
153     /**
154      * Increases the indentation level by 1.
155      */
156     public void indent() {
157         ++_tabLevel;
158     }
159 
160     /**
161      * Checks to see if the cursor is positioned on a new line.
162      *
163      * @return True if the cursor is at the start of a new line, otherwise false.
164      */
165     public boolean isNewline() {
166         //-- if we need to add indentation, we are on a new line
167         return _addIndentation;
168     }
169 
170     /**
171      * Sets the line separator to use at the end of each line. Typically a line
172      * separator will be one of the following:
173      * <ul>
174      *   <li>"\r\n" for MS Windows</li>
175      *   <li>"\n" for UNIX</li>
176      *   <li>"\r" for Macintosh</li>
177      * </ul>
178      *
179      * @param lineSeparator The String to use as a line separator.
180      */
181     public void setLineSeparator(final String lineSeparator) {
182         _lineSeparator = lineSeparator;
183     }
184 
185     /**
186      * Decreases the indentation level by 1.
187      */
188     public void unindent() {
189         if (_tabLevel > 0) { --_tabLevel; }
190     }
191 
192     /**
193      * Returns the current indentation level.
194      *
195      * @return The current indentation level.
196      */
197     protected short getIndentLevel() {
198         return _tabLevel;
199     }
200 
201     /**
202      * Returns the current indent size (getIndentLevel()*tabSize).
203      *
204      * @return The current indent size.
205      */
206     protected short getIndentSize() {
207         return (short) (_tabLevel * _tabSize);
208     }
209 
210     /**
211      * Returns the current character used for indentation.
212      * 
213      * @return The current character used for indentation.
214      */
215     protected char getIndentChar() {
216         return _tabChar;
217     }
218 
219     /**
220      * Always applies the current indentation.
221      */
222     protected void writeIndent() {
223         try {
224             for (int i = 0; i < _tabLevel; i++) { _out.write(_tab); }
225         } catch (java.io.IOException ioe) {
226             // ignore
227         }
228     }
229 
230     /**
231      * If indentation has not already been applied, then applies it.
232      */
233     private void ensureIndent() {
234         if (_addIndentation) {
235             writeIndent();
236             _addIndentation = false;
237         }
238     }
239 
240     /**
241      * Writes the line separator character to the writer.
242      */
243     private void linefeed() {
244         try {
245             _out.write(_lineSeparator);
246         } catch (java.io.IOException ioe) {
247             // ignore
248         }
249     }
250 
251     /**
252      * Creates the tab from the tabSize and the tabChar.
253      */
254     private void createTab() {
255         _tab = new char[_tabSize];
256         for (int i = 0; i < _tabSize; i++) {
257             _tab[i] = _tabChar;
258         }
259     }
260 
261     //--------------------------------------------------------------------------
262 
263     public void write(final float f) {
264         write(String.valueOf(f));
265     }
266 
267     public void write(final long l) {
268         write(String.valueOf(l));
269     }
270 
271     public void write(final double d) {
272         write(String.valueOf(d));
273     }
274 
275     public void write(final Object obj) {
276         write(obj.toString());
277     }
278 
279     public void write(final boolean b) {
280         write(String.valueOf(b));
281     }
282 
283     //--------------------------------------------------------------------------
284 
285     public void writeln() {
286         synchronized (lock) {
287             linefeed();
288             _addIndentation = true;
289         }
290     }
291 
292     public void writeln(final float f) {
293         synchronized (lock) {
294             ensureIndent();
295             try {
296                 _out.write(String.valueOf(f));
297             } catch (java.io.IOException ioe) {
298                 // ignore
299             }
300             linefeed();
301             _addIndentation = true;
302         }
303     }
304 
305     public void writeln(final long l) {
306         synchronized (lock) {
307             ensureIndent();
308             try {
309                 _out.write(String.valueOf(l));
310             } catch (java.io.IOException ioe) {
311                 // ignore
312             }
313             linefeed();
314             _addIndentation = true;
315         }
316     }
317 
318     public void writeln(final int i) {
319         synchronized (lock) {
320             ensureIndent();
321             try {
322                 _out.write(String.valueOf(i));
323             } catch (java.io.IOException ioe) {
324                 // ignore
325             }
326             linefeed();
327             _addIndentation = true;
328         }
329     }
330 
331     public void writeln(final double d) {
332         synchronized (lock) {
333             ensureIndent();
334             try {
335                 _out.write(String.valueOf(d));
336             } catch (java.io.IOException ioe) {
337                 // ignore
338             }
339             linefeed();
340             _addIndentation = true;
341         }
342     }
343 
344     public void writeln(final Object obj) {
345         synchronized (lock) {
346             ensureIndent();
347             try {
348                 _out.write(obj.toString());
349             } catch (java.io.IOException ioe) {
350                 // ignore
351             }
352             linefeed();
353             _addIndentation = true;
354         }
355     }
356 
357     public void writeln(final String string) {
358         synchronized (lock) {
359             if (string.length() > 0) {
360                 ensureIndent();
361                 try {
362                     _out.write(string);
363                 } catch (java.io.IOException ioe) {
364                     // ignore
365                 }
366             }
367             linefeed();
368             _addIndentation = true;
369         }
370     }
371 
372     public void writeln(final char[] chars) {
373         synchronized (lock) {
374             ensureIndent();
375             try {
376                 _out.write(chars);
377             } catch (java.io.IOException ioe) {
378                 // ignore
379             }
380             linefeed();
381             _addIndentation = true;
382         }
383     }
384 
385     public void writeln(final boolean b) {
386         synchronized (lock) {
387             ensureIndent();
388             try {
389                 _out.write(String.valueOf(b));
390             } catch (java.io.IOException ioe) {
391                 // ignore
392             }
393             linefeed();
394             _addIndentation = true;
395         }
396     }
397 
398     public void writeln(final char c) {
399         synchronized (lock) {
400             ensureIndent();
401             try {
402                 _out.write(c);
403             } catch (java.io.IOException ioe) {
404                 // ignore
405             }
406             linefeed();
407             _addIndentation = true;
408         }
409     }
410 
411     //--------------------------------------------------------------------------
412 
413     /**
414      * {@inheritDoc}
415      */
416     public void close() {
417         try {
418             _out.close();
419         } catch (java.io.IOException ioe) {
420             // ignore
421         }
422     }
423 
424     /**
425      * {@inheritDoc}
426      */
427     public void flush() {
428         try {
429             _out.flush();
430         } catch (java.io.IOException ioe) {
431             // ignore
432         }
433     }
434 
435     /**
436      * {@inheritDoc}
437      */
438     public void write(final String s, final int off, final int len) {
439         synchronized (lock) {
440             ensureIndent();
441             try {
442                 _out.write(s, off, len);
443             } catch (java.io.IOException ioe) {
444                 // ignore
445             }
446             if (_autoflush) { flush(); }
447         }
448     }
449 
450     /**
451      * {@inheritDoc}
452      */
453     public void write(final String s) {
454         synchronized (lock) {
455             ensureIndent();
456             try {
457                 _out.write(s);
458             } catch (java.io.IOException ioe) {
459                 // ignore
460             }
461             if (_autoflush) { flush(); }
462         }
463     }
464 
465     /**
466      * {@inheritDoc}
467      */
468     public void write(final char[] buf) {
469         synchronized (lock) {
470             ensureIndent();
471             try {
472                 _out.write(buf);
473             } catch (java.io.IOException ioe) {
474                 // ignore
475             }
476             if (_autoflush) { flush(); }
477         }
478     }
479 
480     /**
481      * {@inheritDoc}
482      */
483     public void write(final int c) {
484         synchronized (lock) {
485             ensureIndent();
486             try {
487                 _out.write(c);
488             } catch (java.io.IOException ioe) {
489                 // ignore
490             }
491             if (_autoflush) { flush(); }
492         }
493     }
494 
495     /**
496      * {@inheritDoc}
497      */
498     public void write(final char[] buf, final int off, final int len) {
499         synchronized (lock) {
500             ensureIndent();
501             try {
502                 _out.write(buf, off, len);
503             } catch (java.io.IOException ioe) {
504                 // ignore
505             }
506             if (_autoflush) { flush(); }
507         }
508     }
509 
510     //--------------------------------------------------------------------------
511 }