package vnet.sms.common.shell.springshell.internal.commands;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Required;
import vnet.sms.common.shell.springshell.MethodTarget;
import vnet.sms.common.shell.springshell.command.CliCommand;
import vnet.sms.common.shell.springshell.command.CliOption;
import vnet.sms.common.shell.springshell.command.CommandMarker;
import vnet.sms.common.shell.springshell.internal.NaturalOrderComparator;
import vnet.sms.common.shell.springshell.internal.logging.HandlerUtils;
import vnet.sms.common.shell.springshell.internal.util.Assert;
import vnet.sms.common.shell.springshell.internal.util.StringUtils;
/**
* Provides a listing of commands known to the shell.
*
* @author Ben Alex
* @author Mark Pollack
* @author Jarred Li
*
*/
public class HelpCommands implements CommandMarker {
private static final Logger LOGGER = HandlerUtils
.getLogger(HelpCommands.class);
private static final Comparator<Object> COMPARATOR = new NaturalOrderComparator<Object>();
private CommandsRegistry commandsRegistry;
@CliCommand(value = "help", help = "list all commands usage")
public void obtainHelp(
@CliOption(key = { "", "command" }, optionContext = "availableCommands", help = "Command name to provide help for") final String buffer) {
doObtainHelp(buffer);
}
/**
* @param commandsRegistry
* the commandsRegistry to set
*/
@Required
public void setCommandsRegistry(final CommandsRegistry commandsRegistry) {
this.commandsRegistry = commandsRegistry;
}
private void doObtainHelp(
@CliOption(key = { "", "command" }, optionContext = "availableCommands", help = "Command name to provide help for") String buffer) {
if (buffer == null) {
buffer = "";
}
final StringBuilder sb = new StringBuilder();
// Figure out if there's a single command we can offer help for
final Collection<MethodTarget> matchingTargets = this.commandsRegistry
.findMatchingCommands(buffer, false, false);
if (matchingTargets.size() == 1) {
// Single command help
final MethodTarget methodTarget = matchingTargets.iterator().next();
// Argument conversion time
final Annotation[][] parameterAnnotations = methodTarget
.getMethod().getParameterAnnotations();
if (parameterAnnotations.length > 0) {
// Offer specified help
final CliCommand cmd = methodTarget.getMethod().getAnnotation(
CliCommand.class);
Assert.notNull(cmd, "CliCommand not found");
for (final String value : cmd.value()) {
sb.append("Keyword: ").append(value)
.append(StringUtils.LINE_SEPARATOR);
}
sb.append("Description: ").append(cmd.help())
.append(StringUtils.LINE_SEPARATOR);
for (final Annotation[] annotations : parameterAnnotations) {
CliOption cliOption = null;
for (final Annotation a : annotations) {
if (a instanceof CliOption) {
cliOption = (CliOption) a;
for (String key : cliOption.key()) {
if ("".equals(key)) {
key = "** default **";
}
sb.append(" Keyword: ")
.append(key)
.append(StringUtils.LINE_SEPARATOR);
}
sb.append(" Help: ")
.append(cliOption.help())
.append(StringUtils.LINE_SEPARATOR);
sb.append(" Mandatory: ")
.append(cliOption.mandatory())
.append(StringUtils.LINE_SEPARATOR);
sb.append(" Default if specified: '")
.append(cliOption.specifiedDefaultValue())
.append("'")
.append(StringUtils.LINE_SEPARATOR);
sb.append(" Default if unspecified: '")
.append(cliOption.unspecifiedDefaultValue())
.append("'")
.append(StringUtils.LINE_SEPARATOR);
sb.append(StringUtils.LINE_SEPARATOR);
}
}
Assert.notNull(
cliOption,
"CliOption not found for parameter '"
+ Arrays.toString(annotations) + "'");
}
}
// Only a single argument, so default to the normal help
// operation
}
final SortedSet<String> result = new TreeSet<String>(COMPARATOR);
for (final MethodTarget mt : matchingTargets) {
final CliCommand cmd = mt.getMethod().getAnnotation(
CliCommand.class);
if (cmd != null) {
for (final String value : cmd.value()) {
if ("".equals(cmd.help())) {
result.add("* " + value);
} else {
result.add("* " + value + " - " + cmd.help());
}
}
}
}
for (final String s : result) {
sb.append(s).append(StringUtils.LINE_SEPARATOR);
}
LOGGER.info(sb.toString());
LOGGER.warning("** Type 'hint' (without the quotes) and hit ENTER for step-by-step guidance **"
+ StringUtils.LINE_SEPARATOR);
}
}