View Javadoc

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 }