-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SystemRegistry: register and manage subcommands execution and completion
- Loading branch information
Showing
4 changed files
with
229 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,9 +54,6 @@ | |
* @author <a href="mailto:[email protected]">Matti Rinta-Nikkola</a> | ||
*/ | ||
public class SystemRegistryImpl implements SystemRegistry { | ||
public enum Command { | ||
EXIT, HELP | ||
}; | ||
|
||
public enum Pipe { | ||
FLIP, NAMED, AND, OR | ||
|
@@ -67,11 +64,9 @@ public enum Pipe { | |
private Integer consoleId; | ||
private Parser parser; | ||
private ConfigurationPath configPath; | ||
private Map<Command, String> commandName = new HashMap<>(); | ||
private Map<String, Command> nameCommand = new HashMap<>(); | ||
private Map<String, String> aliasCommand = new HashMap<>(); | ||
private Map<String,CommandRegistry> subcommands = new HashMap<>(); | ||
private Map<Pipe, String> pipeName = new HashMap<>(); | ||
private final Map<Command, CommandMethods> commandExecute = new HashMap<>(); | ||
private final Map<String, CommandMethods> commandExecute = new HashMap<>(); | ||
private Map<String, List<String>> commandInfos = new HashMap<>(); | ||
private Exception exception; | ||
private CommandOutputStream outputStream; | ||
|
@@ -81,21 +76,12 @@ public SystemRegistryImpl(Parser parser, Terminal terminal, ConfigurationPath co | |
this.parser = parser; | ||
this.configPath = configPath; | ||
outputStream = new CommandOutputStream(terminal); | ||
Set<Command> cmds = new HashSet<>(EnumSet.allOf(Command.class)); | ||
for (Command c : cmds) { | ||
commandName.put(c, c.name().toLowerCase()); | ||
} | ||
doNameCommand(); | ||
pipeName.put(Pipe.FLIP, "|;"); | ||
pipeName.put(Pipe.NAMED, "|"); | ||
pipeName.put(Pipe.AND, "&&"); | ||
pipeName.put(Pipe.OR, "||"); | ||
commandExecute.put(Command.EXIT, new CommandMethods(this::exit, this::exitCompleter)); | ||
commandExecute.put(Command.HELP, new CommandMethods(this::help, this::helpCompleter)); | ||
} | ||
|
||
private void doNameCommand() { | ||
nameCommand = commandName.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); | ||
commandExecute.put("exit", new CommandMethods(this::exit, this::exitCompleter)); | ||
commandExecute.put("help", new CommandMethods(this::help, this::helpCompleter)); | ||
} | ||
|
||
public void rename(Pipe pipe, String name) { | ||
|
@@ -151,7 +137,7 @@ public Set<String> commandNames() { | |
} | ||
|
||
private Set<String> localCommandNames() { | ||
return nameCommand.keySet(); | ||
return commandExecute.keySet(); | ||
} | ||
|
||
@Override | ||
|
@@ -160,29 +146,26 @@ public Map<String, String> commandAliases() { | |
for (CommandRegistry r : commandRegistries) { | ||
out.putAll(r.commandAliases()); | ||
} | ||
out.putAll(aliasCommand); | ||
return out; | ||
} | ||
|
||
private Command command(String name) { | ||
Command out = null; | ||
if (!isLocalCommand(name)) { | ||
throw new IllegalArgumentException("Command does not exists!"); | ||
} | ||
if (aliasCommand.containsKey(name)) { | ||
name = aliasCommand.get(name); | ||
} | ||
if (nameCommand.containsKey(name)) { | ||
out = nameCommand.get(name); | ||
} else { | ||
throw new IllegalArgumentException("Command does not exists!"); | ||
} | ||
return out; | ||
/** | ||
* Register subcommand registry | ||
* @param command main command | ||
* @param subcommandRegistry subcommand registry | ||
*/ | ||
public void register(String command, CommandRegistry subcommandRegistry) { | ||
subcommands.put(command, subcommandRegistry); | ||
commandExecute.put(command, new Builtins.CommandMethods(this::subcommand, this::emptyCompleter)); | ||
} | ||
|
||
private List<String> localCommandInfo(String command) { | ||
try { | ||
localExecute(command, new String[] { "--help" }); | ||
if (subcommands.containsKey(command)) { | ||
return subcommands.get(command).commandInfo("help"); | ||
} else { | ||
localExecute(command, new String[] { "--help" }); | ||
} | ||
} catch (HelpException e) { | ||
exception = null; | ||
return Builtins.compileCommandInfo(e.getMessage()); | ||
|
@@ -215,7 +198,7 @@ public boolean hasCommand(String command) { | |
} | ||
|
||
private boolean isLocalCommand(String command) { | ||
return nameCommand.containsKey(command) || aliasCommand.containsKey(command); | ||
return commandExecute.containsKey(command); | ||
} | ||
|
||
private boolean isCommandOrScript(String command) { | ||
|
@@ -229,10 +212,28 @@ private boolean isCommandOrScript(String command) { | |
public Completers.SystemCompleter compileCompleters() { | ||
Completers.SystemCompleter out = CommandRegistry.aggregateCompleters(commandRegistries); | ||
Completers.SystemCompleter local = new Completers.SystemCompleter(); | ||
for (Map.Entry<Command, String> entry : commandName.entrySet()) { | ||
local.add(entry.getValue(), commandExecute.get(entry.getKey()).compileCompleter().apply(entry.getValue())); | ||
for (String command : commandExecute.keySet()) { | ||
if (subcommands.containsKey(command)) { | ||
for(Map.Entry<String,List<Completer>> entry : subcommands.get(command).compileCompleters().getCompleters().entrySet()) { | ||
for (Completer cc : entry.getValue()) { | ||
if (!(cc instanceof ArgumentCompleter)) { | ||
throw new IllegalArgumentException(); | ||
} | ||
List<Completer> cmps = ((ArgumentCompleter)cc).getCompleters(); | ||
cmps.add(0, NullCompleter.INSTANCE); | ||
cmps.set(1, new StringsCompleter(entry.getKey())); | ||
Completer last = cmps.get(cmps.size() - 1); | ||
if (last instanceof OptionCompleter) { | ||
((OptionCompleter)last).setStartPos(cmps.size() - 1); | ||
cmps.set(cmps.size() - 1, last); | ||
} | ||
local.add(command, new ArgumentCompleter(cmps)); | ||
} | ||
} | ||
} else { | ||
local.add(command, commandExecute.get(command).compileCompleter().apply(command)); | ||
} | ||
} | ||
local.addAliases(aliasCommand); | ||
out.add(local); | ||
out.compile(); | ||
return out; | ||
|
@@ -284,7 +285,13 @@ public Widgets.CmdDesc commandDescription(Widgets.CmdLine line) { | |
case COMMAND: | ||
String cmd = parser.getCommand(line.getArgs().get(0)); | ||
if (isCommandOrScript(cmd) && !hasPipes(line.getArgs())) { | ||
out = commandDescription(cmd); | ||
if (subcommands.containsKey(cmd)) { | ||
List<String> args = line.getArgs(); | ||
String c = args.size() > 1 ? args.get(1) : "help"; | ||
out = subcommands.get(cmd).commandDescription(c); | ||
} else { | ||
out = commandDescription(cmd); | ||
} | ||
} | ||
break; | ||
case METHOD: | ||
|
@@ -333,7 +340,7 @@ public Object localExecute(String command, String[] args) throws Exception { | |
if (!isLocalCommand(command)) { | ||
throw new IllegalArgumentException(); | ||
} | ||
Object out = commandExecute.get(command(command)).executeFunction() | ||
Object out = commandExecute.get(command).executeFunction() | ||
.apply(new Builtins.CommandInput(command, args, commandSession())); | ||
if (exception != null) { | ||
throw exception; | ||
|
@@ -1250,6 +1257,7 @@ private Object help(Builtins.CommandInput input) { | |
boolean withInfo = commands.size() < terminal().getHeight() || !opt.args().isEmpty() ? true : false; | ||
int max = Collections.max(commands, Comparator.comparing(String::length)).length() + 1; | ||
TreeMap<String, String> builtinCommands = new TreeMap<>(); | ||
TreeMap<String, String> systemCommands = new TreeMap<>(); | ||
for (CommandRegistry r : commandRegistries) { | ||
if (isBuiltinRegistry(r)) { | ||
for (String c : r.commandNames()) { | ||
|
@@ -1258,9 +1266,19 @@ private Object help(Builtins.CommandInput input) { | |
} | ||
} | ||
for (String c : localCommandNames()) { | ||
builtinCommands.put(c, doCommandInfo(commandInfo(c))); | ||
systemCommands.put(c, doCommandInfo(commandInfo(c))); | ||
exception = null; | ||
} | ||
if (isInArgs(opt.args(), "System")) { | ||
printHeader("System"); | ||
if (withInfo) { | ||
for (Map.Entry<String, String> entry : systemCommands.entrySet()) { | ||
printCommandInfo(entry.getKey(), entry.getValue(), max); | ||
} | ||
} else { | ||
printCommands(systemCommands.keySet(), max); | ||
} | ||
} | ||
if (isInArgs(opt.args(), "Builtins")) { | ||
printHeader("Builtins"); | ||
if (withInfo) { | ||
|
@@ -1321,6 +1339,18 @@ private Object exit(Builtins.CommandInput input) { | |
return null; | ||
} | ||
|
||
private Object subcommand(Builtins.CommandInput input) { | ||
Object out = null; | ||
try { | ||
out = subcommands.get(input.command()).execute(input.session() | ||
, input.args()[0] | ||
, Arrays.copyOfRange(input.args(), 1, input.args().length)); | ||
} catch (Exception e) { | ||
exception = e; | ||
} | ||
return out; | ||
} | ||
|
||
private List<OptDesc> commandOptions(String command) { | ||
try { | ||
localExecute(command, new String[] { "--help" }); | ||
|
@@ -1348,6 +1378,10 @@ private List<String> registryNames() { | |
return out; | ||
} | ||
|
||
private List<Completer> emptyCompleter(String command) { | ||
return new ArrayList<>(); | ||
} | ||
|
||
private List<Completer> helpCompleter(String command) { | ||
List<Completer> completers = new ArrayList<>(); | ||
completers.add(new ArgumentCompleter(NullCompleter.INSTANCE, | ||
|
Oops, something went wrong.