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 */ 017 018 package org.apache.commons.cli; 019 020 import java.io.Serializable; 021 import java.util.ArrayList; 022 import java.util.Collection; 023 import java.util.Collections; 024 import java.util.HashMap; 025 import java.util.HashSet; 026 import java.util.Iterator; 027 import java.util.List; 028 import java.util.Map; 029 030 /** 031 * <p>Main entry-point into the library.</p> 032 * 033 * <p>Options represents a collection of {@link Option} objects, which 034 * describe the possible options for a command-line.<p> 035 * 036 * <p>It may flexibly parse long and short options, with or without 037 * values. Additionally, it may parse only a portion of a commandline, 038 * allowing for flexible multi-stage parsing.<p> 039 * 040 * @see org.apache.commons.cli.CommandLine 041 * 042 * @author bob mcwhirter (bob @ werken.com) 043 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 044 * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $ 045 */ 046 public class Options implements Serializable 047 { 048 private static final long serialVersionUID = 1L; 049 050 /** a map of the options with the character key */ 051 private Map shortOpts = new HashMap(); 052 053 /** a map of the options with the long key */ 054 private Map longOpts = new HashMap(); 055 056 /** a map of the required options */ 057 private List requiredOpts = new ArrayList(); 058 059 /** a map of the option groups */ 060 private Map optionGroups = new HashMap(); 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 { 070 Iterator options = group.getOptions().iterator(); 071 072 if (group.isRequired()) 073 { 074 requiredOpts.add(group); 075 } 076 077 while (options.hasNext()) 078 { 079 Option option = (Option) options.next(); 080 081 // an Option cannot be required if it is in an 082 // OptionGroup, either the group is required or 083 // nothing is required 084 option.setRequired(false); 085 addOption(option); 086 087 optionGroups.put(option.getKey(), group); 088 } 089 090 return this; 091 } 092 093 /** 094 * Lists the OptionGroups that are members of this Options instance. 095 * 096 * @return a Collection of OptionGroup instances. 097 */ 098 Collection getOptionGroups() 099 { 100 return new HashSet(optionGroups.values()); 101 } 102 103 /** 104 * Add an option that only contains a short-name. 105 * It may be specified as requiring an argument. 106 * 107 * @param opt Short single-character name of the option. 108 * @param hasArg flag signally if an argument is required after this option 109 * @param description Self-documenting description 110 * @return the resulting Options instance 111 */ 112 public Options addOption(String opt, boolean hasArg, String description) 113 { 114 addOption(opt, null, hasArg, description); 115 116 return this; 117 } 118 119 /** 120 * Add an option that contains a short-name and a long-name. 121 * It may be specified as requiring an argument. 122 * 123 * @param opt Short single-character name of the option. 124 * @param longOpt Long multi-character name of the option. 125 * @param hasArg flag signally if an argument is required after this option 126 * @param description Self-documenting description 127 * @return the resulting Options instance 128 */ 129 public Options addOption(String opt, String longOpt, boolean hasArg, String description) 130 { 131 addOption(new Option(opt, longOpt, hasArg, description)); 132 133 return this; 134 } 135 136 /** 137 * Adds an option instance 138 * 139 * @param opt the option that is to be added 140 * @return the resulting Options instance 141 */ 142 public Options addOption(Option opt) 143 { 144 String key = opt.getKey(); 145 146 // add it to the long option list 147 if (opt.hasLongOpt()) 148 { 149 longOpts.put(opt.getLongOpt(), opt); 150 } 151 152 // if the option is required add it to the required list 153 if (opt.isRequired()) 154 { 155 if (requiredOpts.contains(key)) 156 { 157 requiredOpts.remove(requiredOpts.indexOf(key)); 158 } 159 requiredOpts.add(key); 160 } 161 162 shortOpts.put(key, opt); 163 164 return this; 165 } 166 167 /** 168 * Retrieve a read-only list of options in this set 169 * 170 * @return read-only Collection of {@link Option} objects in this descriptor 171 */ 172 public Collection getOptions() 173 { 174 return Collections.unmodifiableCollection(helpOptions()); 175 } 176 177 /** 178 * Returns the Options for use by the HelpFormatter. 179 * 180 * @return the List of Options 181 */ 182 List helpOptions() 183 { 184 return new ArrayList(shortOpts.values()); 185 } 186 187 /** 188 * Returns the required options. 189 * 190 * @return List of required options 191 */ 192 public List getRequiredOptions() 193 { 194 return requiredOpts; 195 } 196 197 /** 198 * Retrieve the {@link Option} matching the long or short name specified. 199 * The leading hyphens in the name are ignored (up to 2). 200 * 201 * @param opt short or long name of the {@link Option} 202 * @return the option represented by opt 203 */ 204 public Option getOption(String opt) 205 { 206 opt = Util.stripLeadingHyphens(opt); 207 208 if (shortOpts.containsKey(opt)) 209 { 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 of this {@link Options}. 218 * 219 * @param opt short or long name of the {@link Option} 220 * @return true if the named {@link Option} is a member 221 * of this {@link Options} 222 */ 223 public boolean hasOption(String opt) 224 { 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> belongs to. 232 * @param opt the option whose OptionGroup is being queried. 233 * 234 * @return the OptionGroup if <code>opt</code> is part 235 * of an OptionGroup, otherwise return null 236 */ 237 public OptionGroup getOptionGroup(Option opt) 238 { 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 { 249 StringBuffer buf = new StringBuffer(); 250 251 buf.append("[ Options: [ short "); 252 buf.append(shortOpts.toString()); 253 buf.append(" ] [ long "); 254 buf.append(longOpts); 255 buf.append(" ]"); 256 257 return buf.toString(); 258 } 259 }