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