001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.utils;
018
019 import org.jetbrains.annotations.NotNull;
020
021 import java.io.IOException;
022 import java.util.Collection;
023 import java.util.Iterator;
024
025 public class Printer {
026 private static final String DEFAULT_INDENTATION_UNIT = " ";
027 private static final String LINE_SEPARATOR = System.getProperty("line.separator");
028
029 protected final Appendable out;
030 private final int maxBlankLines;
031
032 private String indent = "";
033 private final String indentUnit;
034 private int blankLineCountIncludingCurrent = 0;
035 private boolean withholdIndentOnce = false;
036
037 public Printer(@NotNull Appendable out) {
038 this(out, Integer.MAX_VALUE);
039 }
040
041 public Printer(@NotNull Appendable out, @NotNull String indentUnit) {
042 this(out, Integer.MAX_VALUE, indentUnit);
043 }
044
045 public Printer(@NotNull Appendable out, int maxBlankLines) {
046 this(out, maxBlankLines, DEFAULT_INDENTATION_UNIT);
047 }
048
049 public Printer(@NotNull Appendable out, int maxBlankLines, @NotNull String indentUnit) {
050 this.out = out;
051 this.maxBlankLines = maxBlankLines;
052 this.indentUnit = indentUnit;
053 }
054
055 private void append(Object o) {
056 try {
057 out.append(o.toString());
058 }
059 catch (IOException e) {
060 // Do nothing
061 }
062 }
063
064 @NotNull
065 public Printer println(Object... objects) {
066 print(objects);
067 printLineSeparator();
068
069 return this;
070 }
071
072 private void printLineSeparator() {
073 if (blankLineCountIncludingCurrent <= maxBlankLines) {
074 blankLineCountIncludingCurrent++;
075 append(LINE_SEPARATOR);
076 }
077 }
078
079 @NotNull
080 public Printer print(Object... objects) {
081 if (withholdIndentOnce) {
082 withholdIndentOnce = false;
083 }
084 else if (objects.length > 0) {
085 printIndent();
086 }
087 printWithNoIndent(objects);
088
089 return this;
090 }
091
092 public void printIndent() {
093 append(indent);
094 }
095
096 @NotNull
097 public Printer printWithNoIndent(Object... objects) {
098 for (Object object : objects) {
099 blankLineCountIncludingCurrent = 0;
100 append(object);
101 }
102
103 return this;
104 }
105
106 @NotNull
107 public Printer withholdIndentOnce() {
108 withholdIndentOnce = true;
109 return this;
110 }
111
112 @NotNull
113 public Printer printlnWithNoIndent(Object... objects) {
114 printWithNoIndent(objects);
115 printLineSeparator();
116
117 return this;
118 }
119
120 @NotNull
121 public Printer pushIndent() {
122 indent += indentUnit;
123
124 return this;
125 }
126
127 @NotNull
128 public Printer popIndent() {
129 if (indent.length() < indentUnit.length()) {
130 throw new IllegalStateException("No indentation to pop");
131 }
132
133 indent = indent.substring(indentUnit.length());
134
135 return this;
136 }
137
138 @NotNull
139 public Printer separated(Object separator, Object... items) {
140 for (int i = 0; i < items.length; i++) {
141 if (i > 0) {
142 printlnWithNoIndent(separator);
143 }
144 printlnWithNoIndent(items[i]);
145 }
146 return this;
147 }
148
149 @NotNull
150 public Printer separated(Object separator, Collection<?> items) {
151 for (Iterator<?> iterator = items.iterator(); iterator.hasNext(); ) {
152 printlnWithNoIndent(iterator.next());
153 if (iterator.hasNext()) {
154 printlnWithNoIndent(separator);
155 }
156 }
157 return this;
158 }
159 }