View Javadoc

1   /*
2    * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
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   package jline;
8   
9   import java.io.*;
10  
11  /***
12   *  Representation of the input terminal for a platform. Handles
13   *  any initialization that the platform may need to perform
14   *  in order to allow the {@link ConsoleReader} to correctly handle
15   *  input.
16   *
17   *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
18   */
19  public abstract class Terminal implements ConsoleOperations {
20      private static Terminal term;
21  
22      /***
23       *  @see #setupTerminal
24       */
25      public static Terminal getTerminal() {
26          return setupTerminal();
27      }
28  
29      /*** 
30       *  Reset the current terminal to null. 
31       */
32      public static void resetTerminal() {
33          term = null;
34      }
35  
36      /***
37       *  <p>Configure and return the {@link Terminal} instance for the
38       *  current platform. This will initialize any system settings
39       *  that are required for the console to be able to handle
40       *  input correctly, such as setting tabtop, buffered input, and
41       *  character echo.</p>
42       *
43       *  <p>This class will use the Terminal implementation specified in the
44       *  <em>jline.terminal</em> system property, or, if it is unset, by
45       *  detecting the operating system from the <em>os.name</em>
46       *  system property and instantiating either the
47       *  {@link WindowsTerminalTest} or {@link UnixTerminal}.
48       *
49       *  @see #initializeTerminal
50       */
51      public static synchronized Terminal setupTerminal() {
52          if (term != null) {
53              return term;
54          }
55  
56          final Terminal t;
57  
58          String os = System.getProperty("os.name").toLowerCase();
59          String termProp = System.getProperty("jline.terminal");
60  
61          if ((termProp != null) && (termProp.length() > 0)) {
62              try {
63                  t = (Terminal) Class.forName(termProp).newInstance();
64              } catch (Exception e) {
65                  throw (IllegalArgumentException) new IllegalArgumentException(e
66                      .toString()).fillInStackTrace();
67              }
68          } else if (os.indexOf("windows") != -1) {
69              t = new WindowsTerminal();
70          } else {
71              t = new UnixTerminal();
72          }
73  
74          try {
75              t.initializeTerminal();
76          } catch (Exception e) {
77              e.printStackTrace();
78  
79              return term = new UnsupportedTerminal();
80          }
81  
82          return term = t;
83      }
84  
85      /***
86       *  Returns true if the current console supports ANSI
87       *  codes.
88       */
89      public boolean isANSISupported() {
90          return true;
91      }
92  
93      /***
94       *  Read a single character from the input stream. This might
95       *  enable a terminal implementation to better handle nuances of
96       *  the console.
97       */
98      public int readCharacter(final InputStream in) throws IOException {
99          return in.read();
100     }
101 
102     /***
103      *  Reads a virtual key from the console. Typically, this will
104      *  just be the raw character that was entered, but in some cases,
105      *  multiple input keys will need to be translated into a single
106      *  virtual key.
107      *
108      *  @param  in  the InputStream to read from
109      *  @return  the virtual key (e.g., {@link ConsoleOperations#VK_UP})
110      */
111     public int readVirtualKey(InputStream in) throws IOException {
112         return readCharacter(in);
113     }
114 
115     /***
116      *  Initialize any system settings
117      *  that are required for the console to be able to handle
118      *  input correctly, such as setting tabtop, buffered input, and
119      *  character echo.
120      */
121     public abstract void initializeTerminal() throws Exception;
122 
123     /***
124      *  Returns the current width of the terminal (in characters)
125      */
126     public abstract int getTerminalWidth();
127 
128     /***
129      *  Returns the current height of the terminal (in lines)
130      */
131     public abstract int getTerminalHeight();
132 
133     /***
134      *  Returns true if this terminal is capable of initializing the
135      *  terminal to use jline.
136      */
137     public abstract boolean isSupported();
138 
139     /***
140      *  Returns true if the terminal will echo all characters type.
141      */
142     public abstract boolean getEcho();
143 
144     /***
145      *  Invokes before the console reads a line with the prompt and mask.
146      */
147     public void beforeReadLine(ConsoleReader reader, String prompt,
148                                Character mask) {
149     }
150 
151     /***
152      *  Invokes after the console reads a line with the prompt and mask.
153      */
154     public void afterReadLine(ConsoleReader reader, String prompt,
155                               Character mask) {
156     }
157 
158     /***
159      *  Returns false if character echoing is disabled.
160      */
161     public abstract boolean isEchoEnabled();
162 
163 
164     /***
165      *  Enable character echoing. This can be used to re-enable character
166      *  if the ConsoleReader is no longer being used.
167      */
168     public abstract void enableEcho();
169 
170 
171     /***
172      *  Disable character echoing. This can be used to manually re-enable
173      *  character if the ConsoleReader has been disabled.
174      */
175     public abstract void disableEcho();
176 
177     public InputStream getDefaultBindings() {
178         return Terminal.class.getResourceAsStream("keybindings.properties");
179     }
180 }