001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.satsa.jcrmic.utils;
028:
029: import java.io.*;
030:
031: /**
032: * IndentingWriter is a BufferedWriter subclass that supports automatic
033: * indentation of lines of text written to the underlying Writer.
034: *
035: * Methods are provided for compact, convenient indenting, writing text,
036: * and writing lines in various combinations.
037: */
038: public class IndentingWriter extends BufferedWriter {
039:
040: /** true if the next character written is the first on a line */
041: private boolean beginningOfLine = true;
042:
043: /** current number of spaces to prepend to lines */
044: private int currentIndent = 0;
045:
046: /** number of spaces to change indent when indenting in or out */
047: private int indentStep = 4;
048:
049: /**
050: * Create a new IndentingWriter that writes indented text to the
051: * given Writer. Use the default indent step of four spaces.
052: * @param out output stream
053: */
054: public IndentingWriter(Writer out) {
055: super (out);
056: }
057:
058: /**
059: * Create a new IndentingWriter that writes indented text to the
060: * given Writer and uses the supplied indent step.
061: * @param out output stream
062: * @param step indent step
063: */
064: public IndentingWriter(Writer out, int step) {
065: this (out);
066:
067: if (indentStep < 0)
068: throw new IllegalArgumentException("negative indent step");
069:
070: indentStep = step;
071: }
072:
073: /**
074: * Write a single character.
075: * @param c the character
076: * @throws IOException if I/O exception occurs
077: */
078: public void write(int c) throws IOException {
079: checkWrite();
080: super .write(c);
081: }
082:
083: /**
084: * Write a portion of an array of characters.
085: * @param cbuf buffer
086: * @param off offset
087: * @param len length
088: * @throws IOException if I/O exception occurs
089: */
090: public void write(char[] cbuf, int off, int len) throws IOException {
091: if (len > 0) {
092: checkWrite();
093: }
094: super .write(cbuf, off, len);
095: }
096:
097: /**
098: * Write a portion of a String.
099: * @param s the string
100: * @param off offset
101: * @param len length
102: * @throws IOException if I/O exception occurs
103: */
104: public void write(String s, int off, int len) throws IOException {
105: if (len > 0) {
106: checkWrite();
107: }
108: super .write(s, off, len);
109: }
110:
111: /**
112: * Write a line separator. The next character written will be
113: * preceded by an indent.
114: * @throws IOException if I/O exception occurs
115: */
116: public void newLine() throws IOException {
117: super .newLine();
118: beginningOfLine = true;
119: }
120:
121: /**
122: * Check if an indent needs to be written before writing the next
123: * character.
124: *
125: * The indent generation is optimized (and made consistent with
126: * certain coding conventions) by condensing groups of eight spaces
127: * into tab characters.
128: * @throws IOException if I/O exception occurs
129: */
130: protected void checkWrite() throws IOException {
131: if (beginningOfLine) {
132: beginningOfLine = false;
133: int i = currentIndent;
134: while (i >= 8) {
135: super .write('\t');
136: i -= 8;
137: }
138: while (i > 0) {
139: super .write(' ');
140: --i;
141: }
142: }
143: }
144:
145: /**
146: * Increase the current indent by the indent step.
147: */
148: protected void indentIn() {
149: currentIndent += indentStep;
150: }
151:
152: /**
153: * Decrease the current indent by the indent step.
154: */
155: protected void indentOut() {
156: currentIndent -= indentStep;
157: if (currentIndent < 0)
158: currentIndent = 0;
159: }
160:
161: /**
162: * Indent in.
163: */
164: public void pI() {
165: indentIn();
166: }
167:
168: /**
169: * Indent out.
170: */
171: public void pO() {
172: indentOut();
173: }
174:
175: /**
176: * Write string.
177: * @param s the string
178: * @throws IOException if I/O exception occurs
179: */
180: public void p(String s) throws IOException {
181: write(s);
182: }
183:
184: /**
185: * End current line.
186: * @throws IOException if I/O exception occurs
187: */
188: public void pln() throws IOException {
189: newLine();
190: }
191:
192: /**
193: * Write string; end current line.
194: * @param s the string
195: * @throws IOException if I/O exception occurs
196: */
197: public void pln(String s) throws IOException {
198: p(s);
199: pln();
200: }
201:
202: /**
203: * Write string; end current line; indent in.
204: * @param s the string
205: * @throws IOException if I/O exception occurs
206: */
207: public void plnI(String s) throws IOException {
208: p(s);
209: pln();
210: pI();
211: }
212:
213: /**
214: * Indent out; write string.
215: * @param s the string
216: * @throws IOException if I/O exception occurs
217: */
218: public void pO(String s) throws IOException {
219: pO();
220: p(s);
221: }
222:
223: /**
224: * Indent out; write string; end current line.
225: * @param s the string
226: * @throws IOException if I/O exception occurs
227: */
228: public void pOln(String s) throws IOException {
229: pO(s);
230: pln();
231: }
232:
233: /**
234: * Indent out; write string; end current line; indent in.
235: *
236: * This method is useful for generating lines of code that both
237: * end and begin nested blocks, like "} else {".
238: * @param s the string
239: * @throws IOException if I/O exception occurs
240: */
241: public void pOlnI(String s) throws IOException {
242: pO(s);
243: pln();
244: pI();
245: }
246: }
|