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.cli;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  
28  /*** <p>Main entry-point into the library.</p>
29   *
30   * <p>Options represents a collection of {@link Option} objects, which
31   * describe the possible options for a command-line.<p>
32   *
33   * <p>It may flexibly parse long and short options, with or without
34   * values.  Additionally, it may parse only a portion of a commandline,
35   * allowing for flexible multi-stage parsing.<p>
36   *
37   * @see org.apache.commons.cli.CommandLine
38   *
39   * @author bob mcwhirter (bob @ werken.com)
40   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
41   * @version $Revision: 542144 $
42   */
43  public class Options {
44  
45      /*** a map of the options with the character key */
46      private Map shortOpts = new HashMap();
47  
48      /*** a map of the options with the long key */
49      private Map longOpts = new HashMap();
50  
51      /*** a map of the required options */
52      private List requiredOpts = new ArrayList();
53  
54      /*** a map of the option groups */
55      private Map optionGroups = new HashMap();
56  
57      /*** Construct a new Options descriptor
58       */
59      public Options()
60      {
61          // nothing to do
62      }
63  
64      /***
65       * Add the specified option group.
66       *
67       * @param group the OptionGroup that is to be added
68       * @return the resulting Options instance
69       */
70      public Options addOptionGroup(OptionGroup group)
71      {
72          Iterator options = group.getOptions().iterator();
73  
74          if (group.isRequired())
75          {
76              requiredOpts.add(group);
77          }
78  
79          while (options.hasNext())
80          {
81              Option option = (Option) options.next();
82  
83  
84              // an Option cannot be required if it is in an
85              // OptionGroup, either the group is required or
86              // nothing is required
87              option.setRequired(false);
88              addOption(option);
89  
90              optionGroups.put(option.getKey(), group);
91          }
92  
93          return this;
94      }
95      
96      /***
97       * Lists the OptionGroups that are members of this Options instance.
98       * @return a Collection of OptionGroup instances.
99       */
100     Collection getOptionGroups(){
101     	return new HashSet(optionGroups.values());
102     }
103 
104     /*** 
105      * Add an option that only contains a short-name.
106      * It may be specified as requiring an argument.
107      *
108      * @param opt Short single-character name of the option.
109      * @param hasArg flag signally if an argument is required after this option
110      * @param description Self-documenting description
111      * @return the resulting Options instance
112      */
113     public Options addOption(String opt, boolean hasArg, String description)
114     {
115         addOption(opt, null, hasArg, description);
116 
117         return this;
118     }
119 
120     /*** 
121      * Add an option that contains a short-name and a long-name.
122      * It may be specified as requiring an argument.
123      *
124      * @param opt Short single-character name of the option.
125      * @param longOpt Long multi-character name of the option.
126      * @param hasArg flag signally if an argument is required after this option
127      * @param description Self-documenting description
128      * @return the resulting Options instance
129      */
130     public Options addOption(String opt, String longOpt, boolean hasArg, 
131                              String description)
132     {
133         addOption(new Option(opt, longOpt, hasArg, description));
134 
135         return this;
136     }
137 
138     /***
139      * Adds an option instance
140      *
141      * @param opt the option that is to be added 
142      * @return the resulting Options instance
143      */
144     public Options addOption(Option opt)
145     {
146         String key = opt.getKey();
147 
148         // add it to the long option list
149         if (opt.hasLongOpt())
150         {
151             longOpts.put(opt.getLongOpt(), opt);
152         }
153 
154         // if the option is required add it to the required list
155         if (opt.isRequired() ) 
156         {
157             if( requiredOpts.contains(key) ) {
158                 requiredOpts.remove( requiredOpts.indexOf(key) );
159             }
160             requiredOpts.add(key);
161         }
162 
163         shortOpts.put(key, opt);
164 
165         return this;
166     }
167 
168     /*** 
169      * Retrieve a read-only list of options in this set
170      *
171      * @return read-only Collection of {@link Option} objects in this descriptor
172      */
173     public Collection getOptions()
174     {
175         return Collections.unmodifiableCollection(helpOptions());
176     }
177 
178     /***
179      * Returns the Options for use by the HelpFormatter.
180      *
181      * @return the List of Options
182      */
183     List helpOptions()
184     {
185         List opts = new ArrayList(shortOpts.values());
186 
187         // now look through the long opts to see if there are any Long-opt
188         // only options
189         Iterator iter = longOpts.values().iterator();
190 
191         while (iter.hasNext())
192         {
193             Object item = iter.next();
194 
195             if (!opts.contains(item))
196             {
197                 opts.add(item);
198             }
199         }
200 
201         return new ArrayList(opts);
202     }
203 
204     /*** 
205      * Returns the required options as a
206      * <code>java.util.Collection</code>.
207      *
208      * @return Collection of required options
209      */
210     public List getRequiredOptions()
211     {
212         return requiredOpts;
213     }
214 
215     /*** 
216      * Retrieve the named {@link Option}
217      *
218      * @param opt short or long name of the {@link Option}
219      * @return the option represented by opt
220      */
221     public Option getOption(String opt)
222     {
223         opt = Util.stripLeadingHyphens(opt);
224 
225         if (shortOpts.containsKey(opt))
226         {
227             return (Option) shortOpts.get(opt);
228         }
229 
230         return (Option) longOpts.get(opt);
231     }
232 
233     /*** 
234      * Returns whether the named {@link Option} is a member
235      * of this {@link Options}.
236      *
237      * @param opt short or long name of the {@link Option}
238      * @return true if the named {@link Option} is a member
239      * of this {@link Options}
240      */
241     public boolean hasOption(String opt)
242     {
243         opt = Util.stripLeadingHyphens(opt);
244 
245         return shortOpts.containsKey(opt) || longOpts.containsKey(opt);
246     }
247 
248     /*** 
249      * Returns the OptionGroup the <code>opt</code>
250      * belongs to.
251      * @param opt the option whose OptionGroup is being queried.
252      *
253      * @return the OptionGroup if <code>opt</code> is part
254      * of an OptionGroup, otherwise return null
255      */
256     public OptionGroup getOptionGroup(Option opt)
257     {
258         return (OptionGroup) optionGroups.get(opt.getKey());
259     }
260 
261     /*** 
262      * Dump state, suitable for debugging.
263      *
264      * @return Stringified form of this object
265      */
266     public String toString()
267     {
268         StringBuffer buf = new StringBuffer();
269 
270         buf.append("[ Options: [ short ");
271         buf.append(shortOpts.toString());
272         buf.append(" ] [ long ");
273         buf.append(longOpts);
274         buf.append(" ]");
275 
276         return buf.toString();
277     }
278 }