fd22c89b2e2ae917c7803837ff45b787efae1799
[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<T> {
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         public 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 T addAliases(final String... aliasArray) {
55
56                 // save aliases
57                 for (final String alias : aliasArray)
58                         aliases.add(alias);
59
60                 return (T) this;
61         }
62
63         /**
64          * @return <code>true</code> if no errors were found. <code>false</code>
65          *         otherwise.
66          */
67         public boolean addArgument(final String argumentString) {
68                 // check if arguments are allowed for this parameter
69                 if (argumentCount.equals(ArgumentCount.NONE)) {
70                         System.out
71                                         .println("Error! No arguments are allowed for parameters: "
72                                                         + getAliases());
73                         return false;
74                 }
75
76                 // check if multiple arguments are allowed
77                 if ((arguments.size() > 0)
78                                 && (argumentCount.equals(ArgumentCount.SINGLE))) {
79                         System.out
80                                         .println("Error! Only single argument is allowed for parameters: "
81                                                         + getAliases());
82                         return false;
83                 }
84
85                 if (!validate(argumentString)) {
86
87                         System.out.println("Error! Invalid argument \"" + argumentString
88                                         + "\". It shall be " + describeFormat() + ".");
89                         return false;
90
91                 }
92
93                 arguments.add(argumentString);
94
95                 return true;
96         }
97
98         /**
99          * @return Single line argument type description.
100          */
101         public abstract String describeFormat();
102
103         public String getAliases() {
104                 final StringBuffer buffer = new StringBuffer();
105
106                 for (final String alias : aliases) {
107
108                         if (buffer.length() > 0)
109                                 buffer.append(", ");
110
111                         buffer.append(alias);
112                 }
113
114                 return buffer.toString();
115         }
116
117         public String getHelp() {
118                 final StringBuffer buffer = new StringBuffer();
119
120                 // first line
121                 buffer.append(getAliases());
122                 if (!argumentCount.equals(ArgumentCount.NONE)) {
123                         buffer.append(" (" + describeFormat() + ")");
124
125                         if (argumentCount.equals(ArgumentCount.MULTI))
126                                 buffer.append("...");
127                 }
128                 buffer.append("\n");
129
130                 // second line
131                 buffer.append("    " + description + "\n");
132
133                 return buffer.toString();
134         }
135
136         public abstract Object getValue();
137
138         public boolean isMandatory() {
139                 return mandatory;
140         }
141
142         /**
143          * @return the parameterSpecified
144          */
145         public boolean isParameterSpecified() {
146                 return parameterSpecified;
147         }
148
149         /**
150          * @return <code>true</code> if given alias is registered for this
151          *         parameter.
152          */
153         public boolean matchesAlias(final String alias) {
154                 if (aliases.contains(alias))
155                         return true;
156
157                 return false;
158         }
159
160         /**
161          * Notifies this parameter that no more arguments will follow. This gives
162          * parameter chance to verify if this is ok.
163          *
164          * @return <code>true</code> if no errors were found. <code>false</code>
165          *         otherwise.
166          */
167         public boolean noMoreArguments() {
168
169                 if ((!argumentCount.equals(ArgumentCount.NONE))
170                                 && (arguments.isEmpty())) {
171
172                         System.out.println("Error! " + getAliases()
173                                         + " require at least one following argument.");
174
175                         return false;
176                 }
177                 return true;
178         }
179
180         public T setMandatory() {
181                 mandatory = true;
182                 return (T) this;
183         }
184
185         /**
186          * @param parameterSpecified
187          *            the parameterSpecified to set
188          */
189         public void setParameterSpecified(final boolean parameterSpecified) {
190                 this.parameterSpecified = parameterSpecified;
191         }
192
193         /**
194          * @return <code>true</code> if value is correct, <code>false</code>
195          *         otherwise.
196          */
197         public abstract boolean validate(String value);
198
199 }