View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.cli2.option;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.Comparator;
22  import java.util.List;
23  import java.util.ListIterator;
24  import java.util.Set;
25  
26  import org.apache.commons.cli2.Argument;
27  import org.apache.commons.cli2.DisplaySetting;
28  import org.apache.commons.cli2.Group;
29  import org.apache.commons.cli2.Option;
30  import org.apache.commons.cli2.OptionException;
31  import org.apache.commons.cli2.Parent;
32  import org.apache.commons.cli2.WriteableCommandLine;
33  
34  /**
35   * A base implementation of Parent providing limited ground work for further
36   * Parent implementations.
37   */
38  public abstract class ParentImpl
39      extends OptionImpl implements Parent {
40      private static final char NUL = '\0';
41      private final Group children;
42      private final Argument argument;
43      private final String description;
44  
45      protected ParentImpl(final Argument argument,
46                           final Group children,
47                           final String description,
48                           final int id,
49                           final boolean required) {
50          super(id, required);
51          this.children = children;
52          this.argument = argument;
53          this.description = description;
54      }
55  
56      /*
57       * (non-Javadoc)
58       *
59       * @see org.apache.commons.cli2.Option#process(org.apache.commons.cli2.CommandLine,
60       *      java.util.ListIterator)
61       */
62      public void process(final WriteableCommandLine commandLine,
63                          final ListIterator arguments)
64          throws OptionException {
65          if (argument != null) {
66              handleInitialSeparator(arguments, argument.getInitialSeparator());
67          }
68  
69          processParent(commandLine, arguments);
70  
71          if (argument != null) {
72              argument.processValues(commandLine, arguments, this);
73          }
74  
75          if ((children != null) && children.canProcess(commandLine, arguments)) {
76              children.process(commandLine, arguments);
77          }
78      }
79  
80      /*
81       * (non-Javadoc)
82       *
83       * @see org.apache.commons.cli2.Option#canProcess(java.lang.String)
84       */
85      public boolean canProcess(final WriteableCommandLine commandLine,
86                                final String arg) {
87          final Set triggers = getTriggers();
88  
89          if (argument != null) {
90              final char separator = argument.getInitialSeparator();
91  
92              // if there is a valid separator character
93              if (separator != NUL) {
94                  final int initialIndex = arg.indexOf(separator);
95  
96                  // if there is a separator present
97                  if (initialIndex > 0) {
98                      return triggers.contains(arg.substring(0, initialIndex));
99                  }
100             }
101         }
102 
103         return triggers.contains(arg);
104     }
105 
106     /*
107      * (non-Javadoc)
108      *
109      * @see org.apache.commons.cli2.Option#prefixes()
110      */
111     public Set getPrefixes() {
112         return (children == null) ? Collections.EMPTY_SET : children.getPrefixes();
113     }
114 
115     /*
116      * (non-Javadoc)
117      *
118      * @see org.apache.commons.cli2.Option#validate(org.apache.commons.cli2.CommandLine)
119      */
120     public void validate(WriteableCommandLine commandLine)
121         throws OptionException {
122         if (commandLine.hasOption(this)) {
123             if (argument != null) {
124                 argument.validate(commandLine, this);
125             }
126 
127             if (children != null) {
128                 children.validate(commandLine);
129             }
130         }
131     }
132 
133     /*
134      * (non-Javadoc)
135      *
136      * @see org.apache.commons.cli2.Option#appendUsage(java.lang.StringBuffer,
137      *      java.util.Set, java.util.Comparator)
138      */
139     public void appendUsage(final StringBuffer buffer,
140                             final Set helpSettings,
141                             final Comparator comp) {
142         final boolean displayArgument =
143             (this.argument != null) &&
144             helpSettings.contains(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
145         final boolean displayChildren =
146             (this.children != null) &&
147             helpSettings.contains(DisplaySetting.DISPLAY_PARENT_CHILDREN);
148 
149         if (displayArgument) {
150             buffer.append(' ');
151             argument.appendUsage(buffer, helpSettings, comp);
152         }
153 
154         if (displayChildren) {
155             buffer.append(' ');
156             children.appendUsage(buffer, helpSettings, comp);
157         }
158     }
159 
160     /**
161      * @return a description of this parent option
162      */
163     public String getDescription() {
164         return description;
165     }
166 
167     /*
168      * (non-Javadoc)
169      *
170      * @see org.apache.commons.cli2.Option#helpLines(int, java.util.Set,
171      *      java.util.Comparator)
172      */
173     public List helpLines(final int depth,
174                           final Set helpSettings,
175                           final Comparator comp) {
176         final List helpLines = new ArrayList();
177         helpLines.add(new HelpLineImpl(this, depth));
178 
179         if (helpSettings.contains(DisplaySetting.DISPLAY_PARENT_ARGUMENT) && (argument != null)) {
180             helpLines.addAll(argument.helpLines(depth + 1, helpSettings, comp));
181         }
182 
183         if (helpSettings.contains(DisplaySetting.DISPLAY_PARENT_CHILDREN) && (children != null)) {
184             helpLines.addAll(children.helpLines(depth + 1, helpSettings, comp));
185         }
186 
187         return helpLines;
188     }
189 
190     /**
191      * @return Returns the argument.
192      */
193     public Argument getArgument() {
194         return argument;
195     }
196 
197     /**
198      * @return Returns the children.
199      */
200     public Group getChildren() {
201         return children;
202     }
203 
204     /**
205      * Split the token using the specified separator character.
206      * @param arguments the current position in the arguments iterator
207      * @param separator the separator char to split on
208      */
209     private void handleInitialSeparator(final ListIterator arguments,
210                                         final char separator) {
211         // next token
212         final String newArgument = (String) arguments.next();
213 
214         // split the token
215         final int initialIndex = newArgument.indexOf(separator);
216 
217         if (initialIndex > 0) {
218             arguments.remove();
219             arguments.add(newArgument.substring(0, initialIndex));
220             String value = newArgument.substring(initialIndex + 1);
221             // The value obviously isn't an option, so we need to quote it if looks like an option.
222             // The quotes will be removed later
223             if (value.startsWith("-")) {
224                 value = '"' + value + '"';
225             }
226             arguments.add(value);
227             arguments.previous();
228         }
229 
230         arguments.previous();
231     }
232 
233     /*
234      * @see org.apache.commons.cli2.Option#findOption(java.lang.String)
235      */
236     public Option findOption(final String trigger) {
237         final Option found = super.findOption(trigger);
238 
239         if ((found == null) && (children != null)) {
240             return children.findOption(trigger);
241         } else {
242             return found;
243         }
244     }
245 
246     public void defaults(final WriteableCommandLine commandLine) {
247         super.defaults(commandLine);
248 
249         if (argument != null) {
250             argument.defaultValues(commandLine, this);
251         }
252 
253         if (children != null) {
254             children.defaults(commandLine);
255         }
256     }
257 }