/Users/lyon/j4p/src/classUtils/pack/util/IndentedPrintWriter.java

1    /* Generated by Together */ 
2     
3    package classUtils.pack.util; 
4     
5    import java.io.*; 
6    import java.util.*; 
7     
8    /** 
9     * A PrintWriter which indents each line of text with a given character. 
10    * 
11    * @author Cris Sadun 
12    * @version 1.2 
13    */ 
14   public class IndentedPrintWriter extends PrintWriter { 
15    
16      private static char [] ls=System.getProperty("line.separator").toCharArray(); 
17      private int truncatedNL; 
18      private char []spc; 
19      private boolean start=true; 
20      private char indentationChar; 
21      private boolean autoFlush; 
22    
23      /** 
24       * Create a new writer over the given one, with the given indentation value. 
25       * The indentation charachter defaults to blank - use {@link 
26       * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
27       * if required. 
28       * @param w the writer wrapped by this IndentationPrintWriter 
29       * @param indent the indentation level 
30       */ 
31      public IndentedPrintWriter(Writer w, int indent) { 
32       this(w, indent, false); 
33      } 
34    
35      /** 
36       * Create a new writer over the given stream, with the given indentation value. 
37       * The indentation charachter defaults to blank - use {@link 
38       * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
39       * if required. 
40       * @param out the stream wrapped by this IndentationPrintWriter 
41       * @param indent the indentation level 
42       * @param autoFlush if true, the println() methods will flush the output buffer 
43       */ 
44      public IndentedPrintWriter(OutputStream out, int indent, boolean autoFlush) { 
45           this(new BufferedWriter(new OutputStreamWriter(out)), indent, autoFlush); 
46      } 
47    
48      /** 
49       * Create a new writer over the given stream, with the given indentation value, 
50       * and no autoflush. 
51       * The indentation charachter defaults to blank - use {@link 
52       * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
53       * if required. 
54       * @param out the stream wrapped by this IndentationPrintWriter 
55       * @param indent the indentation level 
56       */ 
57      public IndentedPrintWriter(OutputStream out, int indent) { 
58          this(out, indent, false); 
59      } 
60    
61      /** 
62       * Create a new writer over the given one, with the given indentation value. 
63       * The indentation charachter defaults to blank - use {@link 
64       * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
65       * if required. 
66       * @param w the writer wrapped by this IndentationPrintWriter 
67       * @param indent the indentation level 
68       * @param autoFlush if true, the println() methods will flush the output buffer 
69       */ 
70      public IndentedPrintWriter(Writer w, int indent, boolean autoFlush) { 
71          super(w, autoFlush); 
72          this.truncatedNL=0; 
73          this.indentationChar=' '; 
74          this.autoFlush=autoFlush; 
75          setIndentation(indent); 
76      } 
77    
78      /** 
79       * Create a new writer over the given one, with the default indentation value, 
80       * and no autoflush. 
81       * The indentation charachter defaults to blank - use {@link 
82       * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
83       * if required. 
84       * @param w the writer wrapped by this IndentationPrintWriter 
85       */ 
86      public IndentedPrintWriter(Writer w) { 
87       this(w, 0); 
88      } 
89    
90      /** 
91       * Create a new writer over the given stream, with the default indentation value. 
92       * The indentation charachter defaults to blank - use {@link 
93       * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
94       * if required. 
95       * @param out the stream wrapped by this IndentationPrintWriter 
96       * @param autoFlush if true, the println() methods will flush the output buffer 
97       */ 
98      public IndentedPrintWriter(OutputStream out, boolean autoFlush) { 
99           this(out, 0, autoFlush); 
100     } 
101   
102   
103     /** 
104      * Create a new writer over the given stream, with the default indentation value 
105      * and no autoflush. 
106      * The indentation charachter defaults to blank - use {@link 
107      * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
108      * if required. 
109      * @param out the stream wrapped by this IndentationPrintWriter 
110      */ 
111     public IndentedPrintWriter(OutputStream out) { 
112         this(out, 0); 
113     } 
114   
115     /** 
116      * Create a new writer over the given one, with the defaukt indentation value. 
117      * The indentation charachter defaults to blank - use {@link 
118      * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently 
119      * if required. 
120      * @param w the writer wrapped by this IndentationPrintWriter 
121      * @param autoFlush if true, the println() methods will flush the output buffer 
122      */ 
123     public IndentedPrintWriter(Writer w, boolean autoFlush) { 
124          this(w, 0, autoFlush); 
125     } 
126   
127     /** 
128      * Return the current indentation level 
129      * @return the current indentation level 
130      */ 
131     public int getIndentation(){ return spc.length; } 
132   
133     /** 
134      * Sets the current indentation level 
135      * @param indent the desired indentation level 
136      */ 
137     public synchronized void setIndentation(int indent){ 
138      if (indent < 0) throw new RuntimeException("Attmpting to set negative indentation"); 
139      spc = new char[indent]; 
140      Arrays.fill(spc, indentationChar); 
141     } 
142   
143     /** 
144      * Increment the current indentation level of the given level. 
145      * @param level the indentation level to be incremented 
146      */ 
147     public void incIndentation(int level) { setIndentation(getIndentation()+level); } 
148   
149     /** 
150      * Decrement the current indentation level of the given level. 
151      * 0 is the minimum level. 
152      * @param level the indentation level to be reduced 
153      */ 
154     public void decIndentation(int level) { setIndentation(getIndentation()-level); } 
155   
156     /** 
157      * Increment the current indentation level. 
158      * <p> 
159      */ 
160     public void incIndentation() { incIndentation(1); } 
161   
162     /** 
163      * Decrement the current indentation level. 0 is the minimum level. 
164      * <p> 
165      */ 
166     public void decIndentation() { decIndentation(1); } 
167   
168     /** 
169      * Set the charachter used to indent to the given character 
170      * @param c the charachter to use for indentation 
171      */ 
172     public synchronized void setIndentationChar(char c) { 
173      this.indentationChar=c; 
174      setIndentation(getIndentation()); 
175     } 
176   
177     /** 
178      * Return the charachter used to indent to the given character 
179      * @return the charachter to use for indentation 
180      */ 
181     public char getIndentationChar() { return indentationChar; } 
182   
183     /** 
184      * Write a substring of a string, of given length from a given offset 
185      */ 
186     public void write(String s, int off, int len) { 
187       write(s.toCharArray(), off, len); 
188     } 
189   
190     /** 
191      * Write a character 
192      */ 
193     public void write(int c) { 
194      write(new char[] { (char)c }, 0, 1); 
195     } 
196   
197     /** 
198      * Write a portion of character array, of given length from a given offset 
199      */ 
200     public void write(char buf[], int off, int len) { 
201      synchronized(out) { 
202   
203       if (start) { 
204          super.write(spc, 0, spc.length); 
205          start=false; 
206       } 
207   
208       List pos = new ArrayList(); 
209       int truncated=truncatedNL; // Remember if we start in a truncated-newline situation 
210       for(int i=off;i<off+len;i++) { 
211          if (isNL(buf, i, off+len)) pos.add(new Integer(i)); 
212       } 
213       int p1 = 0; 
214       String s; 
215       for(Iterator i=pos.iterator();i.hasNext(); ) { 
216         int p2 = ((Integer)i.next()).intValue(); 
217         super.write(buf, p1, p2-p1); 
218         super.write(ls, 0, ls.length); 
219         super.write(spc, 0, spc.length); 
220         p1=p2+ls.length-truncated; 
221         if (truncated!=0) truncated=0; // Just the first time 
222       } 
223       super.write(buf, p1, off+len-p1); 
224       if (autoFlush) super.flush(); 
225      } 
226     } 
227   
228     /** 
229      * Checks if buf matches the line separator this.ls, 
230      * setting this.truncatedNL if a partial match exists 
231      * but the buffer portion is too short for a complete 
232      * match 
233      */ 
234     private boolean isNL(char []buf, int start, int end) { 
235     for(int i=truncatedNL;i<ls.length && start+i<end;i++) { 
236          int pos = start+i-truncatedNL; 
237          if (buf[pos]!=ls[i]) { 
238              if (truncatedNL !=0) truncatedNL=0; 
239              return false; 
240          } 
241      } 
242      if (end-start+truncatedNL < ls.length) { 
243          truncatedNL=end-start; 
244          return false; 
245      } 
246      if (truncatedNL !=0) truncatedNL=0; 
247      return true; 
248     } 
249   
250   
251     /** 
252      * Terminate the current line by writing the line separator string.  The 
253      * line separator string is defined by the system property 
254      * <code>line.separator</code>, and is not necessarily a single newline 
255      * character (<code>'\n'</code>). 
256      */ 
257     public void println() { 
258      super.println(); 
259      flush(); 
260      start=true; 
261     } 
262   
263     /*public static void main(String []args) throws Exception { 
264       IndentedPrintWriter pw = new IndentedPrintWriter(System.out, 5); 
265       //pw.autoFlush=true; 
266       pw.write(ls[0]); 
267       pw.write(ls[1]); 
268        
269       pw.print("This is a test... \r"); 
270       pw.print("\nlet'see."); 
271       pw.println("Hello"+System.getProperty("line.separator")+"World"); 
272     }*/ 
273   
274  } 
275   
276