1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
package com.lexicalscope.jewel.cli.validation; |
16 | |
|
17 | |
import static com.lexicalscope.fluent.FluentDollar.$; |
18 | |
import static com.lexicalscope.jewel.cli.specification.OptionSpecificationMatchers.mandatory; |
19 | |
|
20 | |
import java.util.ArrayList; |
21 | |
import java.util.List; |
22 | |
import java.util.Map; |
23 | |
|
24 | |
import com.lexicalscope.fluent.map.FluentMap; |
25 | |
import com.lexicalscope.jewel.cli.ValidationErrorBuilder; |
26 | |
import com.lexicalscope.jewel.cli.specification.OptionSpecification; |
27 | |
import com.lexicalscope.jewel.cli.specification.OptionsSpecification; |
28 | |
import com.lexicalscope.jewel.cli.specification.ParsedOptionSpecification; |
29 | |
|
30 | |
class ArgumentValidatorImpl<O> implements ArgumentValidator |
31 | |
{ |
32 | |
private final ValidationErrorBuilder validationErrorBuilder; |
33 | |
|
34 | |
private final Map<RawOption, List<String>> rawArguments; |
35 | 226 | private final FluentMap<ParsedOptionSpecification, List<String>> arguments = $.<ParsedOptionSpecification, List<String>>map(); |
36 | 226 | private final FluentMap<ParsedOptionSpecification, List<String>> mandatoryArguments = $(arguments).$retainKeys(mandatory()); |
37 | |
|
38 | 226 | private final List<String> validatedUnparsedArguments = new ArrayList<String>(); |
39 | |
|
40 | |
private final OptionsSpecification<O> specification; |
41 | |
|
42 | |
public ArgumentValidatorImpl( |
43 | |
final OptionsSpecification<O> specification, |
44 | |
final ValidationErrorBuilder validationErrorBuilder) |
45 | 226 | { |
46 | 226 | this.specification = specification; |
47 | 226 | this.validationErrorBuilder = validationErrorBuilder; |
48 | |
|
49 | 226 | rawArguments = new ValidationPipeline(specification, validationErrorBuilder).buildValidationPipeline(validatedUnparsedArguments).outputTo(arguments); |
50 | 226 | } |
51 | |
|
52 | |
@Override public void processOption(final String optionName, final List<String> values) { |
53 | 78 | rawArguments.put(new RawOption(optionName), values); |
54 | 78 | } |
55 | |
|
56 | |
@Override public void processLastOption(final String optionName, final List<String> values) { |
57 | 162 | rawArguments.put(new RawOption(optionName, true), values); |
58 | 158 | } |
59 | |
|
60 | |
@Override public void processUnparsed(final List<String> values) { |
61 | 222 | validatedUnparsedArguments.addAll(values); |
62 | 222 | } |
63 | |
|
64 | |
@Override public OptionCollection finishedProcessing() { |
65 | 222 | validateUnparsedOptions(); |
66 | 222 | validationErrorBuilder.validate(); |
67 | |
|
68 | 172 | specification. |
69 | |
getMandatoryOptions(). |
70 | |
_withoutKeys(mandatoryArguments). |
71 | |
_forEach(ParsedOptionSpecification.class). |
72 | |
reportMissingTo(validationErrorBuilder); |
73 | |
|
74 | 172 | validationErrorBuilder.validate(); |
75 | |
|
76 | 160 | return new OptionCollectionImpl(specification, arguments, validatedUnparsedArguments); |
77 | |
} |
78 | |
|
79 | |
private void validateUnparsedOptions() |
80 | |
{ |
81 | 222 | if (specification.hasUnparsedSpecification()) |
82 | |
{ |
83 | 52 | final OptionSpecification unparsedSpecification = specification.getUnparsedSpecification(); |
84 | |
|
85 | 52 | if (unparsedSpecification.isOptional() && validatedUnparsedArguments.isEmpty()) |
86 | |
{ |
87 | |
|
88 | |
} |
89 | 38 | else if (!unparsedSpecification.allowedThisManyValues(validatedUnparsedArguments.size())) |
90 | |
{ |
91 | 4 | validationErrorBuilder.wrongNumberOfValues(unparsedSpecification, validatedUnparsedArguments); |
92 | |
} |
93 | 52 | } |
94 | 170 | else if (!validatedUnparsedArguments.isEmpty()) |
95 | |
{ |
96 | 2 | validationErrorBuilder.unexpectedTrailingValue(validatedUnparsedArguments); |
97 | |
} |
98 | 222 | } |
99 | |
} |