Skip to content

Commit

Permalink
FORGE-1114: Support for multi-step wizards in Shell
Browse files Browse the repository at this point in the history
  • Loading branch information
gastaldi committed Aug 20, 2013
1 parent a397bec commit 565a831
Show file tree
Hide file tree
Showing 12 changed files with 480 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@
import java.util.Map;

import org.jboss.forge.addon.convert.ConverterFactory;
import org.jboss.forge.addon.shell.aesh.AbstractShellCommand;
import org.jboss.forge.addon.shell.aesh.CommandLineUtil;
import org.jboss.forge.addon.shell.aesh.ShellCommand;
import org.jboss.forge.addon.shell.aesh.ShellSingleCommand;
import org.jboss.forge.addon.shell.aesh.ShellWizard;
import org.jboss.forge.addon.shell.ui.ShellContext;
import org.jboss.forge.addon.ui.UICommand;
import org.jboss.forge.addon.ui.util.Commands;
import org.jboss.forge.addon.ui.wizard.UIWizard;
import org.jboss.forge.addon.ui.wizard.UIWizardStep;
import org.jboss.forge.furnace.addons.AddonRegistry;
import org.jboss.forge.furnace.services.Imported;

/**
* Manages {@link ShellCommand} objects
* Manages {@link ShellSingleCommand} objects
*
* @author <a href="ggastald@redhat.com">George Gastaldi</a>
*/
Expand All @@ -30,13 +34,26 @@ public CommandManager(AddonRegistry addonRegistry)
this.addonRegistry = addonRegistry;
}

public Map<String, ShellCommand> getEnabledShellCommands(ShellContext shellContext)
public UIWizardStep lookup(Class<? extends UIWizardStep> type)
{
Map<String, ShellCommand> commands = new HashMap<String, ShellCommand>();
return addonRegistry.getServices(type).get();
}

public Map<String, AbstractShellCommand> getEnabledShellCommands(ShellContext shellContext)
{
Map<String, AbstractShellCommand> commands = new HashMap<String, AbstractShellCommand>();
CommandLineUtil cmdLineUtil = getCommandLineUtil();
for (UICommand cmd : Commands.getEnabledCommands(getAllCommands(), shellContext))
{
ShellCommand shellCommand = new ShellCommand(cmd, shellContext, cmdLineUtil);
AbstractShellCommand shellCommand;
if (cmd instanceof UIWizard)
{
shellCommand = new ShellWizard((UIWizard) cmd, shellContext, cmdLineUtil, this);
}
else
{
shellCommand = new ShellSingleCommand(cmd, shellContext, cmdLineUtil);
}
commands.put(shellCommand.getName(), shellCommand);
}
return commands;
Expand Down
24 changes: 12 additions & 12 deletions shell/impl/src/main/java/org/jboss/forge/addon/shell/ShellImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
import org.jboss.aesh.terminal.TerminalCharacter;
import org.jboss.forge.addon.convert.ConverterFactory;
import org.jboss.forge.addon.resource.FileResource;
import org.jboss.forge.addon.shell.aesh.AbstractShellCommand;
import org.jboss.forge.addon.shell.aesh.ForgeConsoleCallback;
import org.jboss.forge.addon.shell.aesh.ShellCommand;
import org.jboss.forge.addon.shell.aesh.completion.ForgeCompletion;
import org.jboss.forge.addon.shell.ui.ShellContext;
import org.jboss.forge.addon.shell.ui.ShellContextImpl;
Expand Down Expand Up @@ -150,15 +150,15 @@ private Prompt createInitialPrompt()
return new Prompt(chars);
}

public Map<String, ShellCommand> getEnabledShellCommands(ShellContext context)
public Map<String, AbstractShellCommand> getEnabledShellCommands(ShellContext context)
{
return commandManager.getEnabledShellCommands(context);
}

/**
* Used in {@link ForgeCompletion} and {@link ForgeConsoleCallback}
*/
public ShellCommand findCommand(ShellContext shellContext, String line)
public AbstractShellCommand findCommand(ShellContext shellContext, String line)
{
String[] tokens = line.split(" ");
if (tokens.length >= 1)
Expand All @@ -168,16 +168,16 @@ public ShellCommand findCommand(ShellContext shellContext, String line)
return null;
}

