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 }