001 /*
002 * Copyright 2010-2013 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.jet.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 INDENTATION_UNIT = " ";
027 private static final String LINE_SEPARATOR = System.getProperty("line.separator");
028
029 private final Appendable out;
030 private final int maxBlankLines;
031
032 private String indent = "";
033 private int blankLineCountIncludingCurrent = 0;
034 private boolean withholdIndentOnce = false;
035
036 public Printer(@NotNull Appendable out) {
037 this(out, Integer.MAX_VALUE);
038 }
039
040 public Printer(@NotNull Appendable out, int maxBlankLines) {
041 this.out = out;
042 this.maxBlankLines = maxBlankLines;
043 }
044
045 private void append(Object o) {
046 try {
047 out.append(o.toString());
048 }
049 catch (IOException e) {
050 // Do nothing
051 }
052 }
053
054 @NotNull
055 public Printer println(Object... objects) {
056 print(objects);
057 printLineSeparator();
058
059 return this;
060 }
061
062 private void printLineSeparator() {
063 if (blankLineCountIncludingCurrent <= maxBlankLines) {
064 blankLineCountIncludingCurrent++;
065 append(LINE_SEPARATOR);
066 }
067 }
068
069 @NotNull
070 public Printer print(Object... objects) {
071 if (withholdIndentOnce) {
072 withholdIndentOnce = false;
073 }
074 else {
075 append(indent);
076 }
077 printWithNoIndent(objects);
078
079 return this;
080 }
081
082 @NotNull
083 public Printer printWithNoIndent(Object... objects) {
084 for (Object object : objects) {
085 blankLineCountIncludingCurrent = 0;
086 append(object);
087 }
088
089 return this;
090 }
091
092 @NotNull
093 public Printer withholdIndentOnce() {
094 withholdIndentOnce = true;
095 return this;
096 }
097
098 @NotNull
099 public Printer printlnWithNoIndent(Object... objects) {
100 printWithNoIndent(objects);
101 printLineSeparator();
102
103 return this;
104 }
105
106 @NotNull
107 public Printer pushIndent() {
108 indent += INDENTATION_UNIT;
109
110 return this;
111 }
112
113 @NotNull
114 public Printer popIndent() {
115 if (indent.length() < INDENTATION_UNIT.length()) {
116 throw new IllegalStateException("No indentation to pop");
117 }
118
119 indent = indent.substring(INDENTATION_UNIT.length());
120
121 return this;
122 }
123
124 @NotNull
125 public Printer separated(Object separator, Object... items) {
126 for (int i = 0; i < items.length; i++) {
127 if (i > 0) {
128 printlnWithNoIndent(separator);
129 }
130 printlnWithNoIndent(items[i]);
131 }
132 return this;
133 }
134
135 @NotNull
136 public Printer separated(Object separator, Collection<?> items) {
137 for (Iterator<?> iterator = items.iterator(); iterator.hasNext(); ) {
138 printlnWithNoIndent(iterator.next());
139 if (iterator.hasNext()) {
140 printlnWithNoIndent(separator);
141 }
142 }
143 return this;
144 }
145 }