View Javadoc
1   package org.cyclopsgroup.jcli.jline;
2   
3   import java.util.Collections;
4   import java.util.HashSet;
5   import java.util.Set;
6   
7   import org.cyclopsgroup.jcli.spi.Option;
8   import org.cyclopsgroup.jcli.spi.ParsingContext;
9   
10  /**
11   * Class that consumes arguments
12   *
13   * @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
14   */
15  class ArgumentsInspector {
16    private final ParsingContext context;
17  
18    private Option currentOption;
19  
20    private String currentValue;
21  
22    private final Set<Option> remainingOptions;
23  
24    private ArgumentsInspectorState state = ArgumentsInspectorState.READY;
25  
26    /**
27     * @param context Parsing context
28     */
29    ArgumentsInspector(ParsingContext context) {
30      this.context = context;
31      remainingOptions = new HashSet<Option>(context.options());
32    }
33  
34    /**
35     * @param argument Argument to consume
36     */
37    void consume(String argument) {
38      if (argument.startsWith("--")) {
39        state = ArgumentsInspectorState.LONG_OPTION;
40      } else if (argument.startsWith("-")) {
41        state = ArgumentsInspectorState.OPTION;
42      } else {
43        switch (state) {
44          case READY:
45            state = ArgumentsInspectorState.ARGUMENT;
46            break;
47          case OPTION:
48            currentOption = context.optionWithShortName(currentValue.substring(1));
49          case LONG_OPTION:
50            if (state == ArgumentsInspectorState.LONG_OPTION) {
51              currentOption = context.optionWithLongName(currentValue.substring(2));
52            }
53            if (currentOption != null && !currentOption.isMultiValue()) {
54              remainingOptions.remove(currentOption);
55            }
56            if (currentOption == null || currentOption.isFlag()) {
57              state = ArgumentsInspectorState.ARGUMENT;
58            } else {
59              state = ArgumentsInspectorState.OPTION_VALUE;
60            }
61            break;
62          case OPTION_VALUE:
63          case ARGUMENT:
64            state = ArgumentsInspectorState.ARGUMENT;
65            break;
66          default:
67            throw new IllegalStateException();
68        }
69      }
70      currentValue = argument;
71    }
72  
73    /**
74     * End the process
75     */
76    void end() {
77      switch (state) {
78        case OPTION:
79          currentOption = context.optionWithShortName(currentValue.substring(1));
80        case LONG_OPTION:
81          if (state == ArgumentsInspectorState.LONG_OPTION) {
82            currentOption = context.optionWithLongName(currentValue.substring(2));
83          }
84          if (currentOption != null && !currentOption.isMultiValue()) {
85            remainingOptions.remove(currentOption);
86          }
87          if (currentOption == null || currentOption.isFlag()) {
88            state = ArgumentsInspectorState.ARGUMENT;
89          } else {
90            state = ArgumentsInspectorState.OPTION_VALUE;
91          }
92          break;
93        default:
94          state = ArgumentsInspectorState.READY;
95      }
96      currentValue = null;
97    }
98  
99    /**
100    * @return The option being processed currently
101    */
102   Option getCurrentOption() {
103     return currentOption;
104   }
105 
106   /**
107    * @return Current value
108    */
109   String getCurrentValue() {
110     return currentValue;
111   }
112 
113   /**
114    * @return Set of remaining options
115    */
116   Set<Option> getRemainingOptions() {
117     return Collections.unmodifiableSet(remainingOptions);
118   }
119 
120   /**
121    * @return Current parsing state
122    */
123   ArgumentsInspectorState getState() {
124     return state;
125   }
126 }