Changed license to CC0
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / commandline / parameterparser / Parameter.java
1 /*
2  * Svjatoslav Commons - shared library of common functionality. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.commons.commandline.parameterparser;
6
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.List;
10
11 public abstract class Parameter<T, I extends Parameter> {
12
13     /**
14      * Purpose of this argument, like: input image path, compression level, etc...
15      *
16      * Note: for describing argument type (file, integer, ...) there is {@link #describeFormat()}.
17      */
18     public final String description;
19
20     public final List<String> arguments = new ArrayList<>();
21     final ArgumentCount argumentCount;
22     private final List<String> aliases = new ArrayList<>();
23     /**
24      * Indicates that at least one argument is mandatory for this parameter.
25      */
26     protected boolean mandatory;
27     /**
28      * If this parameter was present in the commandline, then this boolean will
29      * be set to <code>true</code>.
30      */
31     private boolean specified;
32
33     public Parameter(final boolean mandatory,
34                      final ArgumentCount argumentCount, final String description,
35                      final String... aliases2) {
36
37         this.mandatory = mandatory;
38         this.description = description;
39         this.argumentCount = argumentCount;
40
41         // save aliases
42         Collections.addAll(aliases, aliases2);
43
44     }
45
46     public Parameter(final String description, final ArgumentCount argumentCount) {
47         this.description = description;
48         this.argumentCount = argumentCount;
49     }
50
51     @SuppressWarnings("unchecked")
52     public I addAliases(final String... aliasArray) {
53
54         // save aliases
55         Collections.addAll(aliases, aliasArray);
56
57         return (I) this;
58     }
59
60     /**
61      * @param argumentString argument to add
62      * @return <code>true</code> if no errors were found. <code>false</code>
63      * otherwise.
64      */
65     public boolean addArgument(final String argumentString) {
66         // check if arguments are allowed for this parameter
67         if (argumentCount.equals(ArgumentCount.NONE)) {
68             System.out
69                     .println("Error! No arguments are allowed for parameters: "
70                             + getAliases());
71             return false;
72         }
73
74         // check if multiple arguments are allowed
75         if ((arguments.size() > 0)
76                 && (argumentCount.equals(ArgumentCount.SINGLE))) {
77             System.out
78                     .println("Error! Only single argument is allowed for parameters: "
79                             + getAliases());
80             return false;
81         }
82
83         if (!validate(argumentString)) {
84
85             System.out.println("Error! Invalid argument \"" + argumentString
86                     + "\". It shall be " + describeFormat() + ".");
87             return false;
88
89         }
90
91         arguments.add(argumentString);
92
93         return true;
94     }
95
96     /**
97      * @return Single line argument type description. If argument type should be file,
98      * date, integer, regular expression, etc..
99      *
100      * Note: for argument purpose description there is {@link #description}
101      */
102     public abstract String describeFormat();
103
104     public String getAliases() {
105         final StringBuilder buffer = new StringBuilder();
106
107         for (final String alias : aliases) {
108
109             if (buffer.length() > 0)
110                 buffer.append(", ");
111
112             buffer.append(alias);
113         }
114
115         return buffer.toString();
116     }
117
118     public String getHelp() {
119         final StringBuilder buffer = new StringBuilder();
120
121         // first line
122         buffer.append(getAliases());
123         if (!argumentCount.equals(ArgumentCount.NONE)) {
124             buffer
125                     .append(" (")
126                     .append(isMandatory() ? "mandatory, " : "")
127                     .append(describeFormat())
128                     .append(")");
129
130             if (argumentCount.equals(ArgumentCount.MULTI))
131                 buffer.append("...");
132         }
133         buffer.append("\n");
134
135         // second line
136         buffer.append("    " + description + "\n");
137
138         return buffer.toString();
139     }
140
141     public abstract T getValue();
142
143     public boolean isMandatory() {
144         return mandatory;
145     }
146
147     /**
148      * @return the parameterSpecified
149      */
150     public boolean isSpecified() {
151         return specified;
152     }
153
154     /**
155      * @param specified the parameterSpecified to set
156      */
157     protected void setSpecified(final boolean specified) {
158         this.specified = specified;
159     }
160
161     /**
162      * @param alias alias to check against
163      * @return <code>true</code> if given alias is registered for this
164      * parameter.
165      */
166     public boolean matchesAlias(final String alias) {
167         return aliases.contains(alias);
168
169     }
170
171     /**
172      * Notifies this parameter that no more arguments will follow. This gives
173      * parameter chance to verify if this is ok.
174      *
175      * @return <code>true</code> if no errors were found. <code>false</code>
176      * otherwise.
177      */
178     public boolean noMoreArguments() {
179
180         if ((!argumentCount.equals(ArgumentCount.NONE))
181                 && (arguments.isEmpty())) {
182
183             System.out.println("Error! " + getAliases()
184                     + " require at least one following argument.");
185
186             return false;
187         }
188         return true;
189     }
190
191     @SuppressWarnings("unchecked")
192     public I setMandatory() {
193         mandatory = true;
194         return (I) this;
195     }
196
197     /**
198      * @param value value to validate
199      * @return <code>true</code> if value is correct, <code>false</code>
200      * otherwise.
201      */
202     public abstract boolean validate(String value);
203
204 }