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