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 }