2 * Svjatoslav Commons - shared library of common functionality. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.commons.cli_helper.parameter_parser;
7 import java.util.ArrayList;
10 import static eu.svjatoslav.commons.cli_helper.parameter_parser.ParameterCount.NONE;
11 import static java.lang.String.join;
12 import static java.util.Collections.addAll;
13 import static java.util.stream.Collectors.joining;
16 * Represents an option that can be provided on CLI.
17 * This class allows specifying whether the option is mandatory,
18 * the parameter count, a description, and any aliases for the option.
20 * @param <T> type of value that this option returns.
21 * @param <I> type of this option.
23 public abstract class Option<T, I extends Option> {
26 * Purpose of this option, like: input image path, compression level, etc...
28 * Note: for describing option type there is {@link #describeFormat()}.
30 public final String description;
33 * List of arguments for this parameter.
35 public final List<String> parameters = new ArrayList<>();
36 final ParameterCount parameterCount;
39 * List of aliases for this option.
41 private final List<String> aliases = new ArrayList<>();
44 * Indicates that at least one parameter is mandatory for this option.
46 protected boolean mandatory;
49 * If this parameter was present in the commandline, then this boolean will
50 * be set to <code>true</code>.
52 private boolean isPresent;
55 * Represents an option that can be provided on CLI.
56 * This class allows specifying whether the option is mandatory,
57 * the parameter count, a description, and any aliases for the option.
59 * @param mandatory indicates whether the option is mandatory
60 * @param parameterCount the number of parameters required for the option
61 * @param description a description of the option
62 * @param aliases2 any additional aliases for the option
64 public Option(final boolean mandatory,
65 final ParameterCount parameterCount, final String description,
66 final String... aliases2) {
68 this.mandatory = mandatory;
69 this.description = description;
70 this.parameterCount = parameterCount;
73 addAll(aliases, aliases2);
76 public Option(final String description, final ParameterCount parameterCount) {
77 this.description = description;
78 this.parameterCount = parameterCount;
82 * Adds additional aliases to the option.
84 * @param aliasArray an array of strings representing the aliases to be added
85 * @return the modified option object
87 @SuppressWarnings("unchecked")
88 public I addAliases(final String... aliasArray) {
91 addAll(aliases, aliasArray);
97 * @param parameterString parameter to add
98 * @return <code>true</code> if no errors were found. <code>false</code>
101 public boolean addParameter(final String parameterString) {
102 // check if arguments are allowed for this parameter
103 if (parameterCount.equals(NONE)) {
105 .println("Error! No parameters are allowed for option(s): "
106 + getAliasesAsString());
110 // check if multiple arguments are allowed
111 if ((!parameters.isEmpty())
112 && (parameterCount.equals(ParameterCount.ONE))) {
114 .println("Error! Only single parameter is allowed for argument(s): "
115 + getAliasesAsString());
119 if (isValid(parameterString)) {
120 parameters.add(parameterString);
123 System.out.println("Error! Invalid parameter type for \"" + parameterString
124 + "\". It shall be " + describeFormat() + ".");
130 * @return Single line parameter type description. For example: "file", "date", "integer", "regular expression", etc..
132 * Note: for argument purpose description there is {@link #description}
134 public abstract String describeFormat();
137 * @return aliases for this parameter as string.
139 public String getAliasesAsString() {
140 return join(", ", aliases);
144 * Returns the help message for this parameter.
146 * @return the help message as a string.
148 public String getHelp() {
149 final StringBuilder result = new StringBuilder();
152 result.append(getAliasesAsString());
153 if (!NONE.equals(parameterCount)) {
156 .append(isMandatory() ? "mandatory, " : "")
157 .append(describeFormat())
160 if (parameterCount.equals(ParameterCount.ONE_OR_MORE))
161 result.append("...");
166 result.append(" " + description + "\n");
168 return result.toString();
172 * Returns the value of the object.
174 * @return the value of the object.
176 public abstract T getValue();
178 public boolean isMandatory() {
183 * @return <code>true</code> if this parameter was present in the commandline.
185 public boolean isPresent() {
190 * Sets the present status of this parameter.
192 * @param present <code>true</code> if this parameter is present in the command line,
193 * <code>false</code> otherwise.
195 protected void setPresent(final boolean present) {
196 this.isPresent = present;
200 * @param alias alias to check against
201 * @return <code>true</code> if given alias is registered for this
204 public boolean matchesAlias(final String alias) {
205 return aliases.contains(alias);
210 * Notifies this option that no more parameters will follow.
211 * This gives option chance to verify if this is ok.
213 * @return <code>true</code> if no errors were found. <code>false</code>
216 public boolean noMoreArguments() {
218 if ((!parameterCount.equals(NONE))
219 && (parameters.isEmpty())) {
221 System.out.println("Error! " + getAliasesAsString()
222 + " require at least one parameter.");
230 * Sets the option as mandatory. This means that the option must be provided by the user
231 * in order for the program to run successfully.
233 * @return The updated instance of the option.
235 @SuppressWarnings("unchecked")
236 public I setMandatory() {
242 * @param value value to validate
243 * @return <code>true</code> if value is correct, <code>false</code>
246 public abstract boolean isValid(String value);