001 /* 002 * Copyright (c) 2002-2006, 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 * <p>Configure and return the {@link Terminal} instance for the 031 * current platform. This will initialize any system settings 032 * that are required for the console to be able to handle 033 * input correctly, such as setting tabtop, buffered input, and 034 * character echo.</p> 035 * 036 * <p>This class will use the Terminal implementation specified in the 037 * <em>jline.terminal</em> system property, or, if it is unset, by 038 * detecting the operating system from the <em>os.name</em> 039 * system property and instantiateing either the 040 * {@link WindowsTerminal} or {@link UnixTerminal}. 041 * 042 * @see #initializeTerminal 043 */ 044 public static synchronized Terminal setupTerminal() { 045 if (term != null) { 046 return term; 047 } 048 049 final Terminal t; 050 051 String os = System.getProperty("os.name").toLowerCase(); 052 String termProp = System.getProperty("jline.terminal"); 053 054 if ((termProp != null) && (termProp.length() > 0)) { 055 try { 056 t = (Terminal) Class.forName(termProp).newInstance(); 057 } catch (Exception e) { 058 throw (IllegalArgumentException) new IllegalArgumentException(e 059 .toString()) 060 .fillInStackTrace(); 061 } 062 } else if (os.indexOf("windows") != -1) { 063 t = new WindowsTerminal(); 064 } else { 065 t = new UnixTerminal(); 066 } 067 068 try { 069 t.initializeTerminal(); 070 } catch (Exception e) { 071 e.printStackTrace(); 072 073 return term = new UnsupportedTerminal(); 074 } 075 076 return term = t; 077 } 078 079 /** 080 * Returns true if the current console supports ANSI 081 * codes. 082 */ 083 public boolean isANSISupported() { 084 return true; 085 } 086 087 /** 088 * Read a single character from the input stream. This might 089 * enable a terminal implementation to better handle nuances of 090 * the console. 091 */ 092 public int readCharacter(final InputStream in) throws IOException { 093 return in.read(); 094 } 095 096 /** 097 * Reads a virtual key from the console. Typically, this will 098 * just be the raw character that was entered, but in some cases, 099 * multiple input keys will need to be translated into a single 100 * virtual key. 101 * 102 * @param in the InputStream to read from 103 * @return the virtual key (e.g., {@link ConsoleOperations#VK_UP}) 104 */ 105 public int readVirtualKey(InputStream in) throws IOException { 106 return readCharacter(in); 107 } 108 109 /** 110 * Initialize any system settings 111 * that are required for the console to be able to handle 112 * input correctly, such as setting tabtop, buffered input, and 113 * character echo. 114 */ 115 public abstract void initializeTerminal() throws Exception; 116 117 /** 118 * Returns the current width of the terminal (in characters) 119 */ 120 public abstract int getTerminalWidth(); 121 122 /** 123 * Returns the current height of the terminal (in lines) 124 */ 125 public abstract int getTerminalHeight(); 126 127 /** 128 * Returns true if this terminal is capable of initializing the 129 * terminal to use jline. 130 */ 131 public abstract boolean isSupported(); 132 133 /** 134 * Returns true if the terminal will echo all characters type. 135 */ 136 public abstract boolean getEcho(); 137 138 /** 139 * Invokes before the console reads a line with the prompt and mask. 140 */ 141 public void beforeReadLine(ConsoleReader reader, String prompt, 142 Character mask) { 143 } 144 145 /** 146 * Invokes after the console reads a line with the prompt and mask. 147 */ 148 public void afterReadLine(ConsoleReader reader, String prompt, 149 Character mask) { 150 } 151 }