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    package org.apache.commons.cli2.builder;
018    
019    import java.util.HashSet;
020    import java.util.Set;
021    
022    import org.apache.commons.cli2.Argument;
023    import org.apache.commons.cli2.Group;
024    import org.apache.commons.cli2.option.DefaultOption;
025    import org.apache.commons.cli2.resource.ResourceConstants;
026    import org.apache.commons.cli2.resource.ResourceHelper;
027    
028    /**
029     * Builds DefaultOption instances.
030     */
031    public 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    }