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     */
017    package net.dpml.cli.builder;
018    
019    import java.util.HashSet;
020    import java.util.Set;
021    
022    import net.dpml.cli.Argument;
023    import net.dpml.cli.Group;
024    import net.dpml.cli.option.Command;
025    import net.dpml.cli.resource.ResourceConstants;
026    import net.dpml.cli.resource.ResourceHelper;
027    
028    /**
029     * Builds Command instances
030     *
031     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
032     * @version 1.0.0
033     */
034    public 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    }