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 //import com.sun.jmx.snmp.ThreadContext; 012 013 /** 014 * Representation of the input terminal for a platform. Handles 015 * any initialization that the platform may need to perform 016 * in order to allow the {@link ConsoleReader} to correctly handle 017 * input. 018 * 019 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> 020 */ 021 public abstract class Terminal implements ConsoleOperations { 022 private static Terminal term; 023 024 /** 025 * @see #setupTerminal 026 */ 027 public static Terminal getTerminal() { 028 return setupTerminal(); 029 } 030 031 /** 032 * Reset the current terminal to null. 033 */ 034 public static void resetTerminal() { 035 term = null; 036 } 037 038 /** 039 * <p>Configure and return the {@link Terminal} instance for the 040 * current platform. This will initialize any system settings 041 * that are required for the console to be able to handle 042 * input correctly, such as setting tabtop, buffered input, and 043 * character echo.</p> 044 * 045 * <p>This class will use the Terminal implementation specified in the 046 * <em>jline.terminal</em> system property, or, if it is unset, by 047 * detecting the operating system from the <em>os.name</em> 048 * system property and instantiating either the 049 * {@link WindowsTerminalTest} or {@link UnixTerminal}. 050 * 051 * @see #initializeTerminal 052 */ 053 public static synchronized Terminal setupTerminal() { 054 if (term != null) { 055 return term; 056 } 057 058 final Terminal t; 059 060 String os = System.getProperty("os.name").toLowerCase(); 061 String termProp = System.getProperty("jline.terminal"); 062 063 if ((termProp != null) && (termProp.length() > 0)) { 064 try { 065 t = (Terminal) Class.forName(termProp).newInstance(); 066 } catch (Exception e) { 067 throw (IllegalArgumentException) new IllegalArgumentException(e 068 .toString()).fillInStackTrace(); 069 } 070 } else if (os.indexOf("windows") != -1) { 071 t = new WindowsTerminal(); 072 } else { 073 t = new UnixTerminal(); 074 } 075 076 try { 077 t.initializeTerminal(); 078 } catch (Exception e) { 079 e.printStackTrace(); 080 081 return term = new UnsupportedTerminal(); 082 } 083 084 return term = t; 085 } 086 087 /** 088 * Returns true if the current console supports ANSI 089 * codes. 090 */ 091 public boolean isANSISupported() { 092 return true; 093 } 094 095 /** 096 * Read a single character from the input stream. This might 097 * enable a terminal implementation to better handle nuances of 098 * the console. 099 */ 100 public int readCharacter(final InputStream in) throws IOException { 101 return in.read(); 102 } 103 104 /** 105 * Reads a virtual key from the console. Typically, this will 106 * just be the raw character that was entered, but in some cases, 107 * multiple input keys will need to be translated into a single 108 * virtual key. 109 * 110 * @param in the InputStream to read from 111 * @return the virtual key (e.g., {@link ConsoleOperations#VK_UP}) 112 */ 113 public int readVirtualKey(InputStream in) throws IOException { 114 return readCharacter(in); 115 } 116 117 /** 118 * Initialize any system settings 119 * that are required for the console to be able to handle 120 * input correctly, such as setting tabtop, buffered input, and 121 * character echo. 122 */ 123 public abstract void initializeTerminal() throws Exception; 124 125 /** 126 * Returns the current width of the terminal (in characters) 127 */ 128 public abstract int getTerminalWidth(); 129 130 /** 131 * Returns the current height of the terminal (in lines) 132 */ 133 public abstract int getTerminalHeight(); 134 135 /** 136 * Returns true if this terminal is capable of initializing the 137 * terminal to use jline. 138 */ 139 public abstract boolean isSupported(); 140 141 /** 142 * Returns true if the terminal will echo all characters type. 143 */ 144 public abstract boolean getEcho(); 145 146 /** 147 * Invokes before the console reads a line with the prompt and mask. 148 */ 149 public void beforeReadLine(ConsoleReader reader, String prompt, 150 Character mask) { 151 } 152 153 /** 154 * Invokes after the console reads a line with the prompt and mask. 155 */ 156 public void afterReadLine(ConsoleReader reader, String prompt, 157 Character mask) { 158 } 159 160 /** 161 * Returns false if character echoing is disabled. 162 */ 163 public abstract boolean isEchoEnabled(); 164 165 166 /** 167 * Enable character echoing. This can be used to re-enable character 168 * if the ConsoleReader is no longer being used. 169 */ 170 public abstract void enableEcho(); 171 172 173 /** 174 * Disable character echoing. This can be used to manually re-enable 175 * character if the ConsoleReader has been disabled. 176 */ 177 public abstract void disableEcho(); 178 179 public InputStream getDefaultBindings() { 180 return getClass().getResourceAsStream("keybindings.properties"); 181 } 182 }