Added FileParameters type.
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / commandline / parameterparser / Parameter.java
index 1e738a5..8208583 100755 (executable)
 /*
  * 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 {
+public abstract class Parameter<T, I extends Parameter> {
 
-       /**
-        * Indicates that at least one argument is mandatory for this parameter.
-        */
-       private final boolean mandatory;
-
-       private final boolean enableArguments;
-
-       private final boolean enableMultipleArguments;
-
-       private final Argument argumentType;
-
-       private final ArrayList<String> aliases;
-
-       private final String description;
-
-       private final ArrayList<String> arguments = new ArrayList<String>();
-
-       /**
-        * If this parameter was present in the commandline, then this boolean will
-        * be set to <code>true</code>.
-        */
-       private boolean parameterSpecified;
-
-       public Parameter(final boolean mandatory, final boolean enableArguments,
-                       final boolean enableMultipleArguments, final Argument argumentType,
-                       final String description, final String... aliases) {
-
-               this.mandatory = mandatory;
-               this.enableArguments = enableArguments;
-               this.enableMultipleArguments = enableMultipleArguments;
-               this.argumentType = argumentType;
-               this.description = description;
-
-               // save aliases
-               {
-                       final ArrayList<String> aliasesList = new ArrayList<String>();
-                       for (final String alias : aliases)
-                               aliasesList.add(alias);
-                       this.aliases = aliasesList;
-               }
-
-       }
-
-       public Parameter(final String description, final String... aliases) {
-               this(false, false, false, null, description, aliases);
-       }
-
-       /**
-        * @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 (!enableArguments) {
-                       System.out
-                                       .println("Error! No arguments are allowed for parameters: "
-                                                       + getAliases());
-                       return false;
-               }
-
-               // check if multiple arguments are allowed
-               if ((arguments.size() > 0) && (!enableMultipleArguments)) {
-                       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 String getArgumentAsString() {
-               if (arguments.size() != 1)
-                       throw new RuntimeException("Parameter " + description
-                                       + " shall have exactly 1 argument.");
-               return 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 (enableArguments) {
-                       buffer.append(" (" + argumentType.describeFormat() + ")");
-
-                       if (enableMultipleArguments)
-                               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 (enableArguments && (arguments.isEmpty())) {
-
-                       System.out.println("Error! " + getAliases()
-                                       + " require at least one following argument.");
-
-                       return false;
-               }
-               return true;
-       }
-
-       /**
-        * @param parameterSpecified
-        *            the parameterSpecified to set
-        */
-       public void setParameterSpecified(final boolean parameterSpecified) {
-               this.parameterSpecified = parameterSpecified;
-       }
+    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.
+     */
+    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);
 
 }