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