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