001 /**
002 * jline - Java console input library
003 * Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or
007 * without modification, are permitted provided that the following
008 * conditions are met:
009 *
010 * Redistributions of source code must retain the above copyright
011 * notice, this list of conditions and the following disclaimer.
012 *
013 * Redistributions in binary form must reproduce the above copyright
014 * notice, this list of conditions and the following disclaimer
015 * in the documentation and/or other materials provided with
016 * the distribution.
017 *
018 * Neither the name of JLine nor the names of its contributors
019 * may be used to endorse or promote products derived from this
020 * software without specific prior written permission.
021 *
022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
025 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
026 * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
027 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
028 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
029 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
031 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
033 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
034 * OF THE POSSIBILITY OF SUCH DAMAGE.
035 */
036 package jline;
037
038 import java.io.*;
039
040 /**
041 * Representation of the input terminal for a platform. Handles
042 * any initialization that the platform may need to perform
043 * in order to allow the {@link ConsoleReader} to correctly handle
044 * input.
045 *
046 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
047 */
048 public abstract class Terminal
049 implements ConsoleOperations
050 {
051 private static Terminal term;
052
053
054 /**
055 * @see #setupTerminal
056 */
057 public static Terminal getTerminal ()
058 {
059 return setupTerminal ();
060 }
061
062
063 /**
064 * <p>Configure and return the {@link Terminal} instance for the
065 * current platform. This will initialize any system settings
066 * that are required for the console to be able to handle
067 * input correctly, such as setting tabtop, buffered input, and
068 * character echo.</p>
069 *
070 * <p>This class will use the Terminal implementation specified in the
071 * <em>jline.terminal</em> system property, or, if it is unset, by
072 * detecting the operating system from the <em>os.name</em>
073 * system property and instantiateing either the
074 * {@link WindowsTerminal} or {@link UnixTerminal}.
075 *
076 * @see #initializeTerminal
077 */
078 public static synchronized Terminal setupTerminal ()
079 {
080 if (term != null)
081 return term;
082
083 final Terminal t;
084
085 String os = System.getProperty ("os.name").toLowerCase ();
086 String termProp = System.getProperty ("jline.terminal");
087 if (termProp != null && termProp.length () > 0)
088 {
089 try
090 {
091 t = (Terminal)Class.forName (termProp).newInstance ();
092 }
093 catch (Exception e)
094 {
095 throw (IllegalArgumentException)new IllegalArgumentException (
096 e.toString ()).fillInStackTrace ();
097 }
098 }
099 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 }