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