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 }