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 }