001    /**
002     *      jline - Java console input library
003     *      Copyright (c) 2002,2003 Marc Prud'hommeaux mwp1@cornell.edu
004     *      
005     *      This library is free software; you can redistribute it and/or
006     *      modify it under the terms of the GNU Lesser General Public
007     *      License as published by the Free Software Foundation; either
008     *      version 2.1 of the License, or (at your option) any later version.
009     *      
010     *      This library is distributed in the hope that it will be useful,
011     *      but WITHOUT ANY WARRANTY; without even the implied warranty of
012     *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     *      Lesser General Public License for more details.
014     *      
015     *      You should have received a copy of the GNU Lesser General Public
016     *      License along with this library; if not, write to the Free Software
017     *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018     */
019    package jline;
020    
021    import java.io.*;
022    import java.util.*;
023    
024    
025    /**
026     *  Representation of the input terminal for a platform. Handles
027     *      any initialization that the platform may need to perform
028     *      in order to allow the {@link ConsoleReader} to correctly handle
029     *      input.
030     *
031     *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
032     */
033    public abstract class Terminal
034    {
035            private static Terminal term;
036    
037    
038            /**
039             *  @see #setupTerminal
040             */
041            public static Terminal getTerminal ()
042            {
043                    return setupTerminal ();
044            }
045    
046    
047            /**
048             *  <p>Configure and return the {@link Terminal} instance for the
049             *  current platform. This will initialize any system settings
050             *  that are required for the console to be able to handle
051             *  input correctly, such as setting tabtop, buffered input, and
052             *  character echo.</p>
053             *
054             *  <p>This class will use the Terminal implementation specified in the
055             *  <em>jline.terminal</em> system property, or, if it is unset, by
056             *  detecting the operating system from the <em>os.name</em>
057             *  system property and instantiateing either the
058             *  {@link WindowsTerminal} or {@link UnixTerminal}.
059             *
060             *  @see #initializeTerminal
061             */
062            public static synchronized Terminal setupTerminal ()
063            {
064                    if (term != null)
065                            return term;
066    
067                    final Terminal t;
068    
069                    String os = System.getProperty ("os.name").toLowerCase ();
070                    String termProp = System.getProperty ("jline.terminal");
071                    if (termProp != null && termProp.length () > 0)
072                    {
073                            try
074                            {
075                                    t = (Terminal)Class.forName (termProp).newInstance ();
076                            }
077                            catch (Exception e)
078                            {
079                                    throw (IllegalArgumentException)new IllegalArgumentException (
080                                            e.toString ()).fillInStackTrace ();
081                            }
082                    }
083                    else if (os.indexOf ("windows") != -1)
084                    {
085                            t = new WindowsTerminal ();
086                    }
087                    else
088                    {
089                            t = new UnixTerminal ();
090                    }
091    
092                    try
093                    {
094                            t.initializeTerminal ();
095                    }
096                    catch (Exception e)
097                    {
098                            e.printStackTrace ();
099                            return term = new UnsupportedTerminal ();
100                    }
101    
102                    return term = t;
103            }
104    
105    
106            /**
107             *  Read a single character from the input stream. This might
108             *  enable a terminal implementation to better handle nuances of
109             *  the console.
110             */
111            public int readCharacter (final InputStream in)
112                    throws IOException
113            {
114                    return in.read ();
115            }
116    
117    
118            /**
119             *  Initialize any system settings
120             *  that are required for the console to be able to handle
121             *  input correctly, such as setting tabtop, buffered input, and
122             *  character echo.
123             */
124            public abstract void initializeTerminal ()
125                    throws Exception;
126    
127    
128            /**
129             *  Returns the current width of the terminal (in characters)
130             */
131            public abstract int getTerminalWidth ();
132    
133    
134            /**
135             *  Returns the current height of the terminal (in lines)
136             */
137            public abstract int getTerminalHeight ();
138    
139    
140            /**
141             *  Returns true if this terminal is capable of initializing the
142             *  terminal to use jline.
143             */
144            public abstract boolean isSupported ();
145    
146    
147            /**
148             *  Returns true if the terminal will echo all characters type.
149             */
150            public abstract boolean getEcho ();
151    }