1 package org.cyclopsgroup.jmxterm.cc;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6
7 import org.apache.commons.lang3.StringUtils;
8 import org.apache.commons.lang3.Validate;
9 import org.cyclopsgroup.jcli.jline.CliCompletor;
10 import org.cyclopsgroup.jmxterm.Command;
11 import org.jline.reader.Candidate;
12 import org.jline.reader.Completer;
13 import org.jline.reader.LineReader;
14 import org.jline.reader.ParsedLine;
15 import org.jline.reader.impl.completer.ArgumentCompleter;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19
20
21
22
23
24 public class ConsoleCompletor implements Completer {
25 private static final Logger LOG = LoggerFactory.getLogger(ConsoleCompletor.class);
26
27 private final CommandCenter commandCenter;
28
29 private final List<Candidate> commandNames;
30
31 public ConsoleCompletor(CommandCenter commandCenter) {
32 Validate.notNull(commandCenter, "Command center can't be NULL");
33 this.commandCenter = commandCenter;
34 List<String> commandNames = new ArrayList<String>(commandCenter.getCommandNames());
35 Collections.sort(commandNames);
36 this.commandNames = new ArrayList<Candidate>(commandNames.size());
37 for (String commandName : commandNames) {
38 this.commandNames.add(new Candidate(commandName));
39 }
40 }
41
42 @Override
43 public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
44 try {
45 String buffer = line.line();
46 if (StringUtils.isEmpty(buffer) || buffer.indexOf(' ') == -1) {
47 completeCommandName(buffer, candidates);
48 }
49 int separatorPos = buffer.indexOf(' ');
50 String commandName = buffer.substring(0, separatorPos);
51 if (LOG.isDebugEnabled()) {
52 LOG.debug("Command name is [" + commandName + "]");
53 }
54 String commandArguments = buffer.substring(separatorPos + 1);
55 commandArguments.replaceFirst("^\\s*", "");
56 if (LOG.isDebugEnabled()) {
57 LOG.debug("Analyzing commmand arguments [" + commandArguments + "]");
58 }
59 Command cmd = commandCenter.commandFactory.createCommand(commandName);
60 cmd.setSession(commandCenter.session);
61 CliCompletor commandCompletor = new CliCompletor(cmd, commandCenter.argTokenizer);
62 int position = line.cursor();
63 commandCompletor.complete(reader,
64 new ArgumentCompleter.ArgumentLine(commandArguments, position - separatorPos),
65 candidates);
66 } catch (RuntimeException e) {
67 if (LOG.isDebugEnabled()) {
68 LOG.debug("Couldn't complete input", e);
69 }
70 }
71 }
72
73 private void completeCommandName(String buf, List<Candidate> candidates) {
74 if (buf == null) {
75
76 candidates.addAll(commandNames);
77 } else if (buf.indexOf(' ') == -1) {
78
79 List<Candidate> matchedNames = new ArrayList<Candidate>();
80 for (Candidate commandName : commandNames) {
81 if (commandName.value().startsWith(buf)) {
82 matchedNames.add(commandName);
83 }
84 }
85 candidates.addAll(matchedNames);
86 } else {
87 throw new IllegalStateException("Invalid state");
88 }
89 }
90 }