1 /* 2 * Zemucan: A Syntax Assistant for DB2 3 * Copyright (C) 2009, 2010 Andres Gomez Casanova 4 * 5 * This file is part of Zemucan. 6 * 7 * Zemucan is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Zemucan is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library; if not, see <http://www.gnu.org/licenses/>. 19 * 20 * Contact: 21 * a n g o c a at y a h o o dot c o m 22 * Cra. 45 No 61 - 31, Bogota, Colombia. 23 * 24 * Author: $LastChangedBy: angoca $: 25 * Date: $LastChangedDate: 2011-03-06 23:10:20 -0500 (dom, 06 mar 2011) $: 26 * Revision: $LastChangedRevision: 1917 $: 27 * URL: $HeadURL: https://zemucan.svn.sourceforge.net/svnroot/zemucan/branches/zemucan_v1/source-code/uiImplJLine/src/main/java/name/angoca/zemucan/ui/impl/jline/JlineInputReader.java $: 28 */ 29 package name.angoca.zemucan.ui.impl.jline; 30 31 import java.awt.event.ActionEvent; 32 import java.awt.event.ActionListener; 33 import java.io.IOException; 34 35 import jline.ConsoleReader; 36 import name.angoca.zemucan.tools.configurator.Configurator; 37 import name.angoca.zemucan.tools.messages.jline.Messages; 38 import name.angoca.zemucan.ui.api.AbstractUIException; 39 import name.angoca.zemucan.ui.api.InputReader; 40 import name.angoca.zemucan.ui.api.InputReaderException; 41 42 import org.slf4j.Logger; 43 import org.slf4j.LoggerFactory; 44 45 /** 46 * Implementation of the input reader using JLine. 47 * <p> 48 * <b>Control Version</b> 49 * <p> 50 * <ul> 51 * <li>0.0.1 Class creation.</li> 52 * <li>0.0.2 'this' to access attributes.</li> 53 * <li>0.0.3 No override.</li> 54 * <li>0.0.4 final.</li> 55 * <li>1.0.0 Moved to version 1.</li> 56 * <li>1.0.1 Validate console.</li> 57 * <li>1.1.0 Exception hierarchy changed.</li> 58 * <li>1.1.1 try catch modified.</li> 59 * <li>1.1.2 Asserts.</li> 60 * <li>1.1.3 Extra line deleted.</li> 61 * <li>1.1.4 Completor renamed.</li> 62 * <li>1.1.5 Completion Handler.</li> 63 * <li>1.1.6 Key binding.</li> 64 * </ul> 65 * 66 * @author Andres Gomez Casanova <a 67 * href="mailto:a n g o c a at y a h o o dot c o m" >(AngocA)</a> 68 * @version 1.1.6 2010-05-24 69 */ 70 public final class JlineInputReader implements InputReader { 71 /** 72 * Logger. 73 */ 74 private static final Logger LOGGER = LoggerFactory 75 .getLogger(JlineInputReader.class); 76 77 /** 78 * Prompt to show in the console. 79 */ 80 private final transient String prompt; 81 /** 82 * JLine console reader. 83 */ 84 private final transient ConsoleReader reader; 85 86 /** 87 * Constructor that flushes the stream. 88 * 89 * @param consolePrompt 90 * Prompt to show in each line of the console. 91 * @throws InputReaderException 92 * If there is a problem flushing the stream. 93 */ 94 public JlineInputReader(final String/* ! */consolePrompt) 95 throws InputReaderException { 96 assert consolePrompt != null; 97 98 this.prompt = consolePrompt; 99 try { 100 this.reader = new ConsoleReader(); 101 } catch (final IOException exception) { 102 throw new InputReaderException(exception); 103 } 104 105 if (this.reader != null) { 106 this.configureConsoleReader(); 107 } 108 } 109 110 /** 111 * Configures the console reader. 112 */ 113 private void configureConsoleReader() { 114 // Normally, each time a tab is pressed, a beep sounds. It 115 // blocks that. 116 this.reader.setBellEnabled(false); 117 118 // Adds the completor that calls the application's core. 119 this.reader.addCompletor(new ZemucanCompletor()); 120 121 // Sets a handler that does not analyzes the candidates, it just 122 // prints them. 123 this.reader.setCompletionHandler(new ZemucanCompletionHandler()); 124 125 // Maximum quantity of candidates to show in an assistance. 126 int threshold = -1; 127 try { 128 threshold = Integer 129 .parseInt(Configurator 130 .getInstance() 131 .getProperty( 132 ImplementationJlineInterfaceController.AUTO_PRINT_THRESHOLD_KEY)); 133 134 } catch (final NumberFormatException exception) { 135 threshold = ImplementationJlineInterfaceController.AUTO_PRINT_THRESHOLD_VALUE; 136 JlineInputReader.LOGGER.info(Messages.getString("JlineInputReader" 137 + ".InvalidThresholdNumber"), threshold); 138 } 139 this.reader.setAutoprintThreshhold(threshold); 140 141 // Configures the Ctrl + c key to exit from the application. 142 this.reader.addTriggeredAction((char) 3, 143 /** 144 * This class is the listener to exit from the application when the Ctrl 145 * + c keys are pressed. 146 * <p> 147 * This only works for Windows systems. In Linux, it already exists. 148 * 149 * @author Andres Gomez Casanova <a 150 * href="mailto:a n g o c a at y a h o o dot c o m" 151 * >(AngocA)</a> 152 */ 153 new ActionListener() { 154 /* 155 * (non-Javadoc) 156 * 157 * @see 158 * java.awt.event.ActionListener#actionPerformed(java.awt.event. 159 * ActionEvent) 160 */ 161 @Override 162 public void actionPerformed(final ActionEvent e) { 163 System.exit(0); 164 } 165 }); 166 } 167 168 /* 169 * (non-Javadoc) 170 * 171 * @see name.angoca.zemucan.ui.api.InputReader#readString() 172 */ 173 @Override 174 public String/* ! */readString() throws AbstractUIException { 175 176 String ret = ""; //$NON-NLS-1$ 177 try { 178 ret = this.reader.readLine(this.prompt); 179 } catch (final IOException exception) { 180 throw new InputReaderException(exception); 181 } 182 if (ret == null) { 183 throw new ConsoleProblemException(); 184 } 185 return ret; 186 } 187 }