1 | |
package com.lexicalscope.jewel.cli; |
2 | |
|
3 | |
import java.util.ArrayList; |
4 | |
import java.util.Iterator; |
5 | |
import java.util.LinkedHashMap; |
6 | |
import java.util.List; |
7 | |
import java.util.Map; |
8 | |
import java.util.Map.Entry; |
9 | |
import java.util.Set; |
10 | |
|
11 | |
import com.lexicalscope.jewel.cli.parser.ParsedArguments; |
12 | |
import com.lexicalscope.jewel.cli.validation.ArgumentValidator; |
13 | |
import com.lexicalscope.jewel.cli.validation.OptionCollection; |
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
|
29 | |
|
30 | |
|
31 | 810 | public class ArgumentCollectionBuilder implements ParsedArguments { |
32 | |
private interface IParsingState { |
33 | |
IParsingState addValue(String value); |
34 | |
|
35 | |
IParsingState addOption(String option) throws ArgumentValidationException; |
36 | |
} |
37 | |
|
38 | 484 | private class Initial implements IParsingState { |
39 | |
@Override public IParsingState addValue(final String value) { |
40 | 20 | return new NoOptions(value); |
41 | |
} |
42 | |
|
43 | |
@Override public IParsingState addOption(final String option) { |
44 | 164 | return new OptionOrValue(option); |
45 | |
} |
46 | |
} |
47 | |
|
48 | |
private class NoOptions implements IParsingState { |
49 | 20 | public NoOptions(final String value) { |
50 | 20 | addUnparsedValue(value); |
51 | 20 | } |
52 | |
|
53 | |
@Override public IParsingState addValue(final String value) { |
54 | 16 | addUnparsedValue(value); |
55 | 16 | return this; |
56 | |
} |
57 | |
|
58 | |
@Override public IParsingState addOption(final String option) throws ArgumentValidationException { |
59 | 6 | throw misplacedOption(option); |
60 | |
} |
61 | |
} |
62 | |
|
63 | |
private class UnparsedState implements IParsingState { |
64 | 8 | public UnparsedState() { |
65 | 8 | valuesForCurrentArgument = null; |
66 | 8 | } |
67 | |
|
68 | |
@Override public IParsingState addValue(final String value) { |
69 | 12 | addUnparsedValue(value); |
70 | 12 | return this; |
71 | |
} |
72 | |
|
73 | |
@Override public IParsingState addOption(final String option) throws ArgumentValidationException { |
74 | 0 | throw misplacedOption(option); |
75 | |
} |
76 | |
} |
77 | |
|
78 | |
private class OptionOrValue implements IParsingState { |
79 | 248 | public OptionOrValue(final String option) { |
80 | 248 | addFirstValueForOption(option); |
81 | 248 | } |
82 | |
|
83 | |
@Override public IParsingState addValue(final String value) { |
84 | 258 | valuesForCurrentArgument.add(value); |
85 | 258 | return this; |
86 | |
} |
87 | |
|
88 | |
@Override public IParsingState addOption(final String option) { |
89 | 84 | return new OptionOrValue(option); |
90 | |
} |
91 | |
} |
92 | |
|
93 | 242 | private final Map<String, List<String>> arguments = new LinkedHashMap<String, List<String>>(); |
94 | 242 | private final List<String> unparsed = new ArrayList<String>(); |
95 | |
|
96 | 242 | private IParsingState state = new Initial(); |
97 | |
private List<String> valuesForCurrentArgument; |
98 | |
|
99 | |
@Override |
100 | |
public void unparsedOptionsFollow() { |
101 | 8 | state = new UnparsedState(); |
102 | 8 | } |
103 | |
|
104 | |
@Override |
105 | |
public void addValue(final String value) |
106 | |
{ |
107 | 306 | state = state.addValue(value); |
108 | 306 | } |
109 | |
|
110 | |
@Override |
111 | |
public void addOption(final String option) |
112 | |
{ |
113 | 254 | state = state.addOption(option); |
114 | 248 | } |
115 | |
|
116 | |
@Override public OptionCollection processArguments(final ArgumentValidator argumentProcessor) { |
117 | 236 | final Set<Entry<String, List<String>>> entrySet = arguments.entrySet(); |
118 | 236 | final Iterator<Entry<String, List<String>>> iterator = entrySet.iterator(); |
119 | 478 | while (iterator.hasNext()) { |
120 | 246 | final Map.Entry<java.lang.String, java.util.List<java.lang.String>> entry = iterator.next(); |
121 | |
|
122 | 246 | if(iterator.hasNext()) { |
123 | 82 | argumentProcessor.processOption(entry.getKey(), entry.getValue()); |
124 | |
} else { |
125 | 164 | argumentProcessor.processLastOption(entry.getKey(), entry.getValue()); |
126 | |
} |
127 | 242 | } |
128 | 232 | argumentProcessor.processUnparsed(unparsed); |
129 | 232 | return argumentProcessor.finishedProcessing(); |
130 | |
} |
131 | |
|
132 | |
private ArgumentValidationException misplacedOption(final String option) { |
133 | 6 | return new ArgumentValidationException(new ValidationFailureMisplacedOption(option)); |
134 | |
} |
135 | |
|
136 | |
private void addUnparsedValue(final String value) { |
137 | 48 | unparsed.add(value); |
138 | 48 | } |
139 | |
|
140 | |
private void addFirstValueForOption(final String option) { |
141 | 248 | if(!arguments.containsKey(option)) |
142 | |
{ |
143 | 246 | valuesForCurrentArgument = new ArrayList<String>(); |
144 | 246 | arguments.put(option, valuesForCurrentArgument); |
145 | |
} |
146 | 248 | valuesForCurrentArgument = arguments.get(option); |
147 | 248 | } |
148 | |
} |