001 /* 002 * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved. 003 * 004 * This software is distributable under the BSD license. See the terms of the 005 * BSD license in the documentation provided with this software. 006 */ 007 package jline; 008 009 import java.io.*; 010 011 /** 012 * Representation of the input terminal for a platform. Handles 013 * any initialization that the platform may need to perform 014 * in order to allow the {@link ConsoleReader} to correctly handle 015 * input. 016 * 017 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> 018 */ 019 public abstract class Terminal implements ConsoleOperations { 020 private static Terminal term; 021 022 /** 023 * @see #setupTerminal 024 */ 025 public static Terminal getTerminal() { 026 return setupTerminal(); 027 } 028 029 /** 030 * Reset the current terminal to null. 031 */ 032 public static void resetTerminal() { 033 term = null; 034 } 035 036 /** 037 * <p>Configure and return the {@link Terminal} instance for the 038 * current platform. This will initialize any system settings 039 * that are required for the console to be able to handle 040 * input correctly, such as setting tabtop, buffered input, and 041 * character echo.</p> 042 * 043 * <p>This class will use the Terminal implementation specified in the 044 * <em>jline.terminal</em> system property, or, if it is unset, by 045 * detecting the operating system from the <em>os.name</em> 046 * system property and instantiating either the 047 * {@link WindowsTerminalTest} or {@link UnixTerminal}. 048 * 049 * @see #initializeTerminal 050 */ 051 public static synchronized Terminal setupTerminal() { 052 if (term != null) { 053 return term; 054 } 055 056 final Terminal t; 057 058 String os = System.getProperty("os.name").toLowerCase(); 059 String termProp = System.getProperty("jline.terminal"); 060 061 if ((termProp != null) && (termProp.length() > 0)) { 062 try { 063 t = (Terminal) Class.forName(termProp).newInstance(); 064 } catch (Exception e) { 065 throw (IllegalArgumentException) new IllegalArgumentException(e 066 .toString()).fillInStackTrace(); 067 } 068 } else if (os.indexOf("windows") != -1) { 069 t = new WindowsTerminal(); 070 } else { 071 t = new UnixTerminal(); 072 } 073 074 try { 075 t.initializeTerminal(); 076 } catch (Exception e) { 077 e.printStackTrace(); 078 079 return term = new UnsupportedTerminal(); 080 } 081 082 return term = t; 083 } 084 085 /** 086 * Returns true if the current console supports ANSI 087 * codes. 088 */ 089 public boolean isANSISupported() { 090 return true; 091 } 092 093 /** 094 * Read a single character from the input stream. This might 095 * enable a terminal implementation to better handle nuances of 096 * the console. 097 */ 098 public int readCharacter(final InputStream in) throws IOException { 099 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 }