1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.cli.processor.command;
28
29 import gov.nist.secauto.metaschema.cli.processor.CLIProcessor.CallingContext;
30 import gov.nist.secauto.metaschema.cli.processor.ExitCode;
31 import gov.nist.secauto.metaschema.cli.processor.ExitStatus;
32
33 import org.apache.commons.cli.CommandLine;
34
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.LinkedHashMap;
38 import java.util.Map;
39 import java.util.stream.Collectors;
40
41 import edu.umd.cs.findbugs.annotations.NonNull;
42
43 public abstract class AbstractParentCommand implements ICommand {
44 @NonNull
45 private final Map<String, ICommand> commandToSubcommandHandlerMap;
46 private final boolean subCommandRequired;
47
48 @SuppressWarnings("null")
49 protected AbstractParentCommand(boolean subCommandRequired) {
50 this.commandToSubcommandHandlerMap = Collections.synchronizedMap(new LinkedHashMap<>());
51 this.subCommandRequired = subCommandRequired;
52 }
53
54 protected void addCommandHandler(ICommand handler) {
55 String commandName = handler.getName();
56 this.commandToSubcommandHandlerMap.put(commandName, handler);
57 }
58
59 @Override
60 public ICommand getSubCommandByName(String name) {
61 return commandToSubcommandHandlerMap.get(name);
62 }
63
64 @SuppressWarnings("null")
65 @Override
66 public Collection<ICommand> getSubCommands() {
67 return Collections.unmodifiableCollection(commandToSubcommandHandlerMap.values());
68 }
69
70 @Override
71 public boolean isSubCommandRequired() {
72 return subCommandRequired;
73 }
74
75 @Override
76 public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine cmdLine) {
77 return ICommandExecutor.using(callingContext, cmdLine, this::executeCommand);
78 }
79
80 @NonNull
81 protected ExitStatus executeCommand(
82 @NonNull CallingContext callingContext,
83 @NonNull CommandLine commandLine) {
84 callingContext.showHelp();
85 ExitStatus status;
86 if (isSubCommandRequired()) {
87 status = ExitCode.INVALID_COMMAND
88 .exitMessage("Please use one of the following sub-commands: " +
89 getSubCommands().stream()
90 .map(command -> command.getName())
91 .collect(Collectors.joining(", ")));
92 } else {
93 status = ExitCode.OK.exit();
94 }
95 return status;
96 }
97
98 }