X-Git-Url: http://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fapi%2Fcli%2FCommandsCli.java;fp=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fapi%2Fcli%2FCommandsCli.java;h=5bbfcfa070d7cee0a2e13c722c4561b6812ec8c8;hp=0000000000000000000000000000000000000000;hb=b95462873703848193e56fcbe997693630db6121;hpb=55d88fba80cec198a0f11ba7545e19878c51fc5e diff --git a/org.argeo.cms/src/org/argeo/api/cli/CommandsCli.java b/org.argeo.cms/src/org/argeo/api/cli/CommandsCli.java new file mode 100644 index 000000000..5bbfcfa07 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/api/cli/CommandsCli.java @@ -0,0 +1,157 @@ +package org.argeo.api.cli; + +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.function.Function; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.MissingOptionException; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +/** Base class for a CLI managing sub commands. */ +public abstract class CommandsCli implements DescribedCommand { + private final String commandName; + private Map, ?>> commands = new TreeMap<>(); + + protected final Options options = new Options(); + + public CommandsCli(String commandName) { + this.commandName = commandName; + } + + @Override + public Object apply(List args) { + String cmd = null; + List newArgs = new ArrayList<>(); + boolean isHelpOption = false; + try { + CommandLineParser clParser = new DefaultParser(); + CommandLine commonCl = clParser.parse(getOptions(), args.toArray(new String[args.size()]), true); + List leftOvers = commonCl.getArgList(); + for (String arg : leftOvers) { + if (arg.equals("--" + HelpCommand.HELP_OPTION.getLongOpt())) { + isHelpOption = true; + // TODO break? + } + + if (!arg.startsWith("-") && cmd == null) { + cmd = arg; + } else { + newArgs.add(arg); + } + } + } catch (ParseException e) { + CommandArgsException cae = new CommandArgsException(e); + throw cae; + } + + Function, ?> function = cmd != null ? getCommand(cmd) : getDefaultCommand(); + + // --help option + if (!(function instanceof CommandsCli)) + if (function instanceof DescribedCommand command) + if (isHelpOption) { + throw new PrintHelpRequestException(cmd, this); +// StringWriter out = new StringWriter(); +// HelpCommand.printHelp(command, out); +// System.out.println(out.toString()); +// return null; + } + + if (function == null) + throw new IllegalArgumentException("Uknown command " + cmd); + try { + Object value = function.apply(newArgs); + return value != null ? value.toString() : null; + } catch (CommandArgsException e) { + if (e.getCommandName() == null) { + e.setCommandName(cmd); + e.setCommandsCli(this); + } + throw e; + } catch (IllegalArgumentException e) { + CommandArgsException cae = new CommandArgsException(e); + cae.setCommandName(cmd); + throw cae; + } + } + + @Override + public Options getOptions() { + return options; + } + + protected void addCommand(String cmd, Function, ?> function) { + commands.put(cmd, function); + + } + + @Override + public String getUsage() { + return "[command]"; + } + + protected void addCommandsCli(CommandsCli commandsCli) { + addCommand(commandsCli.getCommandName(), commandsCli); + commandsCli.addCommand(HelpCommand.HELP, new HelpCommand(this, commandsCli)); + } + + public String getCommandName() { + return commandName; + } + + public Set getSubCommands() { + return commands.keySet(); + } + + public Function, ?> getCommand(String command) { + return commands.get(command); + } + + public HelpCommand getHelpCommand() { + return (HelpCommand) getCommand(HelpCommand.HELP); + } + + public Function, String> getDefaultCommand() { + return getHelpCommand(); + } + + /** In order to implement quickly a main method. */ + public static void mainImpl(CommandsCli cli, String[] args) { + try { + cli.addCommand(HelpCommand.HELP, new HelpCommand(null, cli)); + Object output = cli.apply(Arrays.asList(args)); + if (output != null) + System.out.println(output); + System.exit(0); + } catch (PrintHelpRequestException e) { + StringWriter out = new StringWriter(); + HelpCommand.printHelp(e.getCommandsCli(), e.getCommandName(), out); + System.out.println(out.toString()); + } catch (CommandArgsException e) { + System.err.println("Wrong arguments " + Arrays.toString(args) + ": " + e.getMessage()); + Throwable cause = e.getCause(); + if (!(cause instanceof MissingOptionException)) + e.printStackTrace(); + if (e.getCommandName() != null) { + StringWriter out = new StringWriter(); + HelpCommand.printHelp(e.getCommandsCli(), e.getCommandName(), out); + System.err.println(out.toString()); + } else { + e.printStackTrace(); + } + System.exit(1); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } +}