Added special commandline argument type to support multiple strings.
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / commandline / parameterparser / Parameter.java
1 /*
2  * Svjatoslav Commons - shared library of common functionality.
3  * Copyright ©2012-2014, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 3 of the GNU Lesser General Public License
7  * or later as published by the Free Software Foundation.
8  */
9
10 package eu.svjatoslav.commons.commandline.parameterparser;
11
12 import java.util.ArrayList;
13
14 public abstract class Parameter {
15
16         /**
17          * Indicates that at least one argument is mandatory for this parameter.
18          */
19         protected boolean mandatory;
20
21         private final ArrayList<String> aliases = new ArrayList<String>();
22
23         public final String description;
24
25         protected final ArrayList<String> arguments = new ArrayList<String>();
26
27         final ArgumentCount argumentCount;
28
29         /**
30          * If this parameter was present in the commandline, then this boolean will
31          * be set to <code>true</code>.
32          */
33         private boolean parameterSpecified;
34
35         public Parameter(final boolean mandatory,
36                         final ArgumentCount argumentCount, final String description,
37                         final String... aliases2) {
38
39                 this.mandatory = mandatory;
40                 this.description = description;
41                 this.argumentCount = argumentCount;
42
43                 // save aliases
44                 for (final String alias : aliases2)
45                         aliases.add(alias);
46
47         };
48
49         public Parameter(final String description, final ArgumentCount argumentCount) {
50                 this.description = description;
51                 this.argumentCount = argumentCount;
52         }
53
54         public abstract Object addAliases(final String... aliasArray);
55
56         protected Parameter addAliasesProtected(final String... aliasArray) {
57
58                 // save aliases
59                 for (final String alias : aliasArray)
60                         aliases.add(alias);
61
62                 return this;
63         }
64
65         /**
66          * @return <code>true</code> if no errors were found. <code>false</code>
67          *         otherwise.
68          */
69         public boolean addArgument(final String argumentString) {
70                 // check if arguments are allowed for this parameter
71                 if (argumentCount.equals(ArgumentCount.NONE)) {
72                         System.out
73                                         .println("Error! No arguments are allowed for parameters: "
74                                                         + getAliases());
75                         return false;
76                 }
77
78                 // check if multiple arguments are allowed
79                 if ((arguments.size() > 0)
80                                 && (argumentCount.equals(ArgumentCount.SINGLE))) {
81                         System.out
82                                         .println("Error! Only single argument is allowed for parameters: "
83                                                         + getAliases());
84                         return false;
85                 }
86
87                 if (!validate(argumentString)) {
88
89                         System.out.println("Error! Invalid argument \"" + argumentString
90                                         + "\". It shall be " + describeFormat() + ".");
91                         return false;
92
93                 }
94
95                 arguments.add(argumentString);
96
97                 return true;
98         }
99
100         /**
101          * @return Single line argument type description.
102          */
103         public abstract String describeFormat();
104
105         public String getAliases() {
106                 final StringBuffer buffer = new StringBuffer();
107
108                 for (final String alias : aliases) {
109
110                         if (buffer.length() > 0)
111                                 buffer.append(", ");
112
113                         buffer.append(alias);
114                 }
115
116                 return buffer.toString();
117         }
118
119         // public List<File> getArgumentsAsFiles() {
120         // final ArrayList<File> result = new ArrayList<File>();
121         //
122         // for (final String argument : arguments) {
123         // final File file = new File(argument);
124         // result.add(file);
125         // }
126         //
127         // return result;
128         // }
129         //
130         // public List<Integer> getArgumentsAsIntegers() {
131         // final ArrayList<Integer> result = new ArrayList<Integer>();
132         //
133         // for (final String argument : arguments)
134         // result.add(Integer.valueOf(argument));
135         //
136         // return result;
137         // }
138         //
139         // public List<String> getArgumentsAsStrings() {
140         // final ArrayList<String> result = new ArrayList<String>(arguments);
141         // return result;
142         // }
143
144         public String getHelp() {
145                 final StringBuffer buffer = new StringBuffer();
146
147                 // first line
148                 buffer.append(getAliases());
149                 if (!argumentCount.equals(ArgumentCount.NONE)) {
150                         buffer.append(" (" + describeFormat() + ")");
151
152                         if (argumentCount.equals(ArgumentCount.MULTI))
153                                 buffer.append("...");
154                 }
155                 buffer.append("\n");
156
157                 // second line
158                 buffer.append("    " + description + "\n");
159
160                 return buffer.toString();
161         }
162
163         public abstract Object getValue();
164
165         public boolean isMandatory() {
166                 return mandatory;
167         }
168
169         /**
170          * @return the parameterSpecified
171          */
172         public boolean isParameterSpecified() {
173                 return parameterSpecified;
174         }
175
176         /**
177          * @return <code>true</code> if given alias is registered for this
178          *         parameter.
179          */
180         public boolean matchesAlias(final String alias) {
181                 if (aliases.contains(alias))
182                         return true;
183
184                 return false;
185         }
186
187         /**
188          * Notifies this parameter that no more arguments will follow. This gives
189          * parameter chance to verify if this is ok.
190          *
191          * @return <code>true</code> if no errors were found. <code>false</code>
192          *         otherwise.
193          */
194         public boolean noMoreArguments() {
195
196                 if ((!argumentCount.equals(ArgumentCount.NONE))
197                                 && (arguments.isEmpty())) {
198
199                         System.out.println("Error! " + getAliases()
200                                         + " require at least one following argument.");
201
202                         return false;
203                 }
204                 return true;
205         }
206
207         public abstract Parameter setMandatory();
208
209         protected Parameter setMandatoryProtected() {
210                 mandatory = true;
211                 return this;
212         }
213
214         /**
215          * @param parameterSpecified
216          *            the parameterSpecified to set
217          */
218         public void setParameterSpecified(final boolean parameterSpecified) {
219                 this.parameterSpecified = parameterSpecified;
220         }
221
222         /**
223          * @return <code>true</code> if value is correct, <code>false</code>
224          *         otherwise.
225          */
226         public abstract boolean validate(String value);
227
228 }