1
2
3
4
5
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 }