001/* 002 * Copyright (C) 2009-2017 the original author(s). 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 */ 016package org.fusesource.jansi; 017 018import java.io.IOException; 019import java.io.OutputStream; 020import java.io.PrintStream; 021 022/** 023 * A PrintStream filtering to another PrintStream, without making any assumption about encoding. 024 * 025 * @author Hervé Boutemy 026 * @since 1.17 027 * @see #filter(int) 028 */ 029public class FilterPrintStream extends PrintStream 030{ 031 private static final String NEWLINE = System.getProperty("line.separator"); 032 protected final PrintStream ps; 033 034 public FilterPrintStream(PrintStream ps) 035 { 036 super( new OutputStream() { 037 038 @Override 039 public void write(int b) throws IOException { 040 throw new RuntimeException("Direct OutputStream use forbidden: must go through delegate PrintStream"); 041 } 042 043 }); 044 this.ps = ps; 045 } 046 047 /** 048 * Filter the content 049 * @param data character to filter 050 * @return <code>true</code> if the data is not filtered then has to be printed to delegate PrintStream 051 */ 052 protected boolean filter(int data) 053 { 054 return true; 055 } 056 057 @Override 058 public void write(int data) 059 { 060 if (filter(data)) 061 { 062 ps.write(data); 063 } 064 } 065 066 @Override 067 public void write(byte[] buf, int off, int len) 068 { 069 for (int i = 0; i < len; i++) 070 { 071 write(buf[off + i]); 072 } 073 } 074 075 @Override 076 public boolean checkError() 077 { 078 return super.checkError() || ps.checkError(); 079 } 080 081 @Override 082 public void close() 083 { 084 super.close(); 085 ps.close(); 086 } 087 088 @Override 089 public void flush() 090 { 091 super.flush(); 092 ps.flush(); 093 } 094 095 private void write(char buf[]) { 096 for (char c : buf) 097 { 098 if (filter(c)) 099 { 100 ps.print(c); 101 } 102 } 103 } 104 105 private void write(String s) { 106 char[] buf = new char[s.length()]; 107 s.getChars(0, s.length(), buf, 0); 108 write(buf); 109 } 110 111 private void newLine() { 112 write(NEWLINE); 113 } 114 115 /* Methods that do not terminate lines */ 116 117 @Override 118 public void print(boolean b) { 119 write(b ? "true" : "false"); 120 } 121 122 @Override 123 public void print(char c) { 124 write(String.valueOf(c)); 125 } 126 127 @Override 128 public void print(int i) { 129 write(String.valueOf(i)); 130 } 131 132 @Override 133 public void print(long l) { 134 write(String.valueOf(l)); 135 } 136 137 @Override 138 public void print(float f) { 139 write(String.valueOf(f)); 140 } 141 142 @Override 143 public void print(double d) { 144 write(String.valueOf(d)); 145 } 146 147 @Override 148 public void print(char s[]) { 149 write(s); 150 } 151 152 @Override 153 public void print(String s) { 154 if (s == null) { 155 s = "null"; 156 } 157 write(s); 158 } 159 160 @Override 161 public void print(Object obj) { 162 write(String.valueOf(obj)); 163 } 164 165 166 /* Methods that do terminate lines */ 167 168 @Override 169 public void println() { 170 newLine(); 171 } 172 173 @Override 174 public void println(boolean x) { 175 synchronized (this) { 176 print(x); 177 newLine(); 178 } 179 } 180 181 @Override 182 public void println(char x) { 183 synchronized (this) { 184 print(x); 185 newLine(); 186 } 187 } 188 189 @Override 190 public void println(int x) { 191 synchronized (this) { 192 print(x); 193 newLine(); 194 } 195 } 196 197 @Override 198 public void println(long x) { 199 synchronized (this) { 200 print(x); 201 newLine(); 202 } 203 } 204 205 @Override 206 public void println(float x) { 207 synchronized (this) { 208 print(x); 209 newLine(); 210 } 211 } 212 213 @Override 214 public void println(double x) { 215 synchronized (this) { 216 print(x); 217 newLine(); 218 } 219 } 220 221 @Override 222 public void println(char x[]) { 223 synchronized (this) { 224 print(x); 225 newLine(); 226 } 227 } 228 229 @Override 230 public void println(String x) { 231 synchronized (this) { 232 print(x); 233 newLine(); 234 } 235 } 236 237 @Override 238 public void println(Object x) { 239 String s = String.valueOf(x); 240 synchronized (this) { 241 print(s); 242 newLine(); 243 } 244 } 245}