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 */
017package org.apache.commons.cli2.builder;
018
019import java.util.HashSet;
020import java.util.Set;
021
022import org.apache.commons.cli2.Argument;
023import org.apache.commons.cli2.Group;
024import org.apache.commons.cli2.option.DefaultOption;
025import org.apache.commons.cli2.resource.ResourceConstants;
026import org.apache.commons.cli2.resource.ResourceHelper;
027
028/**
029 * Builds DefaultOption instances.
030 */
031public class DefaultOptionBuilder {
032    private final String shortPrefix;
033    private final String longPrefix;
034    private final boolean burstEnabled;
035    private String preferredName;
036    private Set aliases;
037    private Set burstAliases;
038    private boolean required;
039    private String description;
040    private Argument argument;
041    private Group children;
042    private int id;
043
044    /**
045     * Creates a new DefaultOptionBuilder using defaults
046     * @see DefaultOption#DEFAULT_SHORT_PREFIX
047     * @see DefaultOption#DEFAULT_LONG_PREFIX
048     * @see DefaultOption#DEFAULT_BURST_ENABLED
049     */
050    public DefaultOptionBuilder() {
051        this(DefaultOption.DEFAULT_SHORT_PREFIX, DefaultOption.DEFAULT_LONG_PREFIX,
052             DefaultOption.DEFAULT_BURST_ENABLED);
053    }
054
055    /**
056     * Creates a new DefaultOptionBuilder
057     * @param shortPrefix the prefix to use for short options
058     * @param longPrefix the prefix to use for long options
059     * @param burstEnabled whether to allow gnu style bursting
060     * @throws IllegalArgumentException if either prefix is less than on
061     *                                  character long
062     */
063    public DefaultOptionBuilder(final String shortPrefix,
064                                final String longPrefix,
065                                final boolean burstEnabled)
066        throws IllegalArgumentException {
067        if ((shortPrefix == null) || (shortPrefix.length() == 0)) {
068            throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.OPTION_ILLEGAL_SHORT_PREFIX));
069        }
070
071        if ((longPrefix == null) || (longPrefix.length() == 0)) {
072            throw new IllegalArgumentException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.OPTION_ILLEGAL_LONG_PREFIX));
073        }
074
075        this.shortPrefix = shortPrefix;
076        this.longPrefix = longPrefix;
077        this.burstEnabled = burstEnabled;
078        reset();
079    }
080
081    /**
082     * Creates a DefaultOption instance
083     * @return the new instance
084     * @throws IllegalStateException if no names have been supplied
085     */
086    public DefaultOption create()
087        throws IllegalStateException {
088        if (preferredName == null) {
089            throw new IllegalStateException(ResourceHelper.getResourceHelper().getMessage(ResourceConstants.OPTION_NO_NAME));
090        }
091
092        final DefaultOption option =
093            new DefaultOption(shortPrefix, longPrefix, burstEnabled, preferredName, description,
094                              aliases, burstAliases, required, argument, children, id);
095
096        reset();
097
098        return option;
099    }
100
101    /**
102     * Resets the builder.
103     * @return this builder
104     */
105    public DefaultOptionBuilder reset() {
106        preferredName = null;
107        description = null;
108        aliases = new HashSet();
109        burstAliases = new HashSet();
110        required = false;
111        argument = null;
112        children = null;
113        id = 0;
114
115        return this;
116    }
117
118    /**
119     * Use this short option name. The first name is used as the preferred
120     * display name for the Command and then later names are used as aliases.
121     *
122     * @param shortName the name to use
123     * @return this builder
124     */
125    public DefaultOptionBuilder withShortName(final String shortName) {
126        final String name = shortPrefix + shortName;
127
128        if (preferredName == null) {
129            preferredName = name;
130        } else {
131            aliases.add(name);
132        }
133
134        if (burstEnabled && (name.length() == (shortPrefix.length() + 1))) {
135            burstAliases.add(name);
136        }
137
138        return this;
139    }
140
141    /**
142     * Use this long option name.  The first name is used as the preferred
143     * display name for the Command and then later names are used as aliases.
144     *
145     * @param longName the name to use
146     * @return this builder
147     */
148    public DefaultOptionBuilder withLongName(final String longName) {
149        final String name = longPrefix + longName;
150
151        if (preferredName == null) {
152            preferredName = name;
153        } else {
154            aliases.add(name);
155        }
156
157        return this;
158    }
159
160    /**
161     * Use this option description
162     * @param newDescription the description to use
163     * @return this builder
164     */
165    public DefaultOptionBuilder withDescription(final String newDescription) {
166        this.description = newDescription;
167
168        return this;
169    }
170
171    /**
172     * Use this optionality
173     * @param newRequired true iff the Option is required
174     * @return this builder
175     */
176    public DefaultOptionBuilder withRequired(final boolean newRequired) {
177        this.required = newRequired;
178
179        return this;
180    }
181
182    /**
183     * Use this child Group
184     * @param newChildren the child Group to use
185     * @return this builder
186     */
187    public DefaultOptionBuilder withChildren(final Group newChildren) {
188        this.children = newChildren;
189
190        return this;
191    }
192
193    /**
194     * Use this Argument
195     * @param newArgument the argument to use
196     * @return this builder
197     */
198    public DefaultOptionBuilder withArgument(final Argument newArgument) {
199        this.argument = newArgument;
200
201        return this;
202    }
203
204    /**
205     * Sets the id
206     *
207     * @param newId
208     *            the id of the DefaultOption
209     * @return this DefaultOptionBuilder
210     */
211    public final DefaultOptionBuilder withId(final int newId) {
212        this.id = newId;
213
214        return this;
215    }
216}