001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.util.args;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.util.HashSet;
033    
034    import static org.opends.messages.UtilityMessages.*;
035    import org.opends.messages.MessageBuilder;
036    import static org.opends.server.util.StaticUtils.*;
037    
038    
039    
040    /**
041     * This class defines an argument type that will only accept one or more of a
042     * specific set of string values.
043     */
044    public class MultiChoiceArgument
045           extends Argument
046    {
047      // Indicates whether argument values should be treated in a case-sensitive
048      // manner.
049      private boolean caseSensitive;
050    
051      // The set of values that will be allowed for use with this argument.
052      private HashSet<String> allowedValues;
053    
054    
055    
056    
057      /**
058       * Creates a new string argument with the provided information.
059       *
060       * @param  name              The generic name that should be used to refer to
061       *                           this argument.
062       * @param  shortIdentifier   The single-character identifier for this
063       *                           argument, or <CODE>null</CODE> if there is none.
064       * @param  longIdentifier    The long identifier for this argument, or
065       *                           <CODE>null</CODE> if there is none.
066       * @param  isRequired        Indicates whether this argument must be specified
067       *                           on the command line.
068       * @param  needsValue        Indicates whether this argument requires a value.
069       * @param  valuePlaceholder  The placeholder for the argument value that will
070       *                           be displayed in usage information, or
071       *                           <CODE>null</CODE> if this argument does not
072       *                           require a value.
073       * @param  allowedValues     The set of values that are allowed for use for
074       *                           this argument.  If they are not to be treated in
075       *                           a case-sensitive value then they should all be
076       *                           formatted in lowercase.
077       * @param  caseSensitive     Indicates whether the set of allowed values
078       *                           should be treated in a case-sensitive manner.
079       * @param  description       Message for the description of this
080       *                           argument.
081       *
082       * @throws  ArgumentException  If there is a problem with any of the
083       *                             parameters used to create this argument.
084       */
085      public MultiChoiceArgument(String name, Character shortIdentifier,
086                                 String longIdentifier, boolean isRequired,
087                                 boolean needsValue, Message valuePlaceholder,
088                                 HashSet<String> allowedValues,
089                                 boolean caseSensitive,
090                                 Message description)
091             throws ArgumentException
092      {
093        super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue,
094              valuePlaceholder, null, null, description);
095    
096        this.allowedValues = allowedValues;
097        this.caseSensitive = caseSensitive;
098      }
099    
100    
101    
102      /**
103       * Creates a new string argument with the provided information.
104       *
105       * @param  name              The generic name that should be used to refer to
106       *                           this argument.
107       * @param  shortIdentifier   The single-character identifier for this
108       *                           argument, or <CODE>null</CODE> if there is none.
109       * @param  longIdentifier    The long identifier for this argument, or
110       *                           <CODE>null</CODE> if there is none.
111       * @param  isRequired        Indicates whether this argument must be specified
112       *                           on the command line.
113       * @param  isMultiValued     Indicates whether this argument may be specified
114       *                           more than once to provide multiple values.
115       * @param  needsValue        Indicates whether this argument requires a value.
116       * @param  valuePlaceholder  The placeholder for the argument value that will
117       *                           be displayed in usage information, or
118       *                           <CODE>null</CODE> if this argument does not
119       *                           require a value.
120       * @param  defaultValue      The default value that should be used for this
121       *                           argument if none is provided in a properties file
122       *                           or on the command line.  This may be
123       *                           <CODE>null</CODE> if there is no generic default.
124       * @param  propertyName      The name of the property in a property file that
125       *                           may be used to override the default value but
126       *                           will be overridden by a command-line argument.
127       * @param  allowedValues     The set of values that are allowed for use for
128       *                           this argument.  If they are not to be treated in
129       *                           a case-sensitive value then they should all be
130       *                           formatted in lowercase.
131       * @param  caseSensitive     Indicates whether the set of allowed values
132       *                           should be treated in a case-sensitive manner.
133       * @param  description       Message for the description of this
134       *                           argument.
135       *
136       * @throws  ArgumentException  If there is a problem with any of the
137       *                             parameters used to create this argument.
138       */
139      public MultiChoiceArgument(String name, Character shortIdentifier,
140                                 String longIdentifier, boolean isRequired,
141                                 boolean isMultiValued, boolean needsValue,
142                                 Message valuePlaceholder, String defaultValue,
143                                 String propertyName, HashSet<String> allowedValues,
144                                 boolean caseSensitive,
145                                 Message description)
146             throws ArgumentException
147      {
148        super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued,
149              needsValue, valuePlaceholder, defaultValue, propertyName,
150              description);
151    
152        this.allowedValues = allowedValues;
153        this.caseSensitive = caseSensitive;
154      }
155    
156    
157    
158      /**
159       * Retrieves the set of allowed values for this argument.  The contents of
160       * this set must not be altered by the caller.
161       *
162       * @return  The set of allowed values for this argument.
163       */
164      public HashSet<String> getAllowedValues()
165      {
166        return allowedValues;
167      }
168    
169    
170    
171      /**
172       * Indicates whether the set of allowed values for this argument should be
173       * treated in a case-sensitive manner.
174       *
175       * @return  <CODE>true</CODE> if the values are to be treated in a
176       *          case-sensitive manner, or <CODE>false</CODE> if not.
177       */
178      public boolean isCaseSensitive()
179      {
180        return caseSensitive;
181      }
182    
183    
184    
185      /**
186       * Indicates whether the provided value is acceptable for use in this
187       * argument.
188       *
189       * @param  valueString    The value for which to make the determination.
190       * @param  invalidReason  A buffer into which the invalid reason may be
191       *                        written if the value is not acceptable.
192       *
193       * @return  <CODE>true</CODE> if the value is acceptable, or
194       *          <CODE>false</CODE> if it is not.
195       */
196      public boolean valueIsAcceptable(String valueString,
197                                       MessageBuilder invalidReason)
198      {
199        if (caseSensitive)
200        {
201          if (! allowedValues.contains(valueString))
202          {
203            invalidReason.append(ERR_MCARG_VALUE_NOT_ALLOWED.get(
204                    getName(), valueString));
205    
206            return false;
207          }
208        }
209        else
210        {
211          if (! allowedValues.contains(toLowerCase(valueString)))
212          {
213            invalidReason.append(
214                    ERR_MCARG_VALUE_NOT_ALLOWED.get(getName(), valueString));
215    
216            return false;
217          }
218        }
219    
220    
221        // If we've gotten here, then the value appears to be acceptable.
222        return true;
223      }
224    }
225