1 /*
   2  * Copyright (c) 1997, 2013, 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 com.sun.tools.internal.ws.processor.util;
  27 
  28 import com.sun.tools.internal.ws.processor.generator.GeneratorException;
  29 
  30 import java.io.BufferedWriter;
  31 import java.io.IOException;
  32 import java.io.Writer;
  33 import java.nio.charset.Charset;
  34 import java.nio.charset.CharsetEncoder;
  35 import java.text.MessageFormat;
  36 
  37 /**
  38  *
  39  * @author WS Development Team
  40  */
  41 public class IndentingWriter extends BufferedWriter {
  42 
  43     private boolean beginningOfLine = true;
  44     private int currentIndent = 0;
  45     private int indentStep = 4;
  46 
  47     public IndentingWriter(Writer out) {
  48         super(out);
  49     }
  50 
  51     public IndentingWriter(Writer out,int step) {
  52         this(out);
  53 
  54         if (indentStep < 0) {
  55             throw new IllegalArgumentException("negative indent step");
  56         }
  57         indentStep = step;
  58     }
  59 
  60     public void write(int c) throws IOException {
  61         checkWrite();
  62         super.write(c);
  63     }
  64 
  65     public void write(char[] cbuf, int off, int len) throws IOException {
  66         if (len > 0) {
  67             checkWrite();
  68         }
  69         super.write(cbuf, off, len);
  70     }
  71 
  72     public void write(String s, int off, int len) throws IOException {
  73         if (len > 0) {
  74             checkWrite();
  75         }
  76         super.write(s, off, len);
  77     }
  78 
  79     public void newLine() throws IOException {
  80         super.newLine();
  81         beginningOfLine = true;
  82     }
  83 
  84     protected void checkWrite() throws IOException {
  85         if (beginningOfLine) {
  86             beginningOfLine = false;
  87             int i = currentIndent;
  88             while (i > 0) {
  89                 super.write(' ');
  90                 -- i;
  91             }
  92         }
  93     }
  94 
  95     protected void indentIn() {
  96         currentIndent += indentStep;
  97     }
  98 
  99     protected void indentOut() {
 100         currentIndent -= indentStep;
 101         if (currentIndent < 0) {
 102             currentIndent = 0;
 103         }
 104     }
 105 
 106     public void pI() {
 107         indentIn();
 108     }
 109 
 110     public void pO() {
 111         indentOut();
 112     }
 113 
 114     public void pI(int levels) {
 115         for (int i = 0; i < levels; ++i) {
 116             indentIn();
 117         }
 118     }
 119 
 120     public void pO(int levels) {
 121         for (int i = 0; i < levels; ++i) {
 122             indentOut();
 123         }
 124     }
 125 
 126     public void p(String s) throws IOException {
 127         /*
 128         int tabCount = 0;
 129         for (int i = 0; i < s.length(); ++i) {
 130             if (s.charAt(i) == '\t') {
 131                 ++tabCount;
 132                 indentIn();
 133             }
 134         }
 135 
 136         String printStr = s.substring(tabCount);
 137          */
 138         boolean canEncode = true;
 139 
 140         //bug fix: 4839636
 141         try{
 142             if(!canEncode(s)) {
 143                 canEncode = false;
 144             }
 145         } catch (Throwable t) {
 146 
 147             // there was some exception, what should we do?
 148             // lets ignore it for now and proceed with the code generation!
 149         }
 150 
 151         if(!canEncode) {
 152             throw new GeneratorException(
 153                 "generator.indentingwriter.charset.cantencode", s);
 154         }
 155         write(s);
 156 /*
 157         while (tabCount-- > 0) {
 158             indentOut();
 159         }
 160  */
 161     }
 162 
 163     /**
 164      * Check if encode can handle the chars in this string.
 165      *
 166      */
 167     protected boolean canEncode(String s) {
 168         final CharsetEncoder encoder =
 169             Charset.forName(System.getProperty("file.encoding")).newEncoder();
 170         char[] chars = s.toCharArray();
 171         for (int i=0; i<chars.length; i++) {
 172             if(!encoder.canEncode(chars[i])) {
 173                 return false;
 174             }
 175         }
 176         return true;
 177     }
 178 
 179     public void p(String s1, String s2) throws IOException {
 180         p(s1);
 181         p(s2);
 182     }
 183 
 184     public void p(String s1, String s2, String s3) throws IOException {
 185         p(s1);
 186         p(s2);
 187         p(s3);
 188     }
 189 
 190     public void p(String s1, String s2, String s3, String s4) throws IOException {
 191         p(s1);
 192         p(s2);
 193         p(s3);
 194         p(s4);
 195     }
 196 
 197     public void p(String s1, String s2, String s3, String s4, String s5) throws IOException {
 198         p(s1);
 199         p(s2);
 200         p(s3);
 201         p(s4);
 202         p(s5);
 203     }
 204 
 205     public void pln() throws IOException {
 206         newLine();
 207     }
 208 
 209     public void pln(String s) throws IOException {
 210         p(s);
 211         pln();
 212     }
 213 
 214     public void pln(String s1, String s2) throws IOException {
 215         p(s1, s2);
 216         pln();
 217     }
 218 
 219     public void pln(String s1, String s2, String s3) throws IOException {
 220         p(s1, s2, s3);
 221         pln();
 222     }
 223 
 224     public void pln(String s1, String s2, String s3, String s4) throws IOException {
 225         p(s1, s2, s3, s4);
 226         pln();
 227     }
 228 
 229     public void pln(String s1, String s2, String s3, String s4, String s5) throws IOException {
 230         p(s1, s2, s3, s4, s5);
 231         pln();
 232     }
 233 
 234     public void plnI(String s) throws IOException {
 235         p(s);
 236         pln();
 237         pI();
 238     }
 239 
 240     public void pO(String s) throws IOException {
 241         pO();
 242         p(s);
 243     }
 244 
 245     public void pOln(String s) throws IOException {
 246         pO(s);
 247         pln();
 248     }
 249 
 250     public void pOlnI(String s) throws IOException {
 251         pO(s);
 252         pln();
 253         pI();
 254     }
 255 
 256     public void p(Object o) throws IOException {
 257         write(o.toString());
 258     }
 259 
 260     public void pln(Object o) throws IOException {
 261         p(o.toString());
 262         pln();
 263     }
 264 
 265     public void plnI(Object o) throws IOException {
 266         p(o.toString());
 267         pln();
 268         pI();
 269     }
 270 
 271     public void pO(Object o) throws IOException {
 272         pO();
 273         p(o.toString());
 274     }
 275 
 276     public void pOln(Object o) throws IOException {
 277         pO(o.toString());
 278         pln();
 279     }
 280 
 281     public void pOlnI(Object o) throws IOException {
 282         pO(o.toString());
 283         pln();
 284         pI();
 285     }
 286 
 287     public void pM(String s) throws IOException {
 288         int i = 0;
 289         while (i < s.length()) {
 290             int j = s.indexOf('\n', i);
 291             if (j == -1) {
 292                 p(s.substring(i));
 293                 break;
 294             } else {
 295                 pln(s.substring(i, j));
 296                 i = j + 1;
 297             }
 298         }
 299     }
 300 
 301     public void pMln(String s) throws IOException {
 302         pM(s);
 303         pln();
 304     }
 305 
 306     public void pMlnI(String s) throws IOException {
 307         pM(s);
 308         pln();
 309         pI();
 310     }
 311 
 312     public void pMO(String s) throws IOException {
 313         pO();
 314         pM(s);
 315     }
 316 
 317     public void pMOln(String s) throws IOException {
 318         pMO(s);
 319         pln();
 320     }
 321 
 322     public void pF(String pattern, Object[] arguments) throws IOException {
 323         pM(MessageFormat.format(pattern, arguments));
 324     }
 325 
 326     public void pFln(String pattern, Object[] arguments) throws IOException {
 327         pF(pattern, arguments);
 328         pln();
 329     }
 330 }