ConsoleCompletor.java
package org.cyclopsgroup.jmxterm.cc;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.cyclopsgroup.jcli.jline.CliCompletor;
import org.cyclopsgroup.jmxterm.Command;
import org.jline.reader.Candidate;
import org.jline.reader.Completer;
import org.jline.reader.LineReader;
import org.jline.reader.ParsedLine;
import org.jline.reader.impl.completer.ArgumentCompleter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JLine completor that handles tab key
*
* @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
*/
public class ConsoleCompletor implements Completer {
private static final Logger LOG = LoggerFactory.getLogger(ConsoleCompletor.class);
private final CommandCenter commandCenter;
private final List<Candidate> commandNames;
public ConsoleCompletor(CommandCenter commandCenter) {
Validate.notNull(commandCenter, "Command center can't be NULL");
this.commandCenter = commandCenter;
List<String> commandNames = new ArrayList<String>(commandCenter.getCommandNames());
Collections.sort(commandNames);
this.commandNames = new ArrayList<Candidate>(commandNames.size());
for (String commandName : commandNames) {
this.commandNames.add(new Candidate(commandName));
}
}
@Override
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
try {
String buffer = line.line();
if (StringUtils.isEmpty(buffer) || buffer.indexOf(' ') == -1) {
completeCommandName(buffer, candidates);
}
int separatorPos = buffer.indexOf(' ');
String commandName = buffer.substring(0, separatorPos);
if (LOG.isDebugEnabled()) {
LOG.debug("Command name is [" + commandName + "]");
}
String commandArguments = buffer.substring(separatorPos + 1);
commandArguments.replaceFirst("^\\s*", "");
if (LOG.isDebugEnabled()) {
LOG.debug("Analyzing commmand arguments [" + commandArguments + "]");
}
Command cmd = commandCenter.commandFactory.createCommand(commandName);
cmd.setSession(commandCenter.session);
CliCompletor commandCompletor = new CliCompletor(cmd, commandCenter.argTokenizer);
int position = line.cursor();
commandCompletor.complete(
reader,
new ArgumentCompleter.ArgumentLine(commandArguments, position - separatorPos),
candidates);
} catch (RuntimeException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Couldn't complete input", e);
}
}
}
private void completeCommandName(String buf, List<Candidate> candidates) {
if (buf == null) {
// Nothing is there
candidates.addAll(commandNames);
} else if (buf.indexOf(' ') == -1) {
// Partial one word
List<Candidate> matchedNames = new ArrayList<Candidate>();
for (Candidate commandName : commandNames) {
if (commandName.value().startsWith(buf)) {
matchedNames.add(commandName);
}
}
candidates.addAll(matchedNames);
} else {
throw new IllegalStateException("Invalid state");
}
}
}