1 /* 2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.rmi.rmic.newrmic; 27 28 import java.io.Writer; 29 import java.io.BufferedWriter; 30 import java.io.IOException; 31 32 /** 33 * A BufferedWriter that supports automatic indentation of lines of 34 * text written to the underlying Writer. 35 * 36 * Methods are provided for compact/convenient indenting in and out, 37 * writing text, and writing lines of text in various combinations. 38 * 39 * WARNING: The contents of this source file are not part of any 40 * supported API. Code that depends on them does so at its own risk: 41 * they are subject to change or removal without notice. 42 * 43 * @author Peter Jones 44 **/ 45 public class IndentingWriter extends BufferedWriter { 46 47 /** number of spaces to change indent when indenting in or out */ 48 private final int indentStep; 49 50 /** number of spaces to convert into tabs (use MAX_VALUE to disable) */ 51 private final int tabSize; 52 53 /** true if the next character written is the first on a line */ 54 private boolean beginningOfLine = true; 55 56 /** current number of spaces to prepend to lines */ 57 private int currentIndent = 0; 58 59 /** 60 * Creates a new IndentingWriter that writes indented text to the 61 * given Writer. Use the default indent step of four spaces. 62 **/ IndentingWriter(Writer out)63 public IndentingWriter(Writer out) { 64 this(out, 4); 65 } 66 67 /** 68 * Creates a new IndentingWriter that writes indented text to the 69 * given Writer and uses the supplied indent step. 70 **/ IndentingWriter(Writer out, int indentStep)71 public IndentingWriter(Writer out, int indentStep) { 72 this(out, indentStep, 8); 73 } 74 75 /** 76 * Creates a new IndentingWriter that writes indented text to the 77 * given Writer and uses the supplied indent step and tab size. 78 **/ IndentingWriter(Writer out, int indentStep, int tabSize)79 public IndentingWriter(Writer out, int indentStep, int tabSize) { 80 super(out); 81 if (indentStep < 0) { 82 throw new IllegalArgumentException("negative indent step"); 83 } 84 if (tabSize < 0) { 85 throw new IllegalArgumentException("negative tab size"); 86 } 87 this.indentStep = indentStep; 88 this.tabSize = tabSize; 89 } 90 91 /** 92 * Writes a single character. 93 **/ write(int c)94 public void write(int c) throws IOException { 95 checkWrite(); 96 super.write(c); 97 } 98 99 /** 100 * Writes a portion of an array of characters. 101 **/ write(char[] cbuf, int off, int len)102 public void write(char[] cbuf, int off, int len) throws IOException { 103 if (len > 0) { 104 checkWrite(); 105 } 106 super.write(cbuf, off, len); 107 } 108 109 /** 110 * Writes a portion of a String. 111 **/ write(String s, int off, int len)112 public void write(String s, int off, int len) throws IOException { 113 if (len > 0) { 114 checkWrite(); 115 } 116 super.write(s, off, len); 117 } 118 119 /** 120 * Writes a line separator. The next character written will be 121 * preceded by an indent. 122 **/ newLine()123 public void newLine() throws IOException { 124 super.newLine(); 125 beginningOfLine = true; 126 } 127 128 /** 129 * Checks if an indent needs to be written before writing the next 130 * character. 131 * 132 * The indent generation is optimized (and made consistent with 133 * certain coding conventions) by condensing groups of eight 134 * spaces into tab characters. 135 **/ checkWrite()136 protected void checkWrite() throws IOException { 137 if (beginningOfLine) { 138 beginningOfLine = false; 139 int i = currentIndent; 140 while (i >= tabSize) { 141 super.write('\t'); 142 i -= tabSize; 143 } 144 while (i > 0) { 145 super.write(' '); 146 i--; 147 } 148 } 149 } 150 151 /** 152 * Increases the current indent by the indent step. 153 **/ indentIn()154 protected void indentIn() { 155 currentIndent += indentStep; 156 } 157 158 /** 159 * Decreases the current indent by the indent step. 160 **/ indentOut()161 protected void indentOut() { 162 currentIndent -= indentStep; 163 if (currentIndent < 0) 164 currentIndent = 0; 165 } 166 167 /** 168 * Indents in. 169 **/ pI()170 public void pI() { 171 indentIn(); 172 } 173 174 /** 175 * Indents out. 176 **/ pO()177 public void pO() { 178 indentOut(); 179 } 180 181 /** 182 * Writes string. 183 **/ p(String s)184 public void p(String s) throws IOException { 185 write(s); 186 } 187 188 /** 189 * Ends current line. 190 **/ pln()191 public void pln() throws IOException { 192 newLine(); 193 } 194 195 /** 196 * Writes string; ends current line. 197 **/ pln(String s)198 public void pln(String s) throws IOException { 199 p(s); 200 pln(); 201 } 202 203 /** 204 * Writes string; ends current line; indents in. 205 **/ plnI(String s)206 public void plnI(String s) throws IOException { 207 p(s); 208 pln(); 209 pI(); 210 } 211 212 /** 213 * Indents out; writes string. 214 **/ pO(String s)215 public void pO(String s) throws IOException { 216 pO(); 217 p(s); 218 } 219 220 /** 221 * Indents out; writes string; ends current line. 222 **/ pOln(String s)223 public void pOln(String s) throws IOException { 224 pO(s); 225 pln(); 226 } 227 228 /** 229 * Indents out; writes string; ends current line; indents in. 230 * 231 * This method is useful for generating lines of code that both 232 * end and begin nested blocks, like "} else {". 233 **/ pOlnI(String s)234 public void pOlnI(String s) throws IOException { 235 pO(s); 236 pln(); 237 pI(); 238 } 239 240 /** 241 * Writes object. 242 **/ p(Object o)243 public void p(Object o) throws IOException { 244 write(o.toString()); 245 } 246 247 /** 248 * Writes object; ends current line. 249 **/ pln(Object o)250 public void pln(Object o) throws IOException { 251 p(o.toString()); 252 pln(); 253 } 254 255 /** 256 * Writes object; ends current line; indents in. 257 **/ plnI(Object o)258 public void plnI(Object o) throws IOException { 259 p(o.toString()); 260 pln(); 261 pI(); 262 } 263 264 /** 265 * Indents out; writes object. 266 **/ pO(Object o)267 public void pO(Object o) throws IOException { 268 pO(); 269 p(o.toString()); 270 } 271 272 /** 273 * Indents out; writes object; ends current line. 274 **/ pOln(Object o)275 public void pOln(Object o) throws IOException { 276 pO(o.toString()); 277 pln(); 278 } 279 280 /** 281 * Indents out; writes object; ends current line; indents in. 282 * 283 * This method is useful for generating lines of code that both 284 * end and begin nested blocks, like "} else {". 285 **/ pOlnI(Object o)286 public void pOlnI(Object o) throws IOException { 287 pO(o.toString()); 288 pln(); 289 pI(); 290 } 291 } 292