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/ZemucanCompletionHandler.java $: 28 */ 29 package name.angoca.zemucan.ui.impl.jline; 30 31 import java.io.IOException; 32 import java.text.MessageFormat; 33 import java.util.Collection; 34 import java.util.List; 35 36 import jline.CompletionHandler; 37 import jline.ConsoleReader; 38 import name.angoca.zemucan.tools.messages.jline.Messages; 39 40 /** 41 * This is the implementation of a JLine CompletionHandler. This class is almost 42 * the same implementation of CandidateListCompletionHandler but it does not 43 * process the candidates, just show them. 44 * <p> 45 * This class is completely based in CandidateListCompletionHandler and that 46 * code has a BSD license. 47 * <p> 48 * <b>Control Version</b> 49 * <p> 50 * <ul> 51 * <li>1.0.0 Class creation.</li> 52 * </ul> 53 * 54 * @author Andres Gomez Casanova <a 55 * href="mailto:a n g o c a at y a h o o dot c o m" >(AngocA)</a> 56 * @version 1.0.0 2010-05-15 57 */ 58 public final class ZemucanCompletionHandler implements CompletionHandler { 59 60 /** 61 * Print out the candidates. If the size of the candidates is greater than 62 * the {@link getAutoprintThreshhold}, they prompt with a warning. 63 * 64 * @param reader 65 * Console that prints out the output. 66 * @param candidates 67 * List of candidates to print. 68 * @throws IOException 69 * If there is a problem writing the output. 70 */ 71 private static void printCandidates(final ConsoleReader/* ! */reader, 72 final Collection<Object>/* ! */candidates) throws IOException { 73 assert reader != null; 74 assert candidates != null; 75 76 boolean printCandidates = false; 77 78 // Prints a message that indicates that there are a lot of 79 // candidates, and asks if the user wants to see all of them. 80 if (candidates.size() > reader.getAutoprintThreshhold()) { 81 // Asks the user. 82 reader.printNewline(); 83 reader.printString(MessageFormat.format( 84 Messages.getString("SACompletionHandler" 85 + ".DisplayCandidates"), 86 new Object[] { new Integer(candidates.size()) }) 87 + " "); 88 89 reader.flushConsole(); 90 91 final String noOpt = Messages 92 .getString("SACompletionHandler.DisplayCandidatesYes"); 93 final String yesOpt = Messages 94 .getString("SACompletionHandler.DisplayCandidatesNo"); 95 96 // Process the user's answer. 97 int c = -1; 98 boolean exit = false; 99 do { 100 // Read the user's answer. 101 c = reader.readCharacter(new char[] { yesOpt.charAt(0), 102 noOpt.charAt(0) }); 103 104 // Not show options. 105 if (noOpt.startsWith(new String(new char[] { (char) c }))) { 106 reader.printNewline(); 107 exit = true; 108 } else 109 // Show options 110 if (yesOpt.startsWith(new String(new char[] { (char) c }))) { 111 printCandidates = true; 112 } else { 113 // Invalid option taped. 114 reader.beep(); 115 } 116 117 } while ((c != -1) && !exit && !printCandidates); 118 119 } else { 120 printCandidates = true; 121 } 122 123 // If the candidates have to be printed. 124 if (printCandidates) { 125 reader.printNewline(); 126 reader.printColumns(candidates); 127 } 128 } 129 130 /** 131 * Prints the command line and position the cursor. 132 * 133 * @param reader 134 * Console that prints the output. 135 * @param value 136 * New value in the command line. 137 * @param offset 138 * cursor position. 139 * @throws IOException 140 * if problem while moving back. 141 */ 142 private static void setBuffer(final ConsoleReader/* ! */reader, 143 final String/* ! */value, final int offset) throws IOException { 144 assert reader != null; 145 assert value != null; 146 147 while ((reader.getCursorBuffer().cursor > offset) && reader.backspace()) { 148 // Nothing. 149 System.currentTimeMillis(); 150 } 151 152 // Prints the line and the cursor in the right position. 153 reader.putString(value); 154 reader.setCursorPosition(offset + value.length()); 155 } 156 157 /** 158 * Completes a phrase. This implementation modifies the normal behavior of 159 * this interface. The first candidate is the phrase to add in the command 160 * line, the others, if they exists are the real candidates. 161 * 162 * @see jline.CompletionHandler#complete(jline.ConsoleReader, 163 * java.util.List, int) 164 */ 165 @SuppressWarnings("unchecked") 166 @Override 167 public boolean complete(final ConsoleReader/* ! */reader, 168 @SuppressWarnings("rawtypes") final List/* <!>! */candidates, final int position) 169 throws IOException { 170 assert reader != null; 171 assert candidates != null; 172 boolean assertsEnabled = false; 173 // Intentional side-effect! 174 assert assertsEnabled = true; 175 if (assertsEnabled) { 176 for (final Object object : candidates) { 177 assert object != null; 178 assert object instanceof String; 179 } 180 } 181 assert candidates.size() >= 1; 182 183 final String newPhrase = candidates.remove(0).toString(); 184 ZemucanCompletionHandler.setBuffer(reader, newPhrase, position); 185 186 ZemucanCompletionHandler.printCandidates(reader, candidates); 187 188 // Redraws the current console buffer. 189 reader.drawLine(); 190 191 return true; 192 } 193 }