import static eu.svjatoslav.commons.cli_helper.parameter_parser.ParameterCount.NONE;
import static java.lang.String.join;
import static java.util.Collections.addAll;
-import static java.util.stream.Collectors.joining;
/**
- * Represents an option that can be provided on CLI.
- * This class allows specifying whether the option is mandatory,
- * the parameter count, a description, and any aliases for the option.
+ * Represents a command-line option (a flag or switch), which can be configured with:
+ * <ul>
+ * <li>whether it's mandatory</li>
+ * <li>the number of parameters accepted</li>
+ * <li>a textual description</li>
+ * <li>aliases (the actual CLI flags, e.g., "--help" or "-h")</li>
+ * </ul>
*
- * @param <T> type of value that this option returns.
- * @param <I> type of this option.
+ * @param <T> the type of object returned by {@link #getValue()}
+ * @param <I> the actual subclass type, used to enable fluent method chaining
*/
-public abstract class Option<T, I extends Option> {
+public abstract class Option<T, I extends Option<?, I>> {
/**
- * Purpose of this option, like: input image path, compression level, etc...
- *
- * Note: for describing option type there is {@link #describeFormat()}.
+ * Human-readable purpose of this option (e.g., "Input image path").
+ * For a description of the parameter format (e.g., "file", "integer"), see {@link #describeFormat()}.
*/
public final String description;
- /**
- * List of arguments for this parameter.
- */
+ /** The list of parameters provided on the command line for this option (if any). */
public final List<String> parameters = new ArrayList<>();
+
+ /** How many parameters this option supports: NONE, ONE, or ONE_OR_MORE. */
final ParameterCount parameterCount;
- /**
- * List of aliases for this option.
- */
+ /** The aliases by which this option can be invoked (e.g. "-f", "--file"). */
private final List<String> aliases = new ArrayList<>();
- /**
- * Indicates that at least one parameter is mandatory for this option.
- */
- protected boolean mandatory;
+ /** Whether this option is mandatory (i.e., must appear at least once on the CLI). */
+ protected boolean mandatory = false;
- /**
- * If this parameter was present in the commandline, then this boolean will
- * be set to <code>true</code>.
- */
- private boolean isPresent;
+ /** Whether this option was actually present on the CLI. */
+ private boolean isPresent = false;
/**
- * Represents an option that can be provided on CLI.
- * This class allows specifying whether the option is mandatory,
- * the parameter count, a description, and any aliases for the option.
+ * Fully-custom constructor for an option.
*
- * @param mandatory indicates whether the option is mandatory
- * @param parameterCount the number of parameters required for the option
- * @param description a description of the option
- * @param aliases2 any additional aliases for the option
+ * @param mandatory {@code true} if the option is required, {@code false} otherwise
+ * @param parameterCount the number of parameters required: NONE, ONE, or ONE_OR_MORE
+ * @param description a textual description of the option
+ * @param aliases2 zero or more aliases (e.g. "-f", "--file")
*/
public Option(final boolean mandatory,
- final ParameterCount parameterCount, final String description,
+ final ParameterCount parameterCount,
+ final String description,
final String... aliases2) {
-
this.mandatory = mandatory;
this.description = description;
this.parameterCount = parameterCount;
-
- // save aliases
addAll(aliases, aliases2);
}
- public Option(final String description, final ParameterCount parameterCount) {
- this.description = description;
- this.parameterCount = parameterCount;
+ /**
+ * Simpler constructor that defaults to a non-mandatory option.
+ * You can make it mandatory later by calling {@link #setMandatory()}.
+ *
+ * @param description a textual description of the option
+ * @param parameterCount the number of parameters required: NONE, ONE, or ONE_OR_MORE
+ * @param aliases2 zero or more aliases
+ */
+ public Option(final String description,
+ final ParameterCount parameterCount,
+ final String... aliases2) {
+ this(false, parameterCount, description, aliases2);
}
/**
- * Adds additional aliases to the option.
+ * Adds additional aliases to this option for user convenience.
*
- * @param aliasArray an array of strings representing the aliases to be added
- * @return the modified option object
+ * @param aliasArray additional aliases (e.g., "-f", "--file")
+ * @return this option (for method chaining)
*/
@SuppressWarnings("unchecked")
public I addAliases(final String... aliasArray) {
-
- // save aliases
addAll(aliases, aliasArray);
-
return (I) this;
}
/**
- * @param parameterString parameter to add
- * @return <code>true</code> if no errors were found. <code>false</code>
- * otherwise.
+ * Adds a parameter to this option, validating it against {@link #isValid(String)}.
+ *
+ * @param parameterString the parameter string to add
+ * @return {@code true} if the parameter was valid and added, otherwise {@code false}
*/
public boolean addParameter(final String parameterString) {
- // check if arguments are allowed for this parameter
+ // Check if this option is supposed to have parameters at all
if (parameterCount.equals(NONE)) {
- System.out
- .println("Error! No parameters are allowed for option(s): "
- + getAliasesAsString());
+ System.out.println("Error! No parameters are allowed for option(s): "
+ + getAliasesAsString());
return false;
}
- // check if multiple arguments are allowed
- if ((!parameters.isEmpty())
- && (parameterCount.equals(ParameterCount.ONE))) {
- System.out
- .println("Error! Only single parameter is allowed for argument(s): "
- + getAliasesAsString());
+ // If only ONE parameter is allowed, but we already have one
+ if ((!parameters.isEmpty()) && parameterCount.equals(ParameterCount.ONE)) {
+ System.out.println("Error! Only one parameter is allowed for argument(s): "
+ + getAliasesAsString());
return false;
}
+ // Validate the parameter itself
if (isValid(parameterString)) {
parameters.add(parameterString);
return true;
} else {
- System.out.println("Error! Invalid parameter type for \"" + parameterString
- + "\". It shall be " + describeFormat() + ".");
+ System.out.println("Error! Invalid parameter \"" + parameterString
+ + "\". It should be " + describeFormat() + ".");
return false;
}
}
/**
- * @return Single line parameter type description. For example: "file", "date", "integer", "regular expression", etc..
- * <p>
- * Note: for argument purpose description there is {@link #description}
+ * Describes the kind or format of the expected parameter(s), e.g. "File", "Integer", etc.
+ *
+ * @return a short string describing the parameter format
*/
public abstract String describeFormat();
/**
- * @return aliases for this parameter as string.
+ * Returns this option's aliases as a comma-separated string (e.g. "-f, --file").
*/
public String getAliasesAsString() {
- return join(", ", aliases);
+ return aliases.isEmpty() ? "<no aliases>" : join(", ", aliases);
}
/**
- * Returns the help message for this parameter.
+ * Returns a help message that includes the aliases, whether the option is mandatory,
+ * the format, and a brief description.
*
- * @return the help message as a string.
+ * @return a descriptive help string
*/
public String getHelp() {
- final StringBuilder result = new StringBuilder();
-
- // first line
+ StringBuilder result = new StringBuilder();
+ // First line: aliases plus (mandatory?, format)
result.append(getAliasesAsString());
if (!NONE.equals(parameterCount)) {
- result
- .append(" (")
+ result.append(" (")
.append(isMandatory() ? "mandatory, " : "")
.append(describeFormat())
.append(")");
-
- if (parameterCount.equals(ParameterCount.ONE_OR_MORE))
+ if (ParameterCount.ONE_OR_MORE.equals(parameterCount)) {
result.append("...");
+ }
}
result.append("\n");
-
- // second line
- result.append(" " + description + "\n");
-
+ // Second line: indentation plus description
+ result.append(" ").append(description).append("\n");
return result.toString();
}
/**
- * Returns the value of the object.
+ * Returns the parsed value (usually constructed from {@link #parameters}).
*
- * @return the value of the object.
+ * @return the parsed value as the generic type T.
+ * @throws RuntimeException if the parameters are insufficient or invalid in a subclass.
*/
public abstract T getValue();
+ /**
+ * @return {@code true} if this option is mandatory.
+ */
public boolean isMandatory() {
return mandatory;
}
/**
- * @return <code>true</code> if this parameter was present in the commandline.
+ * @return {@code true} if this option was present on the command line.
*/
public boolean isPresent() {
return isPresent;
}
/**
- * Sets the present status of this parameter.
+ * Marks this option as present or not present.
*
- * @param present <code>true</code> if this parameter is present in the command line,
- * <code>false</code> otherwise.
+ * @param present {@code true} if it was found in the CLI arguments, else {@code false}.
*/
protected void setPresent(final boolean present) {
this.isPresent = present;
}
/**
- * @param alias alias to check against
- * @return <code>true</code> if given alias is registered for this
- * parameter.
+ * Checks if a given alias matches this option.
+ *
+ * @param alias the alias to check
+ * @return {@code true} if the alias is registered for this option
*/
public boolean matchesAlias(final String alias) {
return aliases.contains(alias);
-
}
/**
- * Notifies this option that no more parameters will follow.
- * This gives option chance to verify if this is ok.
+ * Called when no more arguments can be added to this option, giving it a chance
+ * to verify correct usage (e.g., check if required parameters are missing).
*
- * @return <code>true</code> if no errors were found. <code>false</code>
- * otherwise.
+ * @return {@code true} if the usage so far is valid; otherwise {@code false}.
*/
public boolean noMoreArguments() {
-
- if ((!parameterCount.equals(NONE))
- && (parameters.isEmpty())) {
-
+ // If we expect at least one parameter but none were provided
+ if (!parameterCount.equals(NONE) && parameters.isEmpty()) {
System.out.println("Error! " + getAliasesAsString()
- + " require at least one parameter.");
-
+ + " requires at least one parameter.");
return false;
}
return true;
}
/**
- * Sets the option as mandatory. This means that the option must be provided by the user
- * in order for the program to run successfully.
+ * Sets this option as mandatory.
*
- * @return The updated instance of the option.
+ * @return this option, for method chaining
*/
@SuppressWarnings("unchecked")
public I setMandatory() {
- mandatory = true;
+ this.mandatory = true;
return (I) this;
}
/**
- * @param value value to validate
- * @return <code>true</code> if value is correct, <code>false</code>
- * otherwise.
+ * Checks if a single parameter string is valid for this option.
+ *
+ * @param value the parameter string to test
+ * @return {@code true} if valid; {@code false} otherwise
*/
public abstract boolean isValid(String value);
-
}
package eu.svjatoslav.commons.cli_helper.parameter_parser;
/**
- * This enumeration is used to define how many parameters
- * does particular commandline option accept.
+ * Defines how many parameters a command-line option can accept.
*/
public enum ParameterCount {
-
- /**
- * Option has no parameters.
- */
+ /** Option has no parameters. */
NONE,
- /**
- * Option has exactly one mandatory parameter.
- */
+ /** Option has exactly one parameter. */
ONE,
- /**
- * Option must have one or more parameters.
- */
+ /** Option can have one or more parameters. */
ONE_OR_MORE
-}
+}
\ No newline at end of file
package eu.svjatoslav.commons.cli_helper.parameter_parser;
import java.util.ArrayList;
+import java.util.List;
/**
- * Single commandline parameter can have any amount of arguments.
+ * This class parses command-line arguments against a set of registered {@link Option} objects.
+ * <p>
+ * Usage:
+ * <pre>{@code
+ * Parser parser = new Parser();
+ * FileOption fileOpt = parser.add(new FileOption("Input file").mustExist())
+ * .addAliases("-f", "--file")
+ * .setMandatory();
+ * parser.parse(args);
+ * if (!parser.checkSuccess()) {
+ * parser.showHelp();
+ * System.exit(1);
+ * }
+ * File inputFile = fileOpt.getValue();
+ * }</pre>
*/
public class Parser {
- private final ArrayList<Option<?, ? extends Option>> options = new ArrayList<>();
-
- public <E extends Option> E add(final E parameter) {
- options.add(parameter);
- return parameter;
- }
+ private final List<Option<?, ? extends Option<?, ?>>> options = new ArrayList<>();
/**
- * @return <code>true</code> if no errors were found. <code>false</code>
- * otherwise.
+ * Registers an option with this parser.
+ *
+ * @param option the option to be added
+ * @param <E> the concrete type of the option
+ * @return the same option object, for chaining
*/
- private boolean checkMandatoryArgumentsPresent() {
-
- for (final Option option : options)
- if (option.isMandatory() && (!option.isPresent())) {
- System.out.println("Error! Mandatory parameter ("
- + option.getAliasesAsString() + ") is not specified.");
- return false;
- }
-
- return true;
+ public <E extends Option<?, E>> E add(final E option) {
+ options.add(option);
+ return option;
}
/**
- * Return parameter by given alias or <code>null</code> if no parameter
- * exists for given alias.
+ * Looks up an option by alias.
*
- * @param alias parameter alias
- * @return found parameter or <code>null</code> if parameter was not found.
+ * @param alias the alias to search for (e.g., "-f" or "--file")
+ * @return the matching option, or {@code null} if not found
*/
- public Option findParameterByAlias(final String alias) {
-
- for (final Option option : options)
- if (option.matchesAlias(alias))
+ public Option<?, ?> findParameterByAlias(final String alias) {
+ for (final Option<?, ?> option : options) {
+ if (option.matchesAlias(alias)) {
return option;
-
+ }
+ }
return null;
}
/**
- * @param args commandline arguments
- * @return <code>true</code> if no errors were found. <code>false</code>
- * otherwise.
+ * Parses the provided command-line arguments, matching them to registered options and their parameters.
+ *
+ * @param args command-line arguments (usually from main(String[]))
+ * @return {@code true} if parsing succeeded without errors; otherwise {@code false}.
*/
public boolean parse(final String[] args) {
-
- Option currentOption = null;
+ Option<?, ?> currentOption = null;
for (final String argument : args) {
+ Option<?, ?> optionForAlias = findParameterByAlias(argument);
- final Option optionForAlias = findParameterByAlias(argument);
if (optionForAlias == null) {
+ // If this argument is not a recognized option alias, treat it as a parameter to the current option
if (currentOption == null) {
- System.out.println("Unknown commandline parameter: "
- + argument);
+ System.out.println("Unknown command-line parameter: " + argument);
return false;
}
-
- if (!currentOption.addParameter(argument))
+ // Attempt to add this argument as a parameter to the current option
+ if (!currentOption.addParameter(argument)) {
return false;
-
+ }
} else {
- if (currentOption != null)
- if (!currentOption.noMoreArguments())
+ // We found a recognized option
+ // First, let the previous option finalize (check if it has all needed params, etc.)
+ if (currentOption != null) {
+ if (!currentOption.noMoreArguments()) {
return false;
-
+ }
+ }
+ // Switch to the newly recognized option
optionForAlias.setPresent(true);
currentOption = optionForAlias;
}
+ }
+ // Finalize the last option (if any)
+ if (currentOption != null) {
+ if (!currentOption.noMoreArguments()) {
+ return false;
+ }
}
+ // Finally, check mandatory options
return checkMandatoryArgumentsPresent();
}
- public void showHelp() {
- System.out.println("Available commandline arguments:");
- for (final Option option : options)
- System.out.println(option.getHelp());
+ /**
+ * Checks whether all mandatory options were present.
+ *
+ * @return {@code true} if all mandatory options are present, otherwise {@code false}.
+ */
+ private boolean checkMandatoryArgumentsPresent() {
+ for (final Option<?, ?> option : options) {
+ if (option.isMandatory() && !option.isPresent()) {
+ System.out.println("Error! Mandatory parameter ("
+ + option.getAliasesAsString() + ") is not specified.");
+ return false;
+ }
+ }
+ return true;
}
-}
+ /**
+ * A convenience method to see if the last parse succeeded. If you stored the result of {@link #parse(String[])} in a
+ * boolean, you can also just check that.
+ *
+ * @return {@code true} if all mandatory options are present (and no parse errors occurred).
+ */
+ public boolean checkSuccess() {
+ return checkMandatoryArgumentsPresent();
+ }
+
+ /**
+ * Prints all available options, their formats, and their descriptions. Usually called upon parse failure.
+ */
+ public void showHelp() {
+ System.out.println("Available command-line arguments:");
+ for (final Option<?, ?> option : options) {
+ System.out.print(option.getHelp());
+ }
+ }
+}
\ No newline at end of file
import java.io.File;
-
/**
- * This class is used to define commandline option which accepts directory as parameter.
+ * Represents a command-line option that accepts exactly one parameter interpreted as a directory path.
*/
public class DirectoryOption extends Option<File, DirectoryOption> {
- /**
- * This enum is used to define if directory shall exist in filesystem or not.
- */
+ /** Defines whether the directory must exist, must not exist, or if it does not matter. */
private ExistenceType existenceType = ExistenceType.DOES_NOT_MATTER;
/**
- * Constructor.
+ * Creates a DirectoryOption object with a specified description.
*
- * @param description Description of the option.
+ * @param description a brief description of what this directory option is for.
*/
public DirectoryOption(final String description) {
super(description, ParameterCount.ONE);
}
@Override
- public java.lang.String describeFormat() {
+ public String describeFormat() {
switch (existenceType) {
- case MUST_EXIST:
- return "Existing directory.";
- case MUST_NOT_EXIST:
- return "Non-existing directory.";
- default:
- return "Directory.";
+ case MUST_EXIST: return "Existing directory.";
+ case MUST_NOT_EXIST: return "Non-existing directory.";
+ default: return "Directory.";
}
}
/**
- * Retrieves the value of the option as a {@link File} object.
+ * Returns the directory as a {@link File} object.
*
- * @return The value of the option as a {@link File} object.
- * @throws RuntimeException if the option does not have exactly 1 argument.
+ * @throws RuntimeException if the user did not provide exactly one parameter.
*/
@Override
public File getValue() {
-
- if (parameters.size() != 1)
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
-
+ if (parameters.size() != 1) {
+ throw new RuntimeException("Parameter '" + description
+ + "' must have exactly 1 argument.");
+ }
return new File(parameters.get(0));
}
/**
- * This method sets that directory shall exist.
+ * Requires that the directory must already exist.
*
- * @return This object.
+ * @return this DirectoryOption instance for chaining
*/
public DirectoryOption mustExist() {
existenceType = ExistenceType.MUST_EXIST;
}
/**
- * This method sets that directory shall not exist.
+ * Requires that the directory must not already exist.
*
- * @return This object.
+ * @return this DirectoryOption instance for chaining
*/
public DirectoryOption mustNotExist() {
existenceType = ExistenceType.MUST_NOT_EXIST;
}
/**
- * This method checks if a provided directory path is valid based on the specified existence type.
+ * Checks whether the provided path is valid based on the {@link ExistenceType}.
*
- * @param value The directory path to validate.
- * @return True if the directory path is valid according to the existence type, otherwise false.
+ * @param value the directory path to validate
+ * @return {@code true} if valid, otherwise {@code false}
*/
@Override
- public boolean isValid(final java.lang.String value) {
+ public boolean isValid(final String value) {
final File file = new File(value);
- if (existenceType == ExistenceType.MUST_EXIST) {
- return file.exists() && file.isDirectory();
- }
+ switch (existenceType) {
+ case MUST_EXIST:
+ return file.exists() && file.isDirectory();
- if (existenceType == ExistenceType.MUST_NOT_EXIST) {
- return !file.exists();
- }
+ case MUST_NOT_EXIST:
+ return !file.exists();
- if (existenceType == ExistenceType.DOES_NOT_MATTER) {
- if (file.exists())
- if (file.isFile())
+ case DOES_NOT_MATTER:
+ // If it exists and is a file, it's invalid
+ if (file.exists() && file.isFile()) {
return false;
+ }
+ return true;
- return true;
+ default:
+ return false;
}
-
- return false;
}
-
-}
+}
\ No newline at end of file
import java.util.stream.Collectors;
/**
- * DirectoryOptions class represents a command-line option for one or more directories.
+ * Represents a command-line option that accepts one or more directory paths.
*/
public class DirectoryOptions extends Option<List<File>, DirectoryOptions> {
- /**
- * This enum is used to define if resource denoted by particular option parameter shall exist or not.
- * <p>
- * This allows to specify for example if directory shall exist or not.
- */
+ /** Defines whether each directory must exist, must not exist, or if it does not matter. */
private ExistenceType existenceType = ExistenceType.DOES_NOT_MATTER;
/**
- * Creates a new DirectoryOptions object with the given description.
+ * Creates a DirectoryOptions object with a specified description, requiring one or more directories.
*
- * @param description The description of the directory options.
+ * @param description a brief description of what these directories represent.
*/
public DirectoryOptions(final String description) {
super(description, ParameterCount.ONE_OR_MORE);
}
- /**
- * Returns a string describing the format of the option.
- *
- * @return A string describing the format of the option.
- */
@Override
public String describeFormat() {
switch (existenceType) {
- case MUST_EXIST:
- return "One to many existing directories.";
- case MUST_NOT_EXIST:
- return "One to many non-existing directories.";
- default:
- return "One to many directories.";
+ case MUST_EXIST: return "One to many existing directories.";
+ case MUST_NOT_EXIST: return "One to many non-existing directories.";
+ default: return "One to many directories.";
}
}
/**
- * Returns the value of the option as a list of File objects.
- *
- * @return The value of the option as a list of File objects.
+ * Returns the directories as a list of {@link File} objects.
*/
@Override
public List<File> getValue() {
return parameters.stream().map(File::new).collect(Collectors.toList());
}
+ /**
+ * Requires that each directory must exist.
+ *
+ * @return this DirectoryOptions instance
+ */
public DirectoryOptions mustExist() {
existenceType = ExistenceType.MUST_EXIST;
return this;
}
+ /**
+ * Requires that each directory must not exist.
+ *
+ * @return this DirectoryOptions instance
+ */
public DirectoryOptions mustNotExist() {
existenceType = ExistenceType.MUST_NOT_EXIST;
return this;
}
-
+ /**
+ * Validates each directory path against the specified {@link ExistenceType}.
+ */
@Override
public boolean isValid(final String value) {
final File file = new File(value);
- if (existenceType == ExistenceType.MUST_EXIST) {
- return file.exists() && file.isDirectory();
- }
+ switch (existenceType) {
+ case MUST_EXIST:
+ return file.exists() && file.isDirectory();
- if (existenceType == ExistenceType.MUST_NOT_EXIST) {
- return !file.exists();
- }
+ case MUST_NOT_EXIST:
+ return !file.exists();
- if (existenceType == ExistenceType.DOES_NOT_MATTER) {
- if (file.exists())
- if (file.isFile())
+ case DOES_NOT_MATTER:
+ if (file.exists() && file.isFile()) {
return false;
+ }
+ return true;
- return true;
+ default:
+ return false;
}
-
- return false;
}
-
-}
+}
\ No newline at end of file
package eu.svjatoslav.commons.cli_helper.parameter_parser.parameter;
/**
- * This enum is used to define if resource denoted by particular option parameter shall exist or not.
- * <p>
- * This allows to specify for example if directory shall exist or not.
+ * Defines whether a file/directory resource must exist, must not exist, or if it does not matter.
*/
public enum ExistenceType {
-
- /**
- * Resource shall exist.
- */
+ /** Resource shall exist. */
MUST_EXIST,
- /**
- * Resource shall not exist.
- */
+ /** Resource shall not exist. */
MUST_NOT_EXIST,
- /**
- * Resource existence does not matter.
- */
- DOES_NOT_MATTER;
-
-}
+ /** Resource existence does not matter. */
+ DOES_NOT_MATTER
+}
\ No newline at end of file
import java.io.File;
/**
- * This class represents commandline option which accepts exactly one parameter
- * which is a file.
+ * Represents a command-line option that accepts exactly one parameter which is interpreted as a file path.
+ * By default, {@link ExistenceType#DOES_NOT_MATTER} is used (i.e., the file may or may not exist).
*/
public class FileOption extends Option<File, FileOption> {
+ /** Specifies whether the file must exist, must not exist, or does not matter. */
private ExistenceType existenceType = ExistenceType.DOES_NOT_MATTER;
+ /**
+ * Creates a FileOption requiring exactly one parameter that represents a file.
+ *
+ * @param description a brief description of what this option is for (e.g., "Path to input file").
+ */
public FileOption(final String description) {
super(description, ParameterCount.ONE);
}
- protected static boolean validateFile(ExistenceType existenceType, String value) {
- final File file = new File(value);
+ /**
+ * Checks whether the given file path is valid according to the specified {@link ExistenceType}.
+ *
+ * @param existenceType the required existence status for the file
+ * @param path the file path to validate
+ * @return {@code true} if the path meets the existence requirement and is not a directory when it must be a file.
+ */
+ protected static boolean isFileValid(ExistenceType existenceType, String path) {
+ final File file = new File(path);
- if (existenceType == ExistenceType.MUST_EXIST) {
- return file.exists() && file.isFile();
- }
+ switch (existenceType) {
+ case MUST_EXIST:
+ return file.exists() && file.isFile();
- if (existenceType == ExistenceType.MUST_NOT_EXIST) {
- return !file.exists();
- }
+ case MUST_NOT_EXIST:
+ return !file.exists();
- if (existenceType == ExistenceType.DOES_NOT_MATTER) {
- if (file.exists())
- if (file.isDirectory())
+ case DOES_NOT_MATTER:
+ // If the file exists, ensure it's not a directory
+ if (file.exists() && file.isDirectory()) {
return false;
+ }
+ return true;
- return true;
+ default:
+ return false;
}
-
- return false;
}
+ /**
+ * Provides a short description of the expected format (e.g., "Existing file", "Non-existing file", or "File").
+ *
+ * @return a string describing the format of this file parameter.
+ */
@Override
- public java.lang.String describeFormat() {
+ public String describeFormat() {
switch (existenceType) {
- case MUST_EXIST:
- return "Existing file.";
- case MUST_NOT_EXIST:
- return "Non-existing file.";
- default:
- return "File.";
+ case MUST_EXIST: return "Existing file.";
+ case MUST_NOT_EXIST: return "Non-existing file.";
+ default: return "File.";
}
}
+ /**
+ * Returns the file chosen by the user (as a {@link File} object).
+ *
+ * @return a {@link File} object constructed from the single parameter.
+ * @throws RuntimeException if the option does not have exactly 1 parameter.
+ */
@Override
public File getValue() {
-
- if (parameters.size() != 1)
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
-
+ if (parameters.size() != 1) {
+ throw new RuntimeException("Parameter '" + description
+ + "' must have exactly 1 argument.");
+ }
return new File(parameters.get(0));
}
/**
- * This method sets that file shall exist.
+ * Enforces that the file path must point to an existing file.
*
- * @return This object.
+ * @return this FileOption instance, for method chaining
*/
public FileOption mustExist() {
existenceType = ExistenceType.MUST_EXIST;
}
/**
- * This method sets that file shall not exist.
+ * Enforces that the file path must not exist.
*
- * @return This object.
+ * @return this FileOption instance, for method chaining
*/
public FileOption mustNotExist() {
existenceType = ExistenceType.MUST_NOT_EXIST;
return this;
}
+ /**
+ * Validates the given parameter against the {@link ExistenceType} rule.
+ *
+ * @param value the file path to validate
+ * @return {@code true} if the file path meets the existence requirement
+ */
@Override
- public boolean isValid(final java.lang.String value) {
- return validateFile(existenceType, value);
+ public boolean isValid(final String value) {
+ return isFileValid(existenceType, value);
}
-
-}
+}
\ No newline at end of file
import java.util.List;
import java.util.stream.Collectors;
-import static eu.svjatoslav.commons.cli_helper.parameter_parser.parameter.FileOption.validateFile;
-
/**
- * This class represents commandline option which accepts one or more parameters
- * which are files.
+ * Represents a command-line option that accepts one or more file paths.
*/
public class FileOptions extends Option<List<File>, FileOptions> {
+ /** Specifies whether each file must exist, must not exist, or does not matter. */
private ExistenceType existenceType = ExistenceType.DOES_NOT_MATTER;
+ /**
+ * Constructs a FileOptions object.
+ *
+ * @param description a brief description of the option's purpose.
+ */
public FileOptions(final String description) {
super(description, ParameterCount.ONE_OR_MORE);
}
+ /**
+ * Provides a short description of the expected file format(s).
+ *
+ * @return either "One to many existing files.", "One to many non-existing files.", or "One to many files."
+ */
@Override
public String describeFormat() {
switch (existenceType) {
- case MUST_EXIST:
- return "One to many existing files.";
- case MUST_NOT_EXIST:
- return "One to many non-existing files.";
- default:
- return "One to many files.";
+ case MUST_EXIST: return "One to many existing files.";
+ case MUST_NOT_EXIST: return "One to many non-existing files.";
+ default: return "One to many files.";
}
}
+ /**
+ * Returns the list of file paths as {@link File} objects.
+ *
+ * @return a list of {@link File} objects corresponding to user input.
+ */
@Override
public List<File> getValue() {
return parameters.stream().map(File::new).collect(Collectors.toList());
}
/**
- * This method is used to define that file shall exist in filesystem.
+ * Requires that each file must already exist.
*
- * @return This object.
+ * @return this FileOptions instance for chaining
*/
public FileOptions mustExist() {
existenceType = ExistenceType.MUST_EXIST;
}
/**
- * This method is used to define that file shall not exist in filesystem.
+ * Requires that each file must not already exist.
*
- * @return This object.
+ * @return this FileOptions instance for chaining
*/
public FileOptions mustNotExist() {
existenceType = ExistenceType.MUST_NOT_EXIST;
return this;
}
+ /**
+ * Validates a single file path against the configured existence type.
+ */
@Override
public boolean isValid(final String value) {
- return validateFile(existenceType, value);
+ return FileOption.isFileValid(existenceType, value);
}
-
-}
+}
\ No newline at end of file
+/*
+ * Svjatoslav Commons - shared library of common functionality. Author: Svjatoslav Agejenko.
+ * This project is released under Creative Commons Zero (CC0) license.
+ */
package eu.svjatoslav.commons.cli_helper.parameter_parser.parameter;
import eu.svjatoslav.commons.cli_helper.parameter_parser.Option;
import eu.svjatoslav.commons.cli_helper.parameter_parser.ParameterCount;
+/**
+ * Represents a command-line option that accepts exactly one floating-point parameter.
+ */
public class FloatOption extends Option<Float, FloatOption> {
- public FloatOption(final String description) {
- super(description, ParameterCount.ONE);
- }
+ /**
+ * Constructs a FloatOption with a brief description and exactly one parameter.
+ *
+ * @param description a brief description of the option (e.g., "Scale factor").
+ */
+ public FloatOption(final String description) {
+ super(description, ParameterCount.ONE);
+ }
- @Override
- public java.lang.String describeFormat() {
- return "Floating point number. Example: 3.14";
- }
+ /**
+ * Describes the expected format ("Floating point number").
+ */
+ @Override
+ public String describeFormat() {
+ return "Floating point number. Example: 3.14";
+ }
- @Override
- public Float getValue() {
- if (parameters.size() != 1)
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
- return Float.parseFloat(parameters.get(0));
+ /**
+ * Returns the float value specified by the user.
+ *
+ * @throws RuntimeException if the user did not provide exactly one parameter.
+ */
+ @Override
+ public Float getValue() {
+ if (parameters.size() != 1) {
+ throw new RuntimeException("Parameter '" + description
+ + "' must have exactly 1 argument.");
}
+ return Float.parseFloat(parameters.get(0));
+ }
- @Override
- public boolean isValid(final java.lang.String value) {
- try {
- java.lang.Float.valueOf(value);
- return true;
- } catch (final NumberFormatException e) {
- return false;
- }
+ /**
+ * Checks if the given string can be parsed as a float.
+ *
+ * @param value the string to validate
+ * @return {@code true} if the string is a valid float, otherwise {@code false}
+ */
+ @Override
+ public boolean isValid(final String value) {
+ try {
+ Float.valueOf(value);
+ return true;
+ } catch (final NumberFormatException e) {
+ return false;
}
-}
-
+ }
+}
\ No newline at end of file
import eu.svjatoslav.commons.cli_helper.parameter_parser.Option;
/**
- * This class represents commandline option which accepts exactly one parameter
- * which is an integer.
+ * Represents a command-line option that accepts exactly one parameter interpreted as an integer.
*/
public class IntegerOption extends Option<Integer, IntegerOption> {
+ /**
+ * Constructs an IntegerOption with exactly one parameter required.
+ *
+ * @param description a brief description of what this option represents.
+ */
public IntegerOption(final String description) {
super(description, ParameterCount.ONE);
}
+ /**
+ * Describes the expected format ("Integer.").
+ */
@Override
- public java.lang.String describeFormat() {
+ public String describeFormat() {
return "Integer.";
}
+ /**
+ * Returns the integer value specified by the user.
+ *
+ * @throws RuntimeException if the user did not provide exactly one parameter.
+ */
@Override
public Integer getValue() {
- if (parameters.size() != 1)
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
+ if (parameters.size() != 1) {
+ throw new RuntimeException("Parameter '" + description
+ + "' must have exactly 1 argument.");
+ }
return Integer.parseInt(parameters.get(0));
}
+ /**
+ * Checks whether the given string can be parsed as an integer.
+ *
+ * @param value the string to validate
+ * @return {@code true} if the string is a valid integer, otherwise {@code false}
+ */
@Override
- public boolean isValid(final java.lang.String value) {
+ public boolean isValid(final String value) {
try {
- java.lang.Integer.valueOf(value);
+ Integer.valueOf(value);
return true;
} catch (final NumberFormatException e) {
return false;
import eu.svjatoslav.commons.cli_helper.parameter_parser.Option;
/**
- * This class represents commandline option which accepts exactly zero parameters.
+ * Represents a command-line option that accepts exactly zero parameters.
+ * Often used for flags that are either present or absent.
*/
public class NullOption extends Option<Boolean, NullOption> {
+ /**
+ * Creates a NullOption (e.g. a boolean flag) that requires no parameters.
+ *
+ * @param description a brief description of what this option does (e.g., "Enable debug mode").
+ */
public NullOption(final String description) {
super(description, ParameterCount.NONE);
}
+ /**
+ * Describes the expected format of this option (i.e., no parameters).
+ *
+ * @return the string "None."
+ */
@Override
- public java.lang.String describeFormat() {
+ public String describeFormat() {
return "None.";
}
+ /**
+ * Returns whether this option was present on the command line.
+ *
+ * @return {@code true} if the user specified this option, otherwise {@code false}.
+ */
@Override
public Boolean getValue() {
return isPresent();
}
+ /**
+ * Always returns {@code true}, since this option has no parameters and needs no validation.
+ */
@Override
- public boolean isValid(final java.lang.String value) {
+ public boolean isValid(final String value) {
return true;
}
-
-}
+}
\ No newline at end of file
import eu.svjatoslav.commons.cli_helper.parameter_parser.Option;
/**
- * This class represents commandline option which accepts exactly one parameter
- * which is a string.
+ * Represents a command-line option that accepts exactly one string parameter.
+ * An optional default value can be provided; if so, this option is considered "present" even without user input.
*/
public class StringOption extends Option<String, StringOption> {
+ /**
+ * Default value to return if the user does not provide a parameter.
+ * If non-null, this option is automatically considered present.
+ */
public final String defaultValue;
+ /**
+ * Constructs a StringOption with no default value.
+ *
+ * @param description a brief description of what this option does.
+ */
public StringOption(final String description) {
super(description, ParameterCount.ONE);
- defaultValue = null;
+ this.defaultValue = null;
}
+
+ /**
+ * Constructs a StringOption with a specified default value.
+ *
+ * @param description a brief description of what this option does.
+ * @param defaultValue the default string to use if the user does not supply a parameter.
+ */
public StringOption(final String description, String defaultValue) {
super(description, ParameterCount.ONE);
this.defaultValue = defaultValue;
+
+ // If a default value is provided, mark this option as present by default.
this.setPresent(true);
}
@Override
- public java.lang.String describeFormat() {
+ public String describeFormat() {
return "String.";
}
+ /**
+ * Returns the string parameter or the default value if none was provided.
+ *
+ * @throws RuntimeException if multiple parameters were provided.
+ */
@Override
public String getValue() {
-
- if (parameters.isEmpty() && (defaultValue != null)) return defaultValue;
-
- if (parameters.size() == 1) return parameters.get(0);
-
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
+ if (parameters.isEmpty() && defaultValue != null) {
+ return defaultValue;
+ }
+ if (parameters.size() == 1) {
+ return parameters.get(0);
+ }
+ throw new RuntimeException("Parameter '" + description
+ + "' must have exactly 1 argument.");
}
+ /**
+ * Always returns {@code true} since any string is considered valid for this option.
+ */
@Override
- public boolean isValid(final java.lang.String value) {
+ public boolean isValid(final String value) {
return true;
}
-
}
import java.util.List;
/**
- * This class represents commandline option which accepts one or more parameters
- * which are strings.
+ * Represents a command-line option that accepts one or more string parameters.
*/
public class StringOptions extends Option<List<String>, StringOptions> {
+ /**
+ * Creates a StringOptions object, requiring one or more string parameters.
+ *
+ * @param description a brief description of what these strings represent.
+ */
public StringOptions(final String description) {
super(description, ParameterCount.ONE_OR_MORE);
}
@Override
- public java.lang.String describeFormat() {
+ public String describeFormat() {
return "One to many string.";
}
+ /**
+ * Returns the list of strings provided by the user.
+ */
@Override
public List<String> getValue() {
return parameters;
}
+ /**
+ * Always returns true since any string is valid for this option.
+ */
@Override
- public boolean isValid(final java.lang.String value) {
+ public boolean isValid(final String value) {
return true;
}
-
-}
+}
\ No newline at end of file