View Javadoc

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   * Copyright 2011 Tim Wood
17   *
18   * Licensed under the Apache License, Version 2.0 (the "License");
19   * you may not use this file except in compliance with the License.
20   * You may obtain a copy of the License at
21   *
22   * http://www.apache.org/licenses/LICENSE-2.0
23   *
24   * Unless required by applicable law or agreed to in writing, software
25   * distributed under the License is distributed on an "AS IS" BASIS,
26   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27   * See the License for the specific language governing permissions and
28   * limitations under the License.
29   */
30  
31  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      private class Initial implements IParsingState {
39          @Override public IParsingState addValue(final String value) {
40              return new NoOptions(value);
41          }
42  
43          @Override public IParsingState addOption(final String option) {
44              return new OptionOrValue(option);
45          }
46      }
47  
48      private class NoOptions implements IParsingState {
49          public NoOptions(final String value) {
50              addUnparsedValue(value);
51          }
52  
53          @Override public IParsingState addValue(final String value) {
54              addUnparsedValue(value);
55              return this;
56          }
57  
58          @Override public IParsingState addOption(final String option) throws ArgumentValidationException {
59              throw misplacedOption(option);
60          }
61      }
62  
63      private class UnparsedState implements IParsingState {
64          public UnparsedState() {
65              valuesForCurrentArgument = null;
66          }
67  
68          @Override public IParsingState addValue(final String value) {
69              addUnparsedValue(value);
70              return this;
71          }
72  
73          @Override public IParsingState addOption(final String option) throws ArgumentValidationException {
74              throw misplacedOption(option);
75          }
76      }
77  
78      private class OptionOrValue implements IParsingState {
79          public OptionOrValue(final String option) {
80              addFirstValueForOption(option);
81          }
82  
83          @Override public IParsingState addValue(final String value) {
84              valuesForCurrentArgument.add(value);
85              return this;
86          }
87  
88          @Override public IParsingState addOption(final String option) {
89              return new OptionOrValue(option);
90          }
91      }
92  
93      private final Map<String, List<String>> arguments = new LinkedHashMap<String, List<String>>();
94      private final List<String> unparsed = new ArrayList<String>();
95  
96      private IParsingState state = new Initial();
97      private List<String> valuesForCurrentArgument;
98  
99      @Override
100     public void unparsedOptionsFollow() {
101         state = new UnparsedState();
102     }
103 
104     @Override
105     public void addValue(final String value)
106     {
107         state = state.addValue(value);
108     }
109 
110     @Override
111     public void addOption(final String option)
112     {
113         state = state.addOption(option);
114     }
115 
116     @Override public OptionCollection processArguments(final ArgumentValidator argumentProcessor) {
117         final Set<Entry<String, List<String>>> entrySet = arguments.entrySet();
118         final Iterator<Entry<String, List<String>>> iterator = entrySet.iterator();
119         while (iterator.hasNext()) {
120             final Map.Entry<java.lang.String, java.util.List<java.lang.String>> entry = iterator.next();
121 
122             if(iterator.hasNext()) {
123                 argumentProcessor.processOption(entry.getKey(), entry.getValue());
124             } else {
125                 argumentProcessor.processLastOption(entry.getKey(), entry.getValue());
126             }
127         }
128         argumentProcessor.processUnparsed(unparsed);
129         return argumentProcessor.finishedProcessing();
130     }
131 
132     private ArgumentValidationException misplacedOption(final String option) {
133         return new ArgumentValidationException(new ValidationFailureMisplacedOption(option));
134     }
135 
136     private void addUnparsedValue(final String value) {
137         unparsed.add(value);
138     }
139 
140     private void addFirstValueForOption(final String option) {
141        if(!arguments.containsKey(option))
142        {
143           valuesForCurrentArgument = new ArrayList<String>();
144           arguments.put(option, valuesForCurrentArgument);
145        }
146        valuesForCurrentArgument = arguments.get(option);
147     }
148 }