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 018package org.apache.commons.cli; 019 020/** 021 * OptionBuilder allows the user to create Options using descriptive methods. 022 * <p> 023 * Details on the Builder pattern can be found at 024 * <a href="http://c2.com/cgi-bin/wiki?BuilderPattern">http://c2.com/cgi-bin/wiki?BuilderPattern</a>. 025 * <p> 026 * This class is NOT thread safe. See <a href="https://issues.apache.org/jira/browse/CLI-209">CLI-209</a> 027 * 028 * @since 1.0 029 * @deprecated since 1.3, use {@link Option#builder(String)} instead 030 */ 031@Deprecated 032public final class OptionBuilder { 033 034 /** Long option */ 035 private static String longOption; 036 037 /** Option description */ 038 private static String description; 039 040 /** Argument name */ 041 private static String argName; 042 043 /** Is required? */ 044 private static boolean required; 045 046 /** The number of arguments */ 047 private static int argCount = Option.UNINITIALIZED; 048 049 /** Option type */ 050 private static Class<?> type; 051 052 /** Option can have an optional argument value */ 053 private static boolean optionalArg; 054 055 /** Value separator for argument value */ 056 private static char valueSeparator; 057 058 /** Option builder instance */ 059 private static final OptionBuilder INSTANCE = new OptionBuilder(); 060 061 static { 062 // ensure the consistency of the initial values 063 reset(); 064 } 065 066 /** 067 * Creates an Option using the current settings 068 * 069 * @return the Option instance 070 * @throws IllegalArgumentException if {@code longOpt} has not been set. 071 */ 072 public static Option create() throws IllegalArgumentException { 073 if (longOption == null) { 074 OptionBuilder.reset(); 075 throw new IllegalArgumentException("must specify longopt"); 076 } 077 078 return create(null); 079 } 080 081 /** 082 * Creates an Option using the current settings and with the specified Option {@code char}. 083 * 084 * @param opt the character representation of the Option 085 * @return the Option instance 086 * @throws IllegalArgumentException if {@code opt} is not a valid character. See Option. 087 */ 088 public static Option create(final char opt) throws IllegalArgumentException { 089 return create(String.valueOf(opt)); 090 } 091 092 /** 093 * Creates an Option using the current settings and with the specified Option {@code char}. 094 * 095 * @param opt the {@code java.lang.String} representation of the Option 096 * @return the Option instance 097 * @throws IllegalArgumentException if {@code opt} is not a valid character. See Option. 098 */ 099 public static Option create(final String opt) throws IllegalArgumentException { 100 Option option; 101 try { 102 // create the option 103 option = new Option(opt, description); 104 105 // set the option properties 106 option.setLongOpt(longOption); 107 option.setRequired(required); 108 option.setOptionalArg(optionalArg); 109 option.setArgs(argCount); 110 option.setType(type); 111 option.setValueSeparator(valueSeparator); 112 option.setArgName(argName); 113 } finally { 114 // reset the OptionBuilder properties 115 OptionBuilder.reset(); 116 } 117 118 // return the Option instance 119 return option; 120 } 121 122 /** 123 * The next Option created will require an argument value. 124 * 125 * @return the OptionBuilder instance 126 */ 127 public static OptionBuilder hasArg() { 128 OptionBuilder.argCount = 1; 129 130 return INSTANCE; 131 } 132 133 /** 134 * The next Option created will require an argument value if {@code hasArg} is true. 135 * 136 * @param hasArg if true then the Option has an argument value 137 * @return the OptionBuilder instance 138 */ 139 public static OptionBuilder hasArg(final boolean hasArg) { 140 OptionBuilder.argCount = hasArg ? 1 : Option.UNINITIALIZED; 141 142 return INSTANCE; 143 } 144 145 /** 146 * The next Option created can have unlimited argument values. 147 * 148 * @return the OptionBuilder instance 149 */ 150 public static OptionBuilder hasArgs() { 151 OptionBuilder.argCount = Option.UNLIMITED_VALUES; 152 153 return INSTANCE; 154 } 155 156 /** 157 * The next Option created can have {@code num} argument values. 158 * 159 * @param num the number of args that the option can have 160 * @return the OptionBuilder instance 161 */ 162 public static OptionBuilder hasArgs(final int num) { 163 OptionBuilder.argCount = num; 164 165 return INSTANCE; 166 } 167 168 /** 169 * The next Option can have an optional argument. 170 * 171 * @return the OptionBuilder instance 172 */ 173 public static OptionBuilder hasOptionalArg() { 174 OptionBuilder.argCount = 1; 175 OptionBuilder.optionalArg = true; 176 177 return INSTANCE; 178 } 179 180 /** 181 * The next Option can have an unlimited number of optional arguments. 182 * 183 * @return the OptionBuilder instance 184 */ 185 public static OptionBuilder hasOptionalArgs() { 186 OptionBuilder.argCount = Option.UNLIMITED_VALUES; 187 OptionBuilder.optionalArg = true; 188 189 return INSTANCE; 190 } 191 192 /** 193 * The next Option can have the specified number of optional arguments. 194 * 195 * @param numArgs - the maximum number of optional arguments the next Option created can have. 196 * @return the OptionBuilder instance 197 */ 198 public static OptionBuilder hasOptionalArgs(final int numArgs) { 199 OptionBuilder.argCount = numArgs; 200 OptionBuilder.optionalArg = true; 201 202 return INSTANCE; 203 } 204 205 /** 206 * The next Option created will be required. 207 * 208 * @return the OptionBuilder instance 209 */ 210 public static OptionBuilder isRequired() { 211 OptionBuilder.required = true; 212 213 return INSTANCE; 214 } 215 216 /** 217 * The next Option created will be required if {@code required} is true. 218 * 219 * @param newRequired if true then the Option is required 220 * @return the OptionBuilder instance 221 */ 222 public static OptionBuilder isRequired(final boolean newRequired) { 223 OptionBuilder.required = newRequired; 224 225 return INSTANCE; 226 } 227 228 /** 229 * Resets the member variables to their default values. 230 */ 231 private static void reset() { 232 description = null; 233 argName = null; 234 longOption = null; 235 type = String.class; 236 required = false; 237 argCount = Option.UNINITIALIZED; 238 optionalArg = false; 239 valueSeparator = (char) 0; 240 } 241 242 /** 243 * The next Option created will have the specified argument value name. 244 * 245 * @param name the name for the argument value 246 * @return the OptionBuilder instance 247 */ 248 public static OptionBuilder withArgName(final String name) { 249 OptionBuilder.argName = name; 250 251 return INSTANCE; 252 } 253 254 /** 255 * The next Option created will have the specified description 256 * 257 * @param newDescription a description of the Option's purpose 258 * @return the OptionBuilder instance 259 */ 260 public static OptionBuilder withDescription(final String newDescription) { 261 OptionBuilder.description = newDescription; 262 263 return INSTANCE; 264 } 265 266 /** 267 * The next Option created will have the following long option value. 268 * 269 * @param newLongopt the long option value 270 * @return the OptionBuilder instance 271 */ 272 public static OptionBuilder withLongOpt(final String newLongopt) { 273 OptionBuilder.longOption = newLongopt; 274 275 return INSTANCE; 276 } 277 278 /** 279 * The next Option created will have a value that will be an instance of {@code type}. 280 * 281 * @param newType the type of the Options argument value 282 * @return the OptionBuilder instance 283 * @since 1.3 284 */ 285 public static OptionBuilder withType(final Class<?> newType) { 286 OptionBuilder.type = newType; 287 288 return INSTANCE; 289 } 290 291 /** 292 * The next Option created will have a value that will be an instance of {@code type}. 293 * <p> 294 * <b>Note:</b> this method is kept for binary compatibility and the input type is supposed to be a {@link Class} 295 * object. 296 * 297 * @param newType the type of the Options argument value 298 * @return the OptionBuilder instance 299 * @deprecated since 1.3, use {@link #withType(Class)} instead 300 */ 301 @Deprecated 302 public static OptionBuilder withType(final Object newType) { 303 return withType((Class<?>) newType); 304 } 305 306 /** 307 * The next Option created uses '{@code =}' as a means to separate argument values. 308 * 309 * <b>Example:</b> 310 * 311 * <pre> 312 * Option opt = OptionBuilder.withValueSeparator().create('D'); 313 * 314 * CommandLine line = parser.parse(args); 315 * String propertyName = opt.getValue(0); 316 * String propertyValue = opt.getValue(1); 317 * </pre> 318 * 319 * @return the OptionBuilder instance 320 */ 321 public static OptionBuilder withValueSeparator() { 322 OptionBuilder.valueSeparator = '='; 323 324 return INSTANCE; 325 } 326 327 /** 328 * The next Option created uses {@code sep} as a means to separate argument values. 329 * <p> 330 * <b>Example:</b> 331 * 332 * <pre> 333 * Option opt = OptionBuilder.withValueSeparator('=').create('D'); 334 * 335 * String args = "-Dkey=value"; 336 * CommandLine line = parser.parse(args); 337 * String propertyName = opt.getValue(0); // will be "key" 338 * String propertyValue = opt.getValue(1); // will be "value" 339 * </pre> 340 * 341 * @param sep The value separator to be used for the argument values. 342 * 343 * @return the OptionBuilder instance 344 */ 345 public static OptionBuilder withValueSeparator(final char sep) { 346 OptionBuilder.valueSeparator = sep; 347 348 return INSTANCE; 349 } 350 351 /** 352 * private constructor to prevent instances being created 353 */ 354 private OptionBuilder() { 355 // hide the constructor 356 } 357}