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