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