/*
* Svjatoslav Commons - shared library of common functionality.
- * Copyright ©2012-2013, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
+ * Copyright ©2012-2017, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
* This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
+ * modify it under the terms of version 3 of the GNU Lesser General Public License
+ * or later as published by the Free Software Foundation.
*/
package eu.svjatoslav.commons.commandline.parameterparser;
-import java.io.File;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-public class Parameter {
-
- /**
- * Indicates that at least one argument is mandatory for this parameter.
- */
- private boolean mandatory;
-
- private final Argument argumentType;
-
- private final ArrayList<String> aliases = new ArrayList<String>();
-
- public final String description;
-
- protected final ArrayList<String> arguments = new ArrayList<String>();
-
- ArgumentCount argumentCount;
-
- /**
- * If this parameter was present in the commandline, then this boolean will
- * be set to <code>true</code>.
- */
- private boolean parameterSpecified;
-
- public Parameter(final Argument argumentType, final String description,
- final ArgumentCount argumentCount) {
-
- this.description = description;
- this.argumentType = argumentType;
- this.argumentCount = argumentCount;
- };
-
- public Parameter(final boolean mandatory,
- final ArgumentCount argumentCount, final Argument argumentType,
- final String description, final String... aliases2) {
-
- this.mandatory = mandatory;
- this.argumentType = argumentType;
- this.description = description;
- this.argumentCount = argumentCount;
-
- // save aliases
- for (final String alias : aliases2)
- aliases.add(alias);
-
- }
-
- public Parameter addAliases(final String... aliasArray) {
-
- // save aliases
- for (final String alias : aliasArray)
- aliases.add(alias);
-
- return this;
- }
-
- /**
- * @return <code>true</code> if no errors were found. <code>false</code>
- * otherwise.
- */
- public boolean addArgument(final String argumentString) {
- // check if arguments are allowed for this parameter
- if (argumentCount.equals(ArgumentCount.NONE)) {
- System.out
- .println("Error! No arguments are allowed for parameters: "
- + getAliases());
- return false;
- }
-
- // check if multiple arguments are allowed
- if ((arguments.size() > 0)
- && (argumentCount.equals(ArgumentCount.SINGLE))) {
- System.out
- .println("Error! Only single argument is allowed for parameters: "
- + getAliases());
- return false;
- }
-
- if (!argumentType.validate(argumentString)) {
-
- System.out.println("Error! Invalid argument \"" + argumentString
- + "\". It shall be " + argumentType.describeFormat() + ".");
- return false;
-
- }
-
- arguments.add(argumentString);
-
- return true;
- }
-
- public String getAliases() {
- final StringBuffer buffer = new StringBuffer();
-
- for (final String alias : aliases) {
-
- if (buffer.length() > 0)
- buffer.append(", ");
-
- buffer.append(alias);
- }
-
- return buffer.toString();
- }
-
- public File getArgumentAsFile() {
- if (arguments.size() != 1)
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
- return new File(arguments.get(0));
- }
-
- public int getArgumentAsInteger() {
- if (arguments.size() != 1)
- throw new RuntimeException("Parameter " + description
- + " shall have exactly 1 argument.");
- return Integer.parseInt(arguments.get(0));
- }
-
- public List<File> getArgumentsAsFiles() {
- final ArrayList<File> result = new ArrayList<File>();
-
- for (final String argument : arguments) {
- final File file = new File(argument);
- result.add(file);
- }
-
- return result;
- }
-
- public List<Integer> getArgumentsAsIntegers() {
- final ArrayList<Integer> result = new ArrayList<Integer>();
-
- for (final String argument : arguments)
- result.add(Integer.valueOf(argument));
-
- return result;
- }
-
- public List<String> getArgumentsAsStrings() {
- final ArrayList<String> result = new ArrayList<String>(arguments);
- return result;
- }
-
- public String getHelp() {
- final StringBuffer buffer = new StringBuffer();
-
- // first line
- buffer.append(getAliases());
- if (!argumentCount.equals(ArgumentCount.NONE)) {
- buffer.append(" (" + argumentType.describeFormat() + ")");
-
- if (argumentCount.equals(ArgumentCount.MULTI))
- buffer.append("...");
- }
- buffer.append("\n");
-
- // second line
- buffer.append(" " + description + "\n");
-
- return buffer.toString();
- }
-
- public boolean isMandatory() {
- return mandatory;
- }
-
- /**
- * @return the parameterSpecified
- */
- public boolean isParameterSpecified() {
- return parameterSpecified;
- }
-
- /**
- * @return <code>true</code> if given alias is registered for this
- * parameter.
- */
- public boolean matchesAlias(final String alias) {
- if (aliases.contains(alias))
- return true;
-
- return false;
- }
-
- /**
- * Notifies this parameter that no more arguments will follow. This gives
- * parameter chance to verify if this is ok.
- *
- * @return <code>true</code> if no errors were found. <code>false</code>
- * otherwise.
- */
- public boolean noMoreArguments() {
-
- if ((!argumentCount.equals(ArgumentCount.NONE))
- && (arguments.isEmpty())) {
-
- System.out.println("Error! " + getAliases()
- + " require at least one following argument.");
-
- return false;
- }
- return true;
- }
-
- public Parameter setMandatory() {
- mandatory = true;
- return this;
- }
-
- /**
- * @param parameterSpecified
- * the parameterSpecified to set
- */
- public void setParameterSpecified(final boolean parameterSpecified) {
- this.parameterSpecified = parameterSpecified;
- }
+public abstract class Parameter<T, I extends Parameter> {
+
+ /**
+ * Purpose of this argument, like: input image path, compression level, etc...
+ *
+ * Note: for describing argument type (file, integer, ...) there is {@link #describeFormat()}.
+ */
+ public final String description;
+
+ public final List<String> arguments = new ArrayList<>();
+ final ArgumentCount argumentCount;
+ private final List<String> aliases = new ArrayList<>();
+ /**
+ * Indicates that at least one argument is mandatory for this parameter.
+ */
+ protected boolean mandatory;
+ /**
+ * If this parameter was present in the commandline, then this boolean will
+ * be set to <code>true</code>.
+ */
+ private boolean specified;
+
+ public Parameter(final boolean mandatory,
+ final ArgumentCount argumentCount, final String description,
+ final String... aliases2) {
+
+ this.mandatory = mandatory;
+ this.description = description;
+ this.argumentCount = argumentCount;
+
+ // save aliases
+ Collections.addAll(aliases, aliases2);
+
+ }
+
+ public Parameter(final String description, final ArgumentCount argumentCount) {
+ this.description = description;
+ this.argumentCount = argumentCount;
+ }
+
+ @SuppressWarnings("unchecked")
+ public I addAliases(final String... aliasArray) {
+
+ // save aliases
+ Collections.addAll(aliases, aliasArray);
+
+ return (I) this;
+ }
+
+ /**
+ * @param argumentString argument to add
+ * @return <code>true</code> if no errors were found. <code>false</code>
+ * otherwise.
+ */
+ public boolean addArgument(final String argumentString) {
+ // check if arguments are allowed for this parameter
+ if (argumentCount.equals(ArgumentCount.NONE)) {
+ System.out
+ .println("Error! No arguments are allowed for parameters: "
+ + getAliases());
+ return false;
+ }
+
+ // check if multiple arguments are allowed
+ if ((arguments.size() > 0)
+ && (argumentCount.equals(ArgumentCount.SINGLE))) {
+ System.out
+ .println("Error! Only single argument is allowed for parameters: "
+ + getAliases());
+ return false;
+ }
+
+ if (!validate(argumentString)) {
+
+ System.out.println("Error! Invalid argument \"" + argumentString
+ + "\". It shall be " + describeFormat() + ".");
+ return false;
+
+ }
+
+ arguments.add(argumentString);
+
+ return true;
+ }
+
+ /**
+ * @return Single line argument type description. If argument type should be file,
+ * date, integer, regular expression, etc..
+ *
+ * Note: for argument purpose description there is {@link #description}
+ */
+ public abstract String describeFormat();
+
+ public String getAliases() {
+ final StringBuilder buffer = new StringBuilder();
+
+ for (final String alias : aliases) {
+
+ if (buffer.length() > 0)
+ buffer.append(", ");
+
+ buffer.append(alias);
+ }
+
+ return buffer.toString();
+ }
+
+ public String getHelp() {
+ final StringBuilder buffer = new StringBuilder();
+
+ // first line
+ buffer.append(getAliases());
+ if (!argumentCount.equals(ArgumentCount.NONE)) {
+ buffer
+ .append(" (")
+ .append(isMandatory() ? "mandatory, " : "")
+ .append(describeFormat())
+ .append(")");
+
+ if (argumentCount.equals(ArgumentCount.MULTI))
+ buffer.append("...");
+ }
+ buffer.append("\n");
+
+ // second line
+ buffer.append(" " + description + "\n");
+
+ return buffer.toString();
+ }
+
+ public abstract T getValue();
+
+ public boolean isMandatory() {
+ return mandatory;
+ }
+
+ /**
+ * @return the parameterSpecified
+ */
+ public boolean isSpecified() {
+ return specified;
+ }
+
+ /**
+ * @param specified the parameterSpecified to set
+ */
+ protected void setSpecified(final boolean specified) {
+ this.specified = specified;
+ }
+
+ /**
+ * @param alias alias to check against
+ * @return <code>true</code> if given alias is registered for this
+ * parameter.
+ */
+ public boolean matchesAlias(final String alias) {
+ return aliases.contains(alias);
+
+ }
+
+ /**
+ * Notifies this parameter that no more arguments will follow. This gives
+ * parameter chance to verify if this is ok.
+ *
+ * @return <code>true</code> if no errors were found. <code>false</code>
+ * otherwise.
+ */
+ public boolean noMoreArguments() {
+
+ if ((!argumentCount.equals(ArgumentCount.NONE))
+ && (arguments.isEmpty())) {
+
+ System.out.println("Error! " + getAliases()
+ + " require at least one following argument.");
+
+ return false;
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public I setMandatory() {
+ mandatory = true;
+ return (I) this;
+ }
+
+ /**
+ * @param value value to validate
+ * @return <code>true</code> if value is correct, <code>false</code>
+ * otherwise.
+ */
+ public abstract boolean validate(String value);
}