public Collection<ShellCommand> findMatchingCommands(ShellContext shellContext, String line)
public Collection<AbstractShellCommand> findMatchingCommands(ShellContext shellContext, String line)
{
Set<ShellCommand> result = new TreeSet<ShellCommand>();
Set<AbstractShellCommand> result = new TreeSet<AbstractShellCommand>();

String[] tokens = line == null ? new String[0] : line.split(" ");
if (tokens.length <= 1)
{
Map<String, ShellCommand> commandMap = getEnabledShellCommands(shellContext);
Map<String, AbstractShellCommand> commandMap = getEnabledShellCommands(shellContext);
String token = (tokens.length == 1) ? tokens[0] : null;
for (Entry<String, ShellCommand> entry : commandMap.entrySet())
for (Entry<String, AbstractShellCommand> entry : commandMap.entrySet())
{
if (token == null || entry.getKey().startsWith(token))
result.add(entry.getValue());
Expand All @@ -186,7 +186,7 @@ public Collection<ShellCommand> findMatchingCommands(ShellContext shellContext,
return result;
}

public Result execute(ShellCommand shellCommand)
public Result execute(AbstractShellCommand shellCommand)
{
Result result = null;
try
Expand All @@ -208,22 +208,22 @@ public Result execute(ShellCommand shellCommand)
/**
* @param shellCommand
*/
private void firePreCommandListeners(ShellCommand shellCommand)
private void firePreCommandListeners(AbstractShellCommand shellCommand)
{
for (CommandExecutionListener listener : listeners)
{
listener.preCommandExecuted(shellCommand.getCommand(), shellCommand.getContext());
listener.preCommandExecuted(shellCommand.getSourceCommand(), shellCommand.getContext());
}
}

/**
* @param shellCommand
*/
private void firePostCommandListeners(ShellCommand shellCommand, Result result)
private void firePostCommandListeners(AbstractShellCommand shellCommand, Result result)
{
for (CommandExecutionListener listener : listeners)
{
listener.postCommandExecuted(shellCommand.getCommand(), shellCommand.getContext(), result);
listener.postCommandExecuted(shellCommand.getSourceCommand(), shellCommand.getContext(), result);
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.jboss.forge.addon.shell.aesh;

import java.util.Map;

import org.jboss.aesh.cl.ParsedCompleteObject;
import org.jboss.aesh.cl.exception.CommandLineParserException;
import org.jboss.aesh.cl.internal.ParameterInt;
import org.jboss.forge.addon.shell.ui.ShellContext;
import org.jboss.forge.addon.shell.ui.ShellUIBuilderImpl;
import org.jboss.forge.addon.shell.util.ShellUtil;
import org.jboss.forge.addon.ui.UICommand;
import org.jboss.forge.addon.ui.input.InputComponent;
import org.jboss.forge.addon.ui.result.Result;

/**
*
* @author <a href="ggastald@redhat.com">George Gastaldi</a>
*/
public abstract class AbstractShellCommand implements Comparable<AbstractShellCommand>
{
private final String name;
private final ShellContext context;
private final UICommand root;

protected final CommandLineUtil commandLineUtil;

protected AbstractShellCommand(UICommand root, ShellContext shellContext,
CommandLineUtil commandLineUtil)
{
this.root = root;
this.name = ShellUtil.shellifyName(root.getMetadata().getName());
this.context = shellContext;
this.commandLineUtil = commandLineUtil;
}

public abstract Map<String, InputComponent<?, Object>> getInputs();

public abstract ParameterInt getParameter();

public abstract ParsedCompleteObject parseCompleteObject(String line) throws CommandLineParserException;

public abstract void populateInputs(String line, boolean lenient) throws CommandLineParserException;

public abstract Result execute() throws Exception;

protected Map<String, InputComponent<?, Object>> buildInputs(UICommand command)
{
// Initialize UICommand
ShellUIBuilderImpl builder = new ShellUIBuilderImpl(context);
try
{
command.initializeUI(builder);
}
catch (Exception e)
{
throw new RuntimeException("Error while initializing command", e);
}
return builder.getComponentMap();

}

public UICommand getSourceCommand()
{
return root;
}

public final String getName()
{
return name;
}

public final ShellContext getContext()
{
return context;
}

@Override
public int compareTo(AbstractShellCommand o)
{
return getName().compareTo(o.getName());
}

@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof AbstractShellCommand))
return false;

AbstractShellCommand that = (AbstractShellCommand) o;

if (!getName().equals(that.getName()))
return false;

return true;
}

@Override
public int hashCode()
{
return getName().hashCode();
}

@Override
public String toString()
{
return getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

import org.jboss.aesh.cl.CommandLine;
import org.jboss.aesh.cl.CommandLineParser;
import org.jboss.aesh.cl.OptionBuilder;
import org.jboss.aesh.cl.ParserBuilder;
import org.jboss.aesh.cl.builder.OptionBuilder;
import org.jboss.aesh.cl.exception.OptionParserException;
import org.jboss.aesh.cl.internal.ParameterInt;
import org.jboss.forge.addon.convert.Converter;
Expand Down Expand Up @@ -67,7 +67,7 @@ public CommandLineParser generateParser(UICommand command,
{
OptionBuilder optionBuilder = new OptionBuilder();

optionBuilder.longName(input.getName())
optionBuilder.name(input.getName())
.defaultValue(defaultValue == null ? null : defaultValue.toString())
.description(input.getLabel())
.hasMultipleValues(isMultiple)
Expand All @@ -76,7 +76,7 @@ public CommandLineParser generateParser(UICommand command,

if (input.getShortName() != InputComponents.DEFAULT_SHORT_NAME)
{
optionBuilder.name(input.getShortName());
optionBuilder.shortName(input.getShortName());
}
parameter.addOption(optionBuilder.create());
}
Expand All @@ -86,7 +86,7 @@ public CommandLineParser generateParser(UICommand command,
}
}
}
builder.addParameter(parameter);
builder.parameter(parameter);
return builder.generateParser();
}

Expand All @@ -100,7 +100,7 @@ public void populateUIInputs(CommandLine commandLine,
if (input.getName().equals("arguments") &&
input instanceof UIInputMany)
{
InputComponents.setValueFor(converterFactory, input, commandLine.getArguments());
InputComponents.setValueFor(converterFactory, input, commandLine.getArgument());
}
else if (input instanceof UIInputMany)
{
Expand All @@ -121,9 +121,11 @@ else if (input instanceof UISelectOne)
}
}

@SuppressWarnings("unchecked")
private void setInputChoice(UISelectOne<Object> input, String optionValue)
{
Converter<Object, String> labelConverter = input.getItemLabelConverter();
Converter<Object, String> labelConverter = (Converter<Object, String>) InputComponents.getItemLabelConverter(
converterFactory, input);
boolean found = false;
for (Object choice : input.getValueChoices())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
import java.io.IOException;

import org.jboss.aesh.cl.exception.CommandLineParserException;
import org.jboss.aesh.console.Config;
import org.jboss.aesh.console.ConsoleCallback;
import org.jboss.aesh.console.ConsoleOutput;
import org.jboss.forge.addon.shell.ShellImpl;
import org.jboss.forge.addon.shell.ui.ShellContext;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.furnace.util.Strings;

/**
* Hook for Aesh operations
Expand All @@ -38,34 +38,37 @@ public ForgeConsoleCallback(ShellImpl shell)
@Override
public int readConsoleOutput(ConsoleOutput output) throws IOException
{
try
String line = output.getBuffer();
if (!Strings.isNullOrEmpty(line))
{
ShellContext context = shell.newShellContext();
String line = output.getBuffer();
ShellCommand command = shell.findCommand(context, line);
if (command == null)
{
throw new IOException("Command not found for line: " + line);
}
try
{
command.populateInputs(line);
}
catch (CommandLineParserException e)
{
throw new IOException(e);
ShellContext context = shell.newShellContext();
AbstractShellCommand command = shell.findCommand(context, line);
if (command == null)
{
throw new IOException("Command not found for line: " + line);
}
try
{
command.populateInputs(line, false);
}
catch (CommandLineParserException e)
{
throw new IOException(e);
}
Result result = shell.execute(command);
if (result != null)
{
shell.getConsole().out().println(result.getMessage());
}
}
Result result = shell.execute(command);
if (result != null)
catch (Exception e)
{
shell.getConsole().pushToStdOut(result.getMessage() + Config.getLineSeparator());
shell.getConsole().out().println("**ERROR**: " + e.getMessage());
return -1;
}
}
catch (Exception e)
{
shell.getConsole().pushToStdOut("**ERROR**: " + e.getMessage() + Config.getLineSeparator());
return -1;
}
return 0;
}
}
Loading

0 comments on commit 565a831

Please sign in to comment.