001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.commons.cli;
017:
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: /** <p>Main entry-point into the library.</p>
028: *
029: * <p>Options represents a collection of {@link Option} objects, which
030: * describe the possible options for a command-line.<p>
031: *
032: * <p>It may flexibly parse long and short options, with or without
033: * values. Additionally, it may parse only a portion of a commandline,
034: * allowing for flexible multi-stage parsing.<p>
035: *
036: * @see org.apache.commons.cli.CommandLine
037: *
038: * @author bob mcwhirter (bob @ werken.com)
039: * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
040: * @version $Revision: 542144 $
041: */
042: public class Options {
043:
044: /** a map of the options with the character key */
045: private Map shortOpts = new HashMap();
046:
047: /** a map of the options with the long key */
048: private Map longOpts = new HashMap();
049:
050: /** a map of the required options */
051: private List requiredOpts = new ArrayList();
052:
053: /** a map of the option groups */
054: private Map optionGroups = new HashMap();
055:
056: /** Construct a new Options descriptor
057: */
058: public Options() {
059: // nothing to do
060: }
061:
062: /**
063: * Add the specified option group.
064: *
065: * @param group the OptionGroup that is to be added
066: * @return the resulting Options instance
067: */
068: public Options addOptionGroup(OptionGroup group) {
069: Iterator options = group.getOptions().iterator();
070:
071: if (group.isRequired()) {
072: requiredOpts.add(group);
073: }
074:
075: while (options.hasNext()) {
076: Option option = (Option) options.next();
077:
078: // an Option cannot be required if it is in an
079: // OptionGroup, either the group is required or
080: // nothing is required
081: option.setRequired(false);
082: addOption(option);
083:
084: optionGroups.put(option.getKey(), group);
085: }
086:
087: return this ;
088: }
089:
090: /**
091: * Lists the OptionGroups that are members of this Options instance.
092: * @return a Collection of OptionGroup instances.
093: */
094: Collection getOptionGroups() {
095: return new HashSet(optionGroups.values());
096: }
097:
098: /**
099: * Add an option that only contains a short-name.
100: * It may be specified as requiring an argument.
101: *
102: * @param opt Short single-character name of the option.
103: * @param hasArg flag signally if an argument is required after this option
104: * @param description Self-documenting description
105: * @return the resulting Options instance
106: */
107: public Options addOption(String opt, boolean hasArg,
108: String description) {
109: addOption(opt, null, hasArg, description);
110:
111: return this ;
112: }
113:
114: /**
115: * Add an option that contains a short-name and a long-name.
116: * It may be specified as requiring an argument.
117: *
118: * @param opt Short single-character name of the option.
119: * @param longOpt Long multi-character name of the option.
120: * @param hasArg flag signally if an argument is required after this option
121: * @param description Self-documenting description
122: * @return the resulting Options instance
123: */
124: public Options addOption(String opt, String longOpt,
125: boolean hasArg, String description) {
126: addOption(new Option(opt, longOpt, hasArg, description));
127:
128: return this ;
129: }
130:
131: /**
132: * Adds an option instance
133: *
134: * @param opt the option that is to be added
135: * @return the resulting Options instance
136: */
137: public Options addOption(Option opt) {
138: String key = opt.getKey();
139:
140: // add it to the long option list
141: if (opt.hasLongOpt()) {
142: longOpts.put(opt.getLongOpt(), opt);
143: }
144:
145: // if the option is required add it to the required list
146: if (opt.isRequired()) {
147: if (requiredOpts.contains(key)) {
148: requiredOpts.remove(requiredOpts.indexOf(key));
149: }
150: requiredOpts.add(key);
151: }
152:
153: shortOpts.put(key, opt);
154:
155: return this ;
156: }
157:
158: /**
159: * Retrieve a read-only list of options in this set
160: *
161: * @return read-only Collection of {@link Option} objects in this descriptor
162: */
163: public Collection getOptions() {
164: return Collections.unmodifiableCollection(helpOptions());
165: }
166:
167: /**
168: * Returns the Options for use by the HelpFormatter.
169: *
170: * @return the List of Options
171: */
172: List helpOptions() {
173: List opts = new ArrayList(shortOpts.values());
174:
175: // now look through the long opts to see if there are any Long-opt
176: // only options
177: Iterator iter = longOpts.values().iterator();
178:
179: while (iter.hasNext()) {
180: Object item = iter.next();
181:
182: if (!opts.contains(item)) {
183: opts.add(item);
184: }
185: }
186:
187: return new ArrayList(opts);
188: }
189:
190: /**
191: * Returns the required options as a
192: * <code>java.util.Collection</code>.
193: *
194: * @return Collection of required options
195: */
196: public List getRequiredOptions() {
197: return requiredOpts;
198: }
199:
200: /**
201: * Retrieve the named {@link Option}
202: *
203: * @param opt short or long name of the {@link Option}
204: * @return the option represented by opt
205: */
206: public Option getOption(String opt) {
207: opt = Util.stripLeadingHyphens(opt);
208:
209: if (shortOpts.containsKey(opt)) {
210: return (Option) shortOpts.get(opt);
211: }
212:
213: return (Option) longOpts.get(opt);
214: }
215:
216: /**
217: * Returns whether the named {@link Option} is a member
218: * of this {@link Options}.
219: *
220: * @param opt short or long name of the {@link Option}
221: * @return true if the named {@link Option} is a member
222: * of this {@link Options}
223: */
224: public boolean hasOption(String opt) {
225: opt = Util.stripLeadingHyphens(opt);
226:
227: return shortOpts.containsKey(opt) || longOpts.containsKey(opt);
228: }
229:
230: /**
231: * Returns the OptionGroup the <code>opt</code>
232: * belongs to.
233: * @param opt the option whose OptionGroup is being queried.
234: *
235: * @return the OptionGroup if <code>opt</code> is part
236: * of an OptionGroup, otherwise return null
237: */
238: public OptionGroup getOptionGroup(Option opt) {
239: return (OptionGroup) optionGroups.get(opt.getKey());
240: }
241:
242: /**
243: * Dump state, suitable for debugging.
244: *
245: * @return Stringified form of this object
246: */
247: public String toString() {
248: StringBuffer buf = new StringBuffer();
249:
250: buf.append("[ Options: [ short ");
251: buf.append(shortOpts.toString());
252: buf.append(" ] [ long ");
253: buf.append(longOpts);
254: buf.append(" ]");
255:
256: return buf.toString();
257: }
258: }
|