001/*
002 * Copyright 2003-2005 The Apache Software Foundation
003 * Copyright 2005 Stephen McConnell
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 net.dpml.cli.builder;
018
019import java.util.HashSet;
020import java.util.Set;
021
022import net.dpml.cli.Argument;
023import net.dpml.cli.Group;
024import net.dpml.cli.option.DefaultOption;
025import net.dpml.cli.resource.ResourceConstants;
026import net.dpml.cli.resource.ResourceHelper;
027
028/**
029 * Builds DefaultOption instances.
030 *
031 * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
032 * @version @PROJECT-VERSION@
033 */
034public class DefaultOptionBuilder
035{
036    private final String m_shortPrefix;
037    private final String m_longPrefix;
038    private final boolean m_burstEnabled;
039    private String m_preferredName;
040    private Set m_aliases;
041    private Set m_burstAliases;
042    private boolean m_required;
043    private String m_description;
044    private Argument m_argument;
045    private Group m_children;
046    private int m_id;
047
048    /**
049     * Creates a new DefaultOptionBuilder using defaults
050     * @see DefaultOption#DEFAULT_SHORT_PREFIX
051     * @see DefaultOption#DEFAULT_LONG_PREFIX
052     * @see DefaultOption#DEFAULT_BURST_ENABLED
053     */
054    public DefaultOptionBuilder()
055    {
056        this( 
057          DefaultOption.DEFAULT_SHORT_PREFIX, 
058          DefaultOption.DEFAULT_LONG_PREFIX,
059          DefaultOption.DEFAULT_BURST_ENABLED );
060    }
061
062    /**
063     * Creates a new DefaultOptionBuilder
064     * @param shortPrefix the prefix to use for short options
065     * @param longPrefix the prefix to use for long options
066     * @param burstEnabled whether to allow gnu style bursting
067     * @throws IllegalArgumentException if either prefix is less than on
068     *                                  character long
069     */
070    public DefaultOptionBuilder( 
071      final String shortPrefix, final String longPrefix, final boolean burstEnabled )
072      throws IllegalArgumentException
073    {
074        if( ( shortPrefix == null ) || ( shortPrefix.length() == 0 ) )
075        {
076            throw new IllegalArgumentException(
077              ResourceHelper.getResourceHelper().getMessage(
078                ResourceConstants.OPTION_ILLEGAL_SHORT_PREFIX ) );
079        }
080
081        if( ( longPrefix == null ) || ( longPrefix.length() == 0 ) )
082        {
083            throw new IllegalArgumentException(
084              ResourceHelper.getResourceHelper().getMessage(
085                ResourceConstants.OPTION_ILLEGAL_LONG_PREFIX ) );
086        }
087
088        m_shortPrefix = shortPrefix;
089        m_longPrefix = longPrefix;
090        m_burstEnabled = burstEnabled;
091        reset();
092    }
093
094    /**
095     * Creates a DefaultOption instance
096     * @return the new instance
097     * @throws IllegalStateException if no names have been supplied
098     */
099    public DefaultOption create() throws IllegalStateException
100    {
101        if( m_preferredName == null )
102        {
103            throw new IllegalStateException(
104              ResourceHelper.getResourceHelper().getMessage(
105                ResourceConstants.OPTION_NO_NAME ) );
106        }
107        final DefaultOption option =
108            new DefaultOption(
109              m_shortPrefix, 
110              m_longPrefix, 
111              m_burstEnabled, 
112              m_preferredName, 
113              m_description,
114              m_aliases, 
115              m_burstAliases, 
116              m_required, 
117              m_argument, 
118              m_children, 
119              m_id );
120        reset();
121        return option;
122    }
123
124    /**
125     * Resets the builder.
126     * @return this <code>DefaultOptionBuilder</code>.
127     */
128    public DefaultOptionBuilder reset()
129    {
130        m_preferredName = null;
131        m_description = null;
132        m_aliases = new HashSet();
133        m_burstAliases = new HashSet();
134        m_required = false;
135        m_argument = null;
136        m_children = null;
137        m_id = 0;
138        return this;
139    }
140
141    /**
142     * Use this short 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 shortName the name to use
146     * @return this builder
147     */
148    public DefaultOptionBuilder withShortName( final String shortName )
149    {
150        final String name = m_shortPrefix + shortName;
151        if( m_preferredName == null )
152        {
153            m_preferredName = name;
154        }
155        else
156        {
157            m_aliases.add( name );
158        }
159        if( m_burstEnabled && ( name.length() == ( m_shortPrefix.length() + 1 ) ) )
160        {
161            m_burstAliases.add( name );
162        }
163        return this;
164    }
165
166    /**
167     * Use this long option name.  The first name is used as the preferred
168     * display name for the Command and then later names are used as aliases.
169     *
170     * @param longName the name to use
171     * @return this builder
172     */
173    public DefaultOptionBuilder withLongName( final String longName )
174    {
175        final String name = m_longPrefix + longName;
176        if( m_preferredName == null )
177        {
178            m_preferredName = name;
179        }
180        else
181        {
182            m_aliases.add( name );
183        }
184        return this;
185    }
186
187    /**
188     * Use this option description
189     * @param newDescription the description to use
190     * @return this builder
191     */
192    public DefaultOptionBuilder withDescription( final String newDescription )
193    {
194        m_description = newDescription;
195        return this;
196    }
197
198    /**
199     * Use this optionality
200     * @param newRequired true iff the Option is required
201     * @return this builder
202     */
203    public DefaultOptionBuilder withRequired( final boolean newRequired )
204    {
205        m_required = newRequired;
206        return this;
207    }
208
209    /**
210     * Use this child Group
211     * @param newChildren the child Group to use
212     * @return this builder
213     */
214    public DefaultOptionBuilder withChildren( final Group newChildren )
215    {
216        m_children = newChildren;
217        return this;
218    }
219
220    /**
221     * Use this Argument
222     * @param newArgument the argument to use
223     * @return this builder
224     */
225    public DefaultOptionBuilder withArgument( final Argument newArgument )
226    {
227        m_argument = newArgument;
228        return this;
229    }
230
231    /**
232     * Sets the id
233     *
234     * @param newId
235     *            the id of the DefaultOption
236     * @return this DefaultOptionBuilder
237     */
238    public final DefaultOptionBuilder withId( final int newId )
239    {
240        m_id = newId;
241        return this;
242    }
243}