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.Command;
025import net.dpml.cli.resource.ResourceConstants;
026import net.dpml.cli.resource.ResourceHelper;
027
028/**
029 * Builds Command instances
030 *
031 * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
032 * @version @PROJECT-VERSION@
033 */
034public class CommandBuilder
035{
036    /** the preferred name of the command */
037    private String m_preferredName;
038
039    /** the description of the command */
040    private String m_description;
041
042    /** the aliases of the command */
043    private Set m_aliases;
044
045    /** whether the command is required or not */
046    private boolean m_required;
047
048    /** the argument of the command */
049    private Argument m_argument;
050
051    /** the children of the command */
052    private Group m_children;
053
054    /** the id of the command */
055    private int m_id;
056
057    /**
058     * Creates a new <code>CommandBuilder</code> instance.
059     */
060    public CommandBuilder()
061    {
062        reset();
063    }
064
065    /**
066     * Creates a new <code>Command</code> instance using the properties of the
067     * <code>CommandBuilder</code>.
068     *
069     * @return the new Command instance
070     */
071    public Command create()
072    {
073        // check we have a valid name
074        if( m_preferredName == null )
075        {
076            throw new IllegalStateException(
077              ResourceHelper.getResourceHelper().getMessage(
078                ResourceConstants.OPTION_NO_NAME ) );
079        }
080
081        // build the command
082        final Command option =
083          new Command( 
084            m_preferredName, m_description, m_aliases, m_required, m_argument, m_children, m_id );
085
086        // reset the builder
087        reset();
088        return option;
089    }
090
091    /**
092     * Resets the CommandBuilder to the defaults for a new Command.
093     *
094     * This method is called automatically at the end of the
095     * {@link #create() create} method.
096     * @return this <code>CommandBuilder</code>.
097     */
098    public CommandBuilder reset()
099    {
100        m_preferredName = null;
101        m_description = null;
102        m_aliases = new HashSet();
103        m_required = false;
104        m_argument = null;
105        m_children = null;
106        m_id = 0;
107        return this;
108    }
109
110    /**
111     * Specifies the name for the next <code>Command</code>
112     * that is created.  The first name is used as the preferred
113     * display name for the <code>Command</code> and then
114     * later names are used as aliases.
115     *
116     * @param name the name for the next <code>Command</code>
117     * that is created.
118     * @return this <code>CommandBuilder</code>.
119     */
120    public CommandBuilder withName( final String name )
121    {
122        if( m_preferredName == null )
123        {
124            m_preferredName = name;
125        }
126        else
127        {
128            m_aliases.add( name );
129        }
130        return this;
131    }
132
133    /**
134     * Specifies the description for the next <code>Command</code>
135     * that is created.  This description is used to produce
136     * help documentation for the <code>Command</code>.
137     *
138     * @param newDescription the description for the next
139     * <code>Command</code> that is created.
140     * @return this <code>CommandBuilder</code>.
141     */
142    public CommandBuilder withDescription( final String newDescription )
143    {
144        m_description = newDescription;
145        return this;
146    }
147
148    /**
149     * Specifies whether the next <code>Command</code> created is
150     * required or not.
151     * @param newRequired whether the next <code>Command</code> created is
152     * required or not.
153     * @return this <code>CommandBuilder</code>.
154     */
155    public CommandBuilder withRequired( final boolean newRequired )
156    {
157        m_required = newRequired;
158        return this;
159    }
160
161    /**
162     * Specifies the children for the next <code>Command</code>
163     * that is created.
164     *
165     * @param newChildren the child options for the next <code>Command</code>
166     * that is created.
167     * @return this <code>CommandBuilder</code>.
168     */
169    public CommandBuilder withChildren( final Group newChildren )
170    {
171        m_children = newChildren;
172        return this;
173    }
174
175    /**
176     * Specifies the argument for the next <code>Command</code>
177     * that is created.
178     *
179     * @param newArgument the argument for the next <code>Command</code>
180     * that is created.
181     * @return this <code>CommandBuilder</code>.
182     */
183    public CommandBuilder withArgument( final Argument newArgument )
184    {
185        m_argument = newArgument;
186        return this;
187    }
188
189    /**
190     * Specifies the id for the next <code>Command</code> that is created.
191     *
192     * @param newId the id for the next <code>Command</code> that is created.
193     * @return this <code>CommandBuilder</code>.
194     */
195    public final CommandBuilder withId( final int newId )
196    {
197        m_id = newId;
198        return this;
199    }
200}