1 /**
2 * jline - Java console input library
3 * Copyright (c) 2002, 2003, 2004, 2005, Marc Prud'hommeaux <mwp1@cornell.edu>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer
15 * in the documentation and/or other materials provided with
16 * the distribution.
17 *
18 * Neither the name of JLine nor the names of its contributors
19 * may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
26 * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 * OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36 package jline;
37
38 import java.io.*;
39
40 /**
41 * Representation of the input terminal for a platform. Handles
42 * any initialization that the platform may need to perform
43 * in order to allow the {@link ConsoleReader} to correctly handle
44 * input.
45 *
46 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
47 */
48 public abstract class Terminal
49 implements ConsoleOperations
50 {
51 private static Terminal term;
52
53
54 /**
55 * @see #setupTerminal
56 */
57 public static Terminal getTerminal ()
58 {
59 return setupTerminal ();
60 }
61
62
63 /**
64 * <p>Configure and return the {@link Terminal} instance for the
65 * current platform. This will initialize any system settings
66 * that are required for the console to be able to handle
67 * input correctly, such as setting tabtop, buffered input, and
68 * character echo.</p>
69 *
70 * <p>This class will use the Terminal implementation specified in the
71 * <em>jline.terminal</em> system property, or, if it is unset, by
72 * detecting the operating system from the <em>os.name</em>
73 * system property and instantiateing either the
74 * {@link WindowsTerminal} or {@link UnixTerminal}.
75 *
76 * @see #initializeTerminal
77 */
78 public static synchronized Terminal setupTerminal ()
79 {
80 if (term != null)
81 return term;
82
83 final Terminal t;
84
85 String os = System.getProperty ("os.name").toLowerCase ();
86 String termProp = System.getProperty ("jline.terminal");
87 if (termProp != null && termProp.length () > 0)
88 {
89 try
90 {
91 t = (Terminal)Class.forName (termProp).newInstance ();
92 }
93 catch (Exception e)
94 {
95 throw (IllegalArgumentException)new IllegalArgumentException (
96 e.toString ()).fillInStackTrace ();
97 }
98 }
99 else if (os.indexOf ("windows") != -1)
100 {
101 t = new WindowsTerminal ();
102 }
103 else
104 {
105 t = new UnixTerminal ();
106 }
107
108 try
109 {
110 t.initializeTerminal ();
111 }
112 catch (Exception e)
113 {
114 e.printStackTrace ();
115 return term = new UnsupportedTerminal ();
116 }
117
118 return term = t;
119 }
120
121
122 /**
123 * Returns true if the current console supports ANSI
124 * codes.
125 */
126 public boolean isANSISupported ()
127 {
128 return true;
129 }
130
131
132 /**
133 * Read a single character from the input stream. This might
134 * enable a terminal implementation to better handle nuances of
135 * the console.
136 */
137 public int readCharacter (final InputStream in)
138 throws IOException
139 {
140 return in.read ();
141 }
142
143
144 /**
145 * Reads a virtual key from the console. Typically, this will
146 * just be the raw character that was entered, but in some cases,
147 * multiple input keys will need to be translated into a single
148 * virtual key.
149 *
150 * @param in the InputStream to read from
151 * @return the virtual key (e.g., {@link ConsoleOperations#VK_UP})
152 */
153 public int readVirtualKey (InputStream in)
154 throws IOException
155 {
156 return readCharacter (in);
157 }
158
159
160 /**
161 * Initialize any system settings
162 * that are required for the console to be able to handle
163 * input correctly, such as setting tabtop, buffered input, and
164 * character echo.
165 */
166 public abstract void initializeTerminal ()
167 throws Exception;
168
169
170 /**
171 * Returns the current width of the terminal (in characters)
172 */
173 public abstract int getTerminalWidth ();
174
175
176 /**
177 * Returns the current height of the terminal (in lines)
178 */
179 public abstract int getTerminalHeight ();
180
181
182 /**
183 * Returns true if this terminal is capable of initializing the
184 * terminal to use jline.
185 */
186 public abstract boolean isSupported ();
187
188
189 /**
190 * Returns true if the terminal will echo all characters type.
191 */
192 public abstract boolean getEcho ();
193 }