1 /*
   2  * Copyright (c) 2002-2012, the original author or authors.
   3  *
   4  * This software is distributable under the BSD license. See the terms of the
   5  * BSD license in the documentation provided with this software.
   6  *
   7  * http://www.opensource.org/licenses/bsd-license.php
   8  */
   9 package jline;
  10 
  11 import jline.internal.Configuration;
  12 import org.fusesource.jansi.AnsiConsole;
  13 import org.fusesource.jansi.AnsiOutputStream;
  14 import org.fusesource.jansi.WindowsAnsiOutputStream;
  15 
  16 import java.io.ByteArrayOutputStream;
  17 import java.io.OutputStream;
  18 
  19 /**
  20  * ANSI-supported {@link WindowsTerminal}.
  21  *
  22  * @since 2.0
  23  */
  24 public class AnsiWindowsTerminal
  25     extends WindowsTerminal
  26 {
  27     private final boolean ansiSupported = detectAnsiSupport();
  28 
  29     @Override
  30     public OutputStream wrapOutIfNeeded(OutputStream out) {
  31         return wrapOutputStream(out);
  32     }
  33 
  34     /**
  35      * Returns an ansi output stream handler. We return whatever was
  36      * passed if we determine we cannot handle ansi based on Kernel32 calls.
  37      * 
  38      * @return an @{link AltWindowAnsiOutputStream} instance or the passed 
  39      * stream.
  40      */
  41     private static OutputStream wrapOutputStream(final OutputStream stream) {
  42         if (Configuration.isWindows()) {
  43             // On windows we know the console does not interpret ANSI codes..
  44             try {
  45                 return new WindowsAnsiOutputStream(stream);
  46             } catch (Throwable ignore) {
  47                 // this happens when JNA is not in the path.. or
  48                 // this happens when the stdout is being redirected to a file.
  49             }
  50             // Use the ANSIOutputStream to strip out the ANSI escape sequences.
  51             return new AnsiOutputStream(stream);
  52         }
  53         return stream;
  54     }
  55 
  56     private static boolean detectAnsiSupport() {
  57         OutputStream out = AnsiConsole.wrapOutputStream(new ByteArrayOutputStream());
  58         try {
  59             out.close();
  60         }
  61         catch (Exception e) {
  62             // ignore;
  63         }
  64         return out instanceof WindowsAnsiOutputStream;
  65     }
  66 
  67     public AnsiWindowsTerminal() throws Exception {
  68         super();
  69     }
  70 
  71     @Override
  72     public boolean isAnsiSupported() {
  73         return ansiSupported;
  74     }
  75 
  76     @Override
  77     public boolean hasWeirdWrap() {
  78         return false;
  79     }
  80 }