package org.cyclopsgroup.jmxterm.cc; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cyclopsgroup.jcli.jline.CliCompletor; import org.cyclopsgroup.jmxterm.Command; import jline.console.completer.Completer; /** * 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 Log LOG = LogFactory.getLog( ConsoleCompletor.class ); private final CommandCenter commandCenter; private final List<String> commandNames; /** * Constructor using a command center * * @param commandCenter */ 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 = Collections.unmodifiableList( commandNames ); } /** * @inheritDoc */ @SuppressWarnings( { "unchecked", "rawtypes" } ) public int complete( String buffer, int position, List candidates ) { try { if ( StringUtils.isEmpty( buffer ) || buffer.indexOf( ' ' ) == -1 ) { return 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 ); return commandCompletor.complete( commandArguments, position - separatorPos, candidates ) + separatorPos + 1; } catch ( RuntimeException e ) { if ( LOG.isDebugEnabled() ) { LOG.debug( "Couldn't complete input", e ); } return position; } } private int completeCommandName( String buf, List<String> candidates ) { if ( buf == null ) { // Nothing is there candidates.addAll( commandNames ); } else if ( buf.indexOf( ' ' ) == -1 ) { // Partial one word List<String> matchedNames = new ArrayList<String>(); for ( String commandName : commandNames ) { if ( commandName.startsWith( buf ) ) { matchedNames.add( commandName ); } } candidates.addAll( matchedNames ); } else { throw new IllegalStateException( "Invalid state" ); } return 0; } }