1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package info.rolandkrueger.roklib.cli;
26
27 import java.util.HashSet;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Set;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public class CommandLineOption
99 {
100 private String mShortOptionName;
101 private String mLongOptionName;
102 private String mDescription;
103 private CommandLineOptionType mType;
104 private boolean mIsSet = false;
105 private boolean mMandatory = false;
106 private boolean mDefaultValueSet = false;
107 private List<String> mValues;
108 private boolean mRepetionsAllowed = false;
109 private int mRepetitionCount = 0;
110
111
112
113
114 private Set<CommandLineOption> mMutuallyExclusiveOptions;
115
116
117
118
119
120 private Set<CommandLineOption> mAssociateOptions;
121
122 private ICommandLineOptionCallback mCallback;
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public CommandLineOption (Character shortOption, String longOption, String description,
147 CommandLineOptionType type, boolean mandatory, ICommandLineOptionCallback callback)
148 {
149 this ();
150 setCallback (callback);
151 if (type == CommandLineOptionType.FLAG && mandatory == true)
152 throw new IllegalArgumentException ("A flag option must not be mandatory.");
153 if (shortOption == null)
154 mShortOptionName = "";
155 else
156 mShortOptionName = String.valueOf (shortOption);
157 if (longOption == null) longOption = "";
158 if (mShortOptionName.equals ("") && longOption.equals (""))
159 throw new IllegalArgumentException ("Short and long option must not be both empty");
160 mLongOptionName = longOption;
161 mType = type;
162 mMandatory = mandatory;
163 if (description == null) description = "";
164 mDescription = description;
165 }
166
167 public CommandLineOption (Character shortOption, String longOption, String description,
168 CommandLineOptionType type)
169 {
170 this (shortOption, longOption, description, type, false);
171 }
172
173 public CommandLineOption (Character shortOption, String longOption, String description,
174 CommandLineOptionType type, boolean mandatory)
175 {
176 this (shortOption, longOption, description, type, mandatory, new EmptyCallback ());
177 }
178
179
180
181
182 private CommandLineOption ()
183 {
184 mCallback = new EmptyCallback ();
185 mValues = new LinkedList<String> ();
186 mShortOptionName = "";
187 mLongOptionName = "";
188 }
189
190
191
192
193 public CommandLineOption (Character shortOption, String longOption, CommandLineOptionType type,
194 boolean mandatory)
195 {
196 this (shortOption, longOption, "", type, mandatory);
197 }
198
199 public void setCallback (ICommandLineOptionCallback callback)
200 {
201 if (callback == null) throw new NullPointerException ("Callback is null");
202 mCallback = callback;
203 }
204
205 public void allowOptionRepetition (boolean yesNo)
206 {
207 if (yesNo == true && mType == CommandLineOptionType.SINGULAR)
208 throw new IllegalStateException ("Cannot allow option repetition for single value options.");
209
210 mRepetionsAllowed = yesNo;
211 }
212
213 public void setMandatory (boolean mandatory)
214 {
215 if (isFlag ()) throw new IllegalStateException ("A flag option must not be mandatory.");
216 mMandatory = mandatory;
217 }
218
219 public boolean isOptionRepetitionAllowed ()
220 {
221 return mRepetionsAllowed;
222 }
223
224
225
226
227
228
229 public boolean isFlag ()
230 {
231 return mType == CommandLineOptionType.FLAG;
232 }
233
234 protected void invokeCallback (CommandLineArgumentEvaluator source)
235 {
236 mCallback.optionIsSet (source, mValues);
237 }
238
239
240
241
242
243
244
245
246
247
248 public boolean isSet ()
249 {
250 return mIsSet;
251 }
252
253 public void addAssociateOptions (CommandLineOption... associates)
254 {
255
256
257
258 for (CommandLineOption option : associates)
259 if (isMutuallyExclusiveWith (option))
260 throw new IllegalArgumentException (String.format (
261 "Option %s is already defined to be mutually " + "exclusive to this option.", option));
262
263 if (mAssociateOptions == null) mAssociateOptions = new HashSet<CommandLineOption> ();
264
265 for (CommandLineOption option : associates)
266 mAssociateOptions.add (option);
267 }
268
269 public void addMutuallyExclusiveOptions (CommandLineOption... otherOptions)
270 {
271
272
273
274
275 if (mMutuallyExclusiveOptions == null)
276 mMutuallyExclusiveOptions = new HashSet<CommandLineOption> ();
277
278 for (CommandLineOption option : otherOptions)
279 {
280 if (isAssociateTo (option))
281 throw new IllegalArgumentException (String.format (
282 "Option %s is already defined as an associate option " + "to this option.", option));
283
284
285
286 if (isMandatory () || option.isMandatory ())
287 throw new IllegalArgumentException (String.format (
288 "Both this option and option %s which shall be " + "mutually exclusive are mandatory.",
289 option));
290
291
292
293
294 if (isSet () || option.isSet ())
295 throw new IllegalArgumentException (String.format (
296 "Cannot add to mutually exclusive relationship. Either "
297 + "this option, both options or option %s are already set.", option));
298
299 mMutuallyExclusiveOptions.add (option);
300 if (! option.isMutuallyExclusiveWith (this)) option.addMutuallyExclusiveOptions (this);
301 }
302 }
303
304 public boolean isMutuallyExclusiveWith (CommandLineOption otherOption)
305 {
306 if (mMutuallyExclusiveOptions == null) return false;
307 return (mMutuallyExclusiveOptions.contains (otherOption));
308 }
309
310 public boolean isAssociateTo (CommandLineOption otherOption)
311 {
312 if (mAssociateOptions == null) return false;
313 return (mAssociateOptions.contains (otherOption));
314 }
315
316
317
318
319
320
321
322
323
324
325 public String[] getInputList ()
326 {
327 if (mValues.size () == 0) return new String[] {};
328 String[] result = new String[mValues.size ()];
329 mValues.toArray (result);
330 return result;
331 }
332
333 public String getSingleParameterValue ()
334 {
335 if (mType == CommandLineOptionType.FLAG)
336 throw new IllegalStateException (
337 "This command line option is of type FLAG. It cannot provide a value.");
338 if (! isSet ()) throw new IllegalStateException ("This option has not been set.");
339 assert mValues.size () != 0;
340 return mValues.get (0);
341 }
342
343
344
345
346 protected void set ()
347 {
348 mIsSet = true;
349 }
350
351
352
353
354
355
356 public boolean isMandatory ()
357 {
358 return mMandatory;
359 }
360
361 protected boolean addUserInput (String input)
362 {
363
364
365 if (mDefaultValueSet)
366 {
367 mValues.clear ();
368 mDefaultValueSet = false;
369 }
370 set ();
371
372 if (mType == CommandLineOptionType.SINGULAR && mValues.size () == 1) return false;
373
374 if (mType == CommandLineOptionType.FLAG) return false;
375
376
377 mValues.add (input);
378 return true;
379 }
380
381 @Override
382 public boolean equals (Object obj)
383 {
384 if (obj == null) return false;
385 if (obj == this) return true;
386 if (obj instanceof CommandLineOption)
387 {
388 CommandLineOption other = (CommandLineOption) obj;
389 if (! mLongOptionName.equals ("") && mLongOptionName.equals (other.mLongOptionName))
390 return true;
391 if (! mShortOptionName.equals ("") && mShortOptionName.equals (other.mShortOptionName))
392 return true;
393 }
394 return false;
395 }
396
397 @Override
398 public int hashCode ()
399 {
400 return super.hashCode ();
401 }
402
403
404
405
406
407
408 public String getDescription ()
409 {
410 return mDescription;
411 }
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 public void addDefaultValue (String defaultValue)
441 {
442 if (mType == CommandLineOptionType.FLAG)
443 throw new IllegalStateException ("Cannot set default value for a flag option.");
444 if (mMandatory)
445 throw new IllegalStateException (
446 "Setting a default value of a mandatory option is not allowed.");
447 if (mMutuallyExclusiveOptions != null && mMutuallyExclusiveOptions.size () > 0)
448 throw new IllegalStateException (
449 "This option is already part of a mutually exclusive relationship.");
450
451 if (mType == CommandLineOptionType.SINGULAR)
452 {
453 mValues = new LinkedList<String> ();
454 }
455 mValues.add (defaultValue);
456 mDefaultValueSet = true;
457 set ();
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471
472 public void addDefaultValues (String... values)
473 {
474 if (mType == CommandLineOptionType.FLAG)
475 throw new UnsupportedOperationException ("Cannot set a default value for a flag option.");
476 if (values.length > 1 && mType == CommandLineOptionType.SINGULAR)
477 throw new UnsupportedOperationException ("Cannot set more than one default value "
478 + "for a singular option. Use setDefaultValue(String) instead.");
479 for (String value : values)
480 {
481 addDefaultValue (value);
482 }
483 }
484
485
486
487
488
489
490 public String getLongOption ()
491 {
492 return mLongOptionName;
493 }
494
495
496
497
498
499
500 public String getShortOption ()
501 {
502 return mShortOptionName;
503 }
504
505 public CommandLineOptionType getType ()
506 {
507 return mType;
508 }
509
510 public void increaseRepetitions ()
511 {
512 mRepetitionCount++;
513 }
514
515 public int getRepetitionCount ()
516 {
517 return mRepetitionCount;
518 }
519
520 @Override
521 public String toString ()
522 {
523 StringBuilder buf = new StringBuilder ();
524 buf.append ("['").append (mShortOptionName).append ("', '");
525 buf.append (mLongOptionName).append ("', ").append ("'");
526 buf.append (mDescription).append ("', ");
527 buf.append (mType.toString ());
528 buf.append (", mandatory=").append (mMandatory);
529 buf.append ("]");
530 return buf.toString ();
531 }
532
533 private static class EmptyCallback implements ICommandLineOptionCallback
534 {
535 public void optionIsSet (CommandLineArgumentEvaluator source, List<String> paramValues)
536 {
537 };
538 }
539 }