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 }