001 /** 002 * Copyright (C) 2009, Progress Software Corporation and/or its 003 * subsidiaries or affiliates. All rights reserved. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.fusesource.jansi; 019 020 import static org.fusesource.jansi.internal.CLibrary.CLIBRARY; 021 022 import java.io.FilterOutputStream; 023 import java.io.IOException; 024 import java.io.OutputStream; 025 import java.io.PrintStream; 026 027 import org.fusesource.jansi.internal.CLibrary; 028 029 /** 030 * Provides consistent access to an ANSI aware console PrintStream. 031 * 032 * @author <a href="http://hiramchirino.com">Hiram Chirino</a> 033 * @since 1.0 034 */ 035 public class AnsiConsole { 036 037 public static final PrintStream system_out = System.out; 038 public static final PrintStream out = new PrintStream(wrapOutputStream(system_out)); 039 040 public static final PrintStream system_err = System.err; 041 public static final PrintStream err = new PrintStream(wrapOutputStream(system_err)); 042 043 private static int installed; 044 045 public static OutputStream wrapOutputStream(final OutputStream stream) { 046 String os = System.getProperty("os.name"); 047 if( os.startsWith("Windows") ) { 048 049 // On windows we know the console does not interpret ANSI codes.. 050 try { 051 return new WindowsAnsiOutputStream(stream); 052 } catch (Throwable ignore) { 053 // this happens when JNA is not in the path.. or 054 // this happens when the stdout is being redirected to a file. 055 } 056 057 // Use the ANSIOutputStream to strip out the ANSI escape sequences. 058 return new AnsiOutputStream(stream); 059 } 060 061 // We must be on some unix variant.. 062 try { 063 // If we can detect that stdout is not a tty.. then setup 064 // to strip the ANSI sequences.. 065 int rc = CLIBRARY.isatty(CLibrary.STDOUT_FILENO); 066 if( rc==0 ) { 067 return new AnsiOutputStream(stream); 068 } 069 } catch (Throwable ignore) { 070 } 071 072 // By default we assume your Unix tty can handle ANSI codes. 073 // Just wrap it up so that when we get closed, we reset the 074 // attributes. 075 return new FilterOutputStream(stream) { 076 @Override 077 public void close() throws IOException { 078 write(AnsiOutputStream.REST_CODE); 079 flush(); 080 super.close(); 081 } 082 }; 083 } 084 085 /** 086 * If the standard out natively supports ANSI escape codes, then this just 087 * returns System.out, otherwise it will provide an ANSI aware PrintStream 088 * which strips out the ANSI escape sequences or which implement the escape 089 * sequences. 090 * 091 * @return a PrintStream which is ANSI aware. 092 */ 093 public static PrintStream out() { 094 return out; 095 } 096 097 /** 098 * If the standard out natively supports ANSI escape codes, then this just 099 * returns System.err, otherwise it will provide an ANSI aware PrintStream 100 * which strips out the ANSI escape sequences or which implement the escape 101 * sequences. 102 * 103 * @return a PrintStream which is ANSI aware. 104 */ 105 public static PrintStream err() { 106 return err; 107 } 108 109 /** 110 * Install Console.out to System.out. 111 */ 112 synchronized static public void systemInstall() { 113 installed++; 114 if( installed==1 ) { 115 System.setOut(out); 116 System.setErr(err); 117 } 118 } 119 120 /** 121 * undo a previous {@link #systemInstall()}. If {@link #systemInstall()} was called 122 * multiple times, it {@link #systemUninstall()} must call the same number of times before 123 * it is actually uninstalled. 124 */ 125 synchronized public static void systemUninstall() { 126 installed--; 127 if( installed==0 ) { 128 System.setOut(system_out); 129 System.setErr(system_err); 130 } 131 } 132 133 }