/**
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.seed.core.internal.init;
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.AnsiOutputStream;
import org.seedstack.seed.ApplicationConfig;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
public class ConsoleManager {
private final PrintStream savedOut = System.out;
private final PrintStream savedErr = System.err;
private static class Holder {
private static final ConsoleManager INSTANCE = new ConsoleManager();
}
public static ConsoleManager get() {
return Holder.INSTANCE;
}
private ConsoleManager() {
// noop
}
public synchronized void install(ApplicationConfig.ColorOutput colorOutput) {
System.setOut(new PrintStream(wrapOutputStream(System.out, colorOutput)));
System.setErr(new PrintStream(wrapOutputStream(System.err, colorOutput)));
}
public synchronized void uninstall() {
System.setOut(savedOut);
System.setErr(savedErr);
}
private OutputStream wrapOutputStream(final OutputStream stream, ApplicationConfig.ColorOutput colorOutput) {
try {
if (colorOutput == ApplicationConfig.ColorOutput.PASSTHROUGH || Boolean.getBoolean("jansi.passthrough")) {
return stream;
} else if (colorOutput == ApplicationConfig.ColorOutput.DISABLE || Boolean.getBoolean("jansi.strip")) {
return basicOutput(stream);
} else if (colorOutput == ApplicationConfig.ColorOutput.ENABLE) {
return ansiOutput(stream);
} else if (colorOutput == ApplicationConfig.ColorOutput.AUTODETECT){
if (isXtermColor()) {
// enable color in recognized XTERM color modes
return ansiOutput(stream);
} else if (isIntelliJ()) {
// enable color under Intellij
return ansiOutput(stream);
} else {
// let Jansi handle other detection
return AnsiConsole.wrapOutputStream(stream);
}
}
// Fallback to stripping ANSI codes
return basicOutput(stream);
} catch (Throwable e) {
// If any error occurs, strip ANSI codes
return basicOutput(stream);
}
}
private FilterOutputStream basicOutput(OutputStream stream) {
return new AnsiOutputStream(stream);
}
private FilterOutputStream ansiOutput(OutputStream stream) {
return new ColorOutputStream(stream);
}
private boolean isXtermColor() {
String term = System.getenv("TERM");
return "xterm-256color".equals(term) ||
"xterm-color".equals(term) ||
"xterm".equals(term);
}
private boolean isIntelliJ() {
if (System.getProperty("java.class.path").contains("idea_rt.jar")) {
return true;
} else {
try {
Class.forName("com.intellij.rt.execution.application.AppMain");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
private static class ColorOutputStream extends FilterOutputStream {
private ColorOutputStream(OutputStream stream) {
super(stream);
}
@Override
public void close() throws IOException {
write(AnsiOutputStream.REST_CODE);
flush();
super.close();
}
}
}