KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com4j > tlbimp > IndentingWriter


1 package com4j.tlbimp;
2
3 import java.io.IOException JavaDoc;
4 import java.io.OutputStream JavaDoc;
5 import java.io.PrintWriter JavaDoc;
6 import java.io.Writer JavaDoc;
7 import java.io.FilterWriter JavaDoc;
8 import java.util.Stack JavaDoc;
9
10 /**
11  * {@link PrintWriter} with a little additional capability.
12  *
13  * <p>
14  * Specifically,
15  * <ol>
16  * <li>Indentation.
17  * <li>Printing comma-separated tokens.
18  * <li>Buffering the certain portion of the output and canceling it later.
19  * </ol>
20  *
21  * @author Kohsuke Kawaguchi (kk@kohsuke.org)
22  */

23 public class IndentingWriter extends PrintWriter JavaDoc {
24     private int indent=0;
25     private boolean newLine=true;
26
27     public IndentingWriter(Writer JavaDoc out) {
28         super(new CancellableWriter(out));
29     }
30
31     public IndentingWriter(Writer JavaDoc out, boolean autoFlush) {
32         super(new CancellableWriter(out), autoFlush);
33     }
34
35     private CancellableWriter getOut() {
36         return (CancellableWriter)out;
37     }
38
39
40 //
41
//
42
// buffering, cancelling, and committing
43
//
44
//
45
public void startBuffering() {
46         try {
47             getOut().mark();
48         } catch (IOException JavaDoc e) {
49         }
50     }
51
52     public void cancel() {
53         getOut().cancel();
54     }
55
56     public void commit() {
57         try {
58             getOut().commit();
59         } catch (IOException JavaDoc e) {
60         }
61     }
62
63 //
64
//
65
// indentation
66
//
67
//
68
/**
69      * Increases the indentation level.
70      */

71     public void in() {
72         indent++;
73     }
74
75     /**
76      * Decreases the indentation level.
77      */

78     public void out() {
79         indent--;
80     }
81
82     private void printIndent() {
83         try {
84             for( int i=0; i<indent; i++ )
85                 out.write(" ");
86         } catch( IOException JavaDoc e ) {
87         }
88     }
89
90     private void checkIndent() {
91         if(newLine)
92             printIndent();
93         newLine = false;
94     }
95
96
97 //
98
//
99
// comma-separated tokens
100
//
101
//
102
/**
103      * If true, we need to print ',' in the next {@link #comma()}.
104      */

105     private boolean needsComma;
106
107     private final Stack JavaDoc<Boolean JavaDoc> commaStack = new Stack JavaDoc<Boolean JavaDoc>();
108
109     /**
110      * Starts the comma-separated token mode.
111      */

112     public void beginCommaMode() {
113         commaStack.push(needsComma);
114         needsComma = false;
115     }
116
117     /**
118      * Ends the comma-separated token mode.
119      */

120     public void endCommaMode() {
121         needsComma |= (boolean)commaStack.pop();
122     }
123
124     /**
125      * Prints out ',' if something was printed since
126      * the last invocation of {@link #comma()} or {@link #beginCommaMode()}.
127      */

128     public void comma() {
129         if(needsComma) {
130             print(',');
131             needsComma = false;
132         }
133     }
134
135
136
137 //
138
//
139
// overriding the base class methods
140
//
141
//
142
public void println() {
143         super.println();
144         newLine = true;
145     }
146
147     public void write(int c) {
148         checkIndent();
149         needsComma = true;
150         super.write(c);
151     }
152
153     public void write(char buf[], int off, int len) {
154         checkIndent();
155         needsComma = true;
156         super.write(buf, off, len);
157     }
158
159     public void write(String JavaDoc s, int off, int len) {
160         checkIndent();
161         needsComma = true;
162         super.write(s, off, len);
163     }
164 }
165
166 class CancellableWriter extends FilterWriter JavaDoc {
167     /**
168      * Text that might be cancelled later will be buffered here.
169      */

170     private final StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
171
172     private boolean marked;
173
174     /**
175      * Once called, successive writing will be buffered until
176      * cancel() or commit() is called later.
177      */

178     public void mark() throws IOException JavaDoc {
179         if(marked) commit();
180         marked = true;
181     }
182
183     /**
184      * Cancel the data written since the last {@link #mark()} method.
185      */

186     public void cancel() {
187         if(!marked) throw new IllegalStateException JavaDoc();
188         marked = false;
189         buffer.setLength(0);
190     }
191
192     /**
193      * Write the pending data.
194      */

195     public void commit() throws IOException JavaDoc {
196         if(!marked) throw new IllegalStateException JavaDoc();
197         marked = false;
198         super.append(buffer);
199         buffer.setLength(0);
200     }
201
202
203     public CancellableWriter(Writer JavaDoc out) {
204         super(out);
205     }
206
207     public void write(int c) throws IOException JavaDoc {
208         if(marked)
209             buffer.append( (char)c );
210         else
211             super.write(c);
212     }
213
214     public void write(char[] cbuf, int off, int len) throws IOException JavaDoc {
215         if(marked)
216             buffer.append(cbuf,off,len);
217         else
218             super.write(cbuf, off, len);
219     }
220
221     public void write(String JavaDoc str, int off, int len) throws IOException JavaDoc {
222         if(marked)
223             buffer.append(str,off,len);
224         else
225             super.write(str, off, len);
226     }
227
228     public void flush() throws IOException JavaDoc {
229         super.flush();
230     }
231
232     public void close() throws IOException JavaDoc {
233         if(marked)
234             commit();
235         super.close();
236     }
237 }
Popular Tags