1 package org
.argeo
.api
.cli
;
3 import java
.io
.StringWriter
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Arrays
;
9 import java
.util
.TreeMap
;
10 import java
.util
.function
.Function
;
12 import org
.apache
.commons
.cli
.CommandLine
;
13 import org
.apache
.commons
.cli
.CommandLineParser
;
14 import org
.apache
.commons
.cli
.DefaultParser
;
15 import org
.apache
.commons
.cli
.MissingOptionException
;
16 import org
.apache
.commons
.cli
.Options
;
17 import org
.apache
.commons
.cli
.ParseException
;
19 /** Base class for a CLI managing sub commands. */
20 public abstract class CommandsCli
implements DescribedCommand
<Object
> {
21 public final static String HELP
= "help";
23 private final String commandName
;
24 private Map
<String
, Function
<List
<String
>, ?
>> commands
= new TreeMap
<>();
26 protected final Options options
= new Options();
28 public CommandsCli(String commandName
) {
29 this.commandName
= commandName
;
33 public Object
apply(List
<String
> args
) {
35 List
<String
> newArgs
= new ArrayList
<>();
37 CommandLineParser clParser
= new DefaultParser();
38 CommandLine commonCl
= clParser
.parse(getOptions(), args
.toArray(new String
[args
.size()]), true);
39 List
<String
> leftOvers
= commonCl
.getArgList();
40 for (String arg
: leftOvers
) {
41 if (!arg
.startsWith("-") && cmd
== null) {
47 } catch (ParseException e
) {
48 CommandArgsException cae
= new CommandArgsException(e
);
52 Function
<List
<String
>, ?
> function
= cmd
!= null ?
getCommand(cmd
) : getDefaultCommand();
54 throw new IllegalArgumentException("Uknown command " + cmd
);
56 Object value
= function
.apply(newArgs
);
57 return value
!= null ? value
.toString() : null;
58 } catch (CommandArgsException e
) {
59 if (e
.getCommandName() == null) {
60 e
.setCommandName(cmd
);
61 e
.setCommandsCli(this);
64 } catch (IllegalArgumentException e
) {
65 CommandArgsException cae
= new CommandArgsException(e
);
66 cae
.setCommandName(cmd
);
72 public Options
getOptions() {
76 protected void addCommand(String cmd
, Function
<List
<String
>, ?
> function
) {
77 commands
.put(cmd
, function
);
82 public String
getUsage() {
86 protected void addCommandsCli(CommandsCli commandsCli
) {
87 addCommand(commandsCli
.getCommandName(), commandsCli
);
88 commandsCli
.addCommand(HELP
, new HelpCommand(this, commandsCli
));
91 public String
getCommandName() {
95 public Set
<String
> getSubCommands() {
96 return commands
.keySet();
99 public Function
<List
<String
>, ?
> getCommand(String command
) {
100 return commands
.get(command
);
103 public HelpCommand
getHelpCommand() {
104 return (HelpCommand
) getCommand(HELP
);
107 public Function
<List
<String
>, String
> getDefaultCommand() {
108 return getHelpCommand();
111 /** In order to implement quickly a main method. */
112 public static void mainImpl(CommandsCli cli
, String
[] args
) {
114 cli
.addCommand(CommandsCli
.HELP
, new HelpCommand(null, cli
));
115 Object output
= cli
.apply(Arrays
.asList(args
));
116 System
.out
.println(output
);
118 } catch (CommandArgsException e
) {
119 System
.err
.println("Wrong arguments " + Arrays
.toString(args
) + ": " + e
.getMessage());
120 Throwable cause
= e
.getCause();
121 if (!(cause
instanceof MissingOptionException
))
123 if (e
.getCommandName() != null) {
124 StringWriter out
= new StringWriter();
125 HelpCommand
.printHelp(e
.getCommandsCli(), e
.getCommandName(), out
);
126 System
.err
.println(out
.toString());
131 } catch (Exception e
) {