    001    /**
    002     *      jline - Java console input library
    003     *      Copyright (c) 2002, 2003, 2004, 2005, 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    }