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@codehaus.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.codehaus.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   * $Id$
44   */
45  package org.codehaus.modello.plugin.java.javasource;
46  
47  /*
48   * Copyright (c) 2004, Codehaus.org
49   *
50   * Permission is hereby granted, free of charge, to any person obtaining a copy of
51   * this software and associated documentation files (the "Software"), to deal in
52   * the Software without restriction, including without limitation the rights to
53   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
54   * of the Software, and to permit persons to whom the Software is furnished to do
55   * so, subject to the following conditions:
56   *
57   * The above copyright notice and this permission notice shall be included in all
58   * copies or substantial portions of the Software.
59   *
60   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
61   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
66   * SOFTWARE.
67   */
68  
69  import java.io.Writer;
70  
71  /**
72   * The writer used by the modello classes
73   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
74   * @version $Revision$ $Date$
75   **/
76  public class JSourceWriter extends Writer {
77  
78      /**
79       * The default character to use for indentation
80       **/
81      public static final char DEFAULT_CHAR = ' ';
82  
83      /**
84       * The default indentation size
85       **/
86      public static final short DEFAULT_SIZE = 4;
87  
88      /**
89       * The line separator to use for the writeln methods
90       **/
91      private String lineSeparator = System.getProperty("line.separator");
92  
93      /**
94       * Flag for indicating whether we need to add
95       * the whitespace to beginning of next write
96       * call
97       **/
98      private boolean addIndentation = true;
99  
100     /**
101      * A flag indicating whether this JSourceWriter should perform
102      * autoflush at the end of a new line
103      **/
104     private boolean autoflush = false;
105 
106     /**
107      * The tab (indentation) size
108      **/
109     private short tabSize = DEFAULT_SIZE;
110 
111     /**
112      * The tab representation
113      **/
114     private char[] tab;
115 
116     /**
117      * The character to use for indentation
118      **/
119     private char tabChar = DEFAULT_CHAR;
120 
121     /**
122      * The current tab level
123      **/
124     private short tabLevel = 0;
125 
126     /**
127      * The writer to send all output to
128      **/
129     private Writer out = null;
130 
131     /**
132      * Creates a new JSourceWriter
133      * @param out the Writer to write the actual output to
134      **/
135     public JSourceWriter(Writer out) {
136         this(out, DEFAULT_SIZE, DEFAULT_CHAR, false);
137     } // -- JSourceWriter
138 
139     /**
140      * Creates a new JSourceWriter
141      * @param out the Writer to write the actual output to
142      * @param autoflush a boolean indicating whether or not to
143      * perform automatic flush at the end of a line
144      **/
145     public JSourceWriter(Writer out, boolean autoflush) {
146         this(out, DEFAULT_SIZE, DEFAULT_CHAR, autoflush);
147     } // -- JSourceWriter
148 
149     /**
150      * Creates a new JSourceWriter
151      * @param out the Writer to write the actual output to
152      * @param tabSize the size of each indentation
153      * @param autoflush a boolean indicating whether or not to
154      * perform automatic flush at the end of a line
155      **/
156     public JSourceWriter(Writer out, short tabSize, boolean autoflush) {
157         this(out, tabSize, DEFAULT_CHAR, autoflush);
158     } // -- JSourceWriter
159 
160     /**
161      * Creates a new JSourceWriter
162      * @param out the Writer to write the actual output to
163      * @param tabSize the size of each indentation
164      * @param tabChar the character to use for indentation
165      * @param autoflush a boolean indicating whether or not to
166      * perform automatic flush at the end of a line
167      **/
168     public JSourceWriter(Writer out, short tabSize, char tabChar, boolean autoflush) {
169         this.out = out;
170         this.autoflush = autoflush;
171         this.tabChar = tabChar;
172         this.tabSize = tabSize;
173         createTab();
174     } // -- JSourceWriter
175 
176     /**
177      * Returns the line separator being used by this JSourceWriter
178      * @return the line separator being used by this JSourceWriter
179      **/
180     public String getLineSeparator() {
181         return lineSeparator;
182     } // -- getLineSeparator
183 
184     /**
185      * Increases the indentation level by 1
186      **/
187     public void indent() {
188         ++tabLevel;
189     } // -- increaseIndent
190 
191     /**
192      * Checks to see if the cursor is positioned on a new line
193      * @return true if the cursor is at the start of a new line, otherwise false
194      **/
195     public boolean isNewline() {
196         // -- if we need to add indentation, we are on a new line
197         return addIndentation;
198     } // --  isNewline
199 
200     /**
201      * Sets the line separator to use at the end of each line
202      * @param lineSeparator the String to use as a line
203      * separator.
204      * <BR>
205      * Typically a line separator will be one of the following:
206      * <BR>
207      * "\r\n" for MS Windows<BR>
208      * "\n"   for UNIX<BR>
209      * "\r"   for Macintosh
210      **/
211     public void setLineSeparator(String lineSeparator) {
212 
213         this.lineSeparator = lineSeparator;
214     } // -- setLineSeparator
215 
216     /**
217      * Decreases the indentation level by 1
218      **/
219     public void unindent() {
220         if (tabLevel > 0) --tabLevel;
221     } // -- decreaseIndent
222 
223     // ----------------------------/
224     // - Additional write methods -/
225     // ----------------------------/
226 
227     public void write(float f) {
228         write(String.valueOf(f));
229     } // -- write(float)
230 
231     public void write(long l) {
232         write(String.valueOf(l));
233     } // -- write(long)
234 
235     public void write(double d) {
236         write(String.valueOf(d));
237     } // -- write(double)
238 
239     public void write(Object obj) {
240         write(obj.toString());
241     } // -- write(Object)
242 
243     public void write(boolean b) {
244         write(String.valueOf(b));
245     } // -- write(boolean)
246 
247     // - writeln() methods
248 
249     public void writeln() {
250         synchronized (lock) {
251             linefeed();
252             addIndentation = true;
253         }
254     } // -- writeln
255 
256     public void writeln(float f) {
257         synchronized (lock) {
258             ensureIndent();
259             try {
260                 out.write(String.valueOf(f));
261             } catch (java.io.IOException ioe) {
262             }
263             ;
264             linefeed();
265             addIndentation = true;
266         }
267     } // -- writeln(float)
268 
269     public void writeln(long l) {
270         synchronized (lock) {
271             ensureIndent();
272             try {
273                 out.write(String.valueOf(l));
274             } catch (java.io.IOException ioe) {
275             }
276             ;
277             linefeed();
278             addIndentation = true;
279         }
280     } // -- writeln(long)
281 
282     public void writeln(int i) {
283         synchronized (lock) {
284             ensureIndent();
285             try {
286                 out.write(String.valueOf(i));
287             } catch (java.io.IOException ioe) {
288             }
289             ;
290             linefeed();
291             addIndentation = true;
292         }
293     } // -- writeln(int)
294 
295     public void writeln(double d) {
296         synchronized (lock) {
297             ensureIndent();
298             try {
299                 out.write(String.valueOf(d));
300             } catch (java.io.IOException ioe) {
301             }
302             ;
303             linefeed();
304             addIndentation = true;
305         }
306     } // -- writeln(double)
307 
308     public void writeln(Object obj) {
309         synchronized (lock) {
310             ensureIndent();
311             try {
312                 out.write(obj.toString());
313             } catch (java.io.IOException ioe) {
314             }
315             ;
316             linefeed();
317             addIndentation = true;
318         }
319     } // -- writeln(Object)
320 
321     public void writeln(String string) {
322         synchronized (lock) {
323             if (string.length() > 0) {
324                 ensureIndent();
325                 try {
326                     out.write(string);
327                 } catch (java.io.IOException ioe) {
328                 }
329             }
330 
331             linefeed();
332             addIndentation = true;
333         }
334     } // -- writeln(String)
335 
336     public void writeln(char[] chars) {
337         synchronized (lock) {
338             ensureIndent();
339             try {
340                 out.write(chars);
341             } catch (java.io.IOException ioe) {
342             }
343             ;
344             linefeed();
345             addIndentation = true;
346         }
347     } // -- writeln(char[])
348 
349     public void writeln(boolean b) {
350         synchronized (lock) {
351             ensureIndent();
352             try {
353                 out.write(String.valueOf(b));
354             } catch (java.io.IOException ioe) {
355             }
356             ;
357             linefeed();
358             addIndentation = true;
359         }
360     } // -- writeln(boolean)
361 
362     public void writeln(char c) {
363         synchronized (lock) {
364             ensureIndent();
365             try {
366                 out.write(c);
367             } catch (java.io.IOException ioe) {
368             }
369             ;
370             linefeed();
371             addIndentation = true;
372         }
373     } // -- writeln(char)
374 
375     // -----------------------/
376     // - Methods from Writer -/
377     // -----------------------/
378 
379     public void close() {
380         try {
381             out.close();
382         } catch (java.io.IOException ioe) {
383         }
384         ;
385     } // -- close
386 
387     public void flush() {
388         try {
389             out.flush();
390         } catch (java.io.IOException ioe) {
391         }
392         ;
393     } // -- flush
394 
395     public void write(String s, int off, int len) {
396         synchronized (lock) {
397             ensureIndent();
398             try {
399                 out.write(s, off, len);
400             } catch (java.io.IOException ioe) {
401             }
402             ;
403             if (autoflush) flush();
404         }
405     } // -- write
406 
407     public void write(String s) {
408         synchronized (lock) {
409             ensureIndent();
410             try {
411                 out.write(s);
412             } catch (java.io.IOException ioe) {
413             }
414             ;
415             if (autoflush) flush();
416         }
417     } // -- write
418 
419     public void write(char[] buf) {
420         synchronized (lock) {
421             ensureIndent();
422             try {
423                 out.write(buf);
424             } catch (java.io.IOException ioe) {
425             }
426             ;
427 
428             if (autoflush) flush();
429         }
430     } // -- write
431 
432     public void write(int c) {
433         synchronized (lock) {
434             ensureIndent();
435             try {
436                 out.write(c);
437             } catch (java.io.IOException ioe) {
438             }
439             ;
440             if (autoflush) flush();
441         }
442     } // -- write
443 
444     public void write(char[] buf, int off, int len) {
445         synchronized (lock) {
446             ensureIndent();
447             try {
448                 out.write(buf, off, len);
449             } catch (java.io.IOException ioe) {
450             }
451             ;
452             if (autoflush) flush();
453         }
454     } // -- write
455 
456     // ---------------------/
457     // - Protected Methods -/
458     // ---------------------/
459 
460     protected short getIndentLevel() {
461         return tabLevel;
462     }
463 
464     /**
465      * Returns the current indent size (getIndentLevel()*tabSize);
466      * @return the current indent size
467      **/
468     protected short getIndentSize() {
469         return (short) (tabLevel * tabSize);
470     } // -- getIndentSize
471 
472     protected char getIndentChar() {
473         return tabChar;
474     }
475 
476     protected void writeIndent() {
477 
478         try {
479             for (int i = 0; i < tabLevel; i++) out.write(tab);
480         } catch (java.io.IOException ioe) {
481         }
482         ;
483     } // -- writeIndent
484 
485     // -------------------/
486     // - Private Methods -/
487     // -------------------/
488 
489     private void ensureIndent() {
490         if (addIndentation) {
491             writeIndent();
492             addIndentation = false;
493         }
494     } // -- ensureIndent
495 
496     /**
497      * writes the line separator character to the writer
498      **/
499     private void linefeed() {
500         try {
501             out.write(lineSeparator);
502         } catch (java.io.IOException ioe) {
503         }
504         ;
505     } // -- linefeed
506 
507     /**
508      * Creates the tab from the tabSize and the tabChar
509      **/
510     private void createTab() {
511         tab = new char[tabSize];
512         for (int i = 0; i < tabSize; i++) {
513             tab[i] = tabChar;
514         }
515     } // -- createTab
516 } // -- JSourceWriter