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
018package org.apache.commons.cli;
019
020import java.io.Serializable;
021import java.util.Collection;
022import java.util.Iterator;
023import java.util.LinkedHashMap;
024import java.util.Map;
025
026/**
027 * A group of mutually exclusive options.
028 */
029public class OptionGroup implements Serializable
030{
031    /** The serial version UID. */
032    private static final long serialVersionUID = 1L;
033    
034    /** hold the options */
035    private final Map<String, Option> optionMap = new LinkedHashMap<String, Option>();
036
037    /** the name of the selected option */
038    private String selected;
039
040    /** specified whether this group is required */
041    private boolean required;
042
043    /**
044     * Add the specified <code>Option</code> to this group.
045     *
046     * @param option the option to add to this group
047     * @return this option group with the option added
048     */
049    public OptionGroup addOption(final Option option)
050    {
051        // key   - option name
052        // value - the option
053        optionMap.put(option.getKey(), option);
054
055        return this;
056    }
057
058    /**
059     * @return the names of the options in this group as a 
060     * <code>Collection</code>
061     */
062    public Collection<String> getNames()
063    {
064        // the key set is the collection of names
065        return optionMap.keySet();
066    }
067
068    /**
069     * @return the options in this group as a <code>Collection</code>
070     */
071    public Collection<Option> getOptions()
072    {
073        // the values are the collection of options
074        return optionMap.values();
075    }
076
077    /**
078     * Set the selected option of this group to <code>name</code>.
079     *
080     * @param option the option that is selected
081     * @throws AlreadySelectedException if an option from this group has 
082     * already been selected.
083     */
084    public void setSelected(final Option option) throws AlreadySelectedException
085    {
086        if (option == null)
087        {
088            // reset the option previously selected
089            selected = null;
090            return;
091        }
092        
093        // if no option has already been selected or the 
094        // same option is being reselected then set the
095        // selected member variable
096        if (selected == null || selected.equals(option.getKey()))
097        {
098            selected = option.getKey();
099        }
100        else
101        {
102            throw new AlreadySelectedException(this, option);
103        }
104    }
105
106    /**
107     * @return the selected option name
108     */
109    public String getSelected()
110    {
111        return selected;
112    }
113
114    /**
115     * @param required specifies if this group is required
116     */
117    public void setRequired(final boolean required)
118    {
119        this.required = required;
120    }
121
122    /**
123     * Returns whether this option group is required.
124     *
125     * @return whether this option group is required
126     */
127    public boolean isRequired()
128    {
129        return required;
130    }
131
132    /**
133     * Returns the stringified version of this OptionGroup.
134     * 
135     * @return the stringified representation of this group
136     */
137    @Override
138    public String toString()
139    {
140        final StringBuilder buff = new StringBuilder();
141        
142        final Iterator<Option> iter = getOptions().iterator();
143
144        buff.append("[");
145
146        while (iter.hasNext())
147        {
148            final Option option = iter.next();
149
150            if (option.getOpt() != null)
151            {
152                buff.append("-");
153                buff.append(option.getOpt());
154            }
155            else
156            {
157                buff.append("--");
158                buff.append(option.getLongOpt());
159            }
160            
161            if (option.getDescription() != null)
162            {
163                buff.append(" ");
164                buff.append(option.getDescription());
165            }
166            
167            if (iter.hasNext())
168            {
169                buff.append(", ");
170            }
171        }
172
173        buff.append("]");
174
175        return buff.toString();
176    }
177}