001    /*
002     * Copyright 2010-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2010-2016 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.util.args;
022    
023    
024    
025    import java.util.Arrays;
026    import java.util.Collections;
027    import java.util.List;
028    
029    import com.unboundid.util.Mutable;
030    import com.unboundid.util.StaticUtils;
031    import com.unboundid.util.ThreadSafety;
032    import com.unboundid.util.ThreadSafetyLevel;
033    
034    import static com.unboundid.util.args.ArgsMessages.*;
035    
036    
037    
038    /**
039     * Creates a new argument that is intended to represent Boolean states based on
040     * the value provided for this argument.  This is similar to the
041     * {@link BooleanArgument} argument type, except that the Boolean value for this
042     * argument must be explicitly specified, whereas the Boolean value for the
043     * {@code BooleanArgument} class is inferred based on whether the argument
044     * was present.
045     * <BR><BR>
046     * Arguments of this type must always have exactly one value.  Values of "true",
047     * "t", "yes", "y", "on", and "1" will be interpreted as representing a Boolean
048     * value of {@code true}, and values of "false", "f", "no", "n", "off", and "0"
049     * will be interpreted as representing a Boolean value of {@code false}.  No
050     * other values will be allowed.
051     */
052    @Mutable()
053    @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
054    public final class BooleanValueArgument
055           extends Argument
056    {
057      /**
058       * The serial version UID for this serializable class.
059       */
060      private static final long serialVersionUID = -3903872574065550222L;
061    
062    
063    
064      // The default value for this argument.
065      private final Boolean defaultValue;
066    
067      // The provided value for this argument.
068      private Boolean value;
069    
070    
071    
072      /**
073       * Creates a new Boolean value argument with the provided information.  It
074       * will not be required, will use a default value placeholder, and will not
075       * have a default value.
076       *
077       * @param  shortIdentifier   The short identifier for this argument.  It may
078       *                           not be {@code null} if the long identifier is
079       *                           {@code null}.
080       * @param  longIdentifier    The long identifier for this argument.  It may
081       *                           not be {@code null} if the short identifier is
082       *                           {@code null}.
083       * @param  description       A human-readable description for this argument.
084       *                           It must not be {@code null}.
085       *
086       * @throws  ArgumentException  If there is a problem with the definition of
087       *                             this argument.
088       */
089      public BooleanValueArgument(final Character shortIdentifier,
090                                  final String longIdentifier,
091                                  final String description)
092             throws ArgumentException
093      {
094        this(shortIdentifier, longIdentifier, false, null, description);
095      }
096    
097    
098    
099      /**
100       * Creates a new Boolean value argument with no default value.
101       *
102       * @param  shortIdentifier   The short identifier for this argument.  It may
103       *                           not be {@code null} if the long identifier is
104       *                           {@code null}.
105       * @param  longIdentifier    The long identifier for this argument.  It may
106       *                           not be {@code null} if the short identifier is
107       *                           {@code null}.
108       * @param  isRequired        Indicates whether this argument is required to
109       *                           be provided.
110       * @param  valuePlaceholder  A placeholder to display in usage information to
111       *                           indicate that a value must be provided.  It may
112       *                           be {@code null} if a default placeholder should
113       *                           be used.
114       * @param  description       A human-readable description for this argument.
115       *                           It must not be {@code null}.
116       *
117       * @throws  ArgumentException  If there is a problem with the definition of
118       *                             this argument.
119       */
120      public BooleanValueArgument(final Character shortIdentifier,
121                                  final String longIdentifier,
122                                  final boolean isRequired,
123                                  final String valuePlaceholder,
124                                  final String description)
125             throws ArgumentException
126      {
127        this(shortIdentifier, longIdentifier, isRequired, valuePlaceholder,
128             description, null);
129      }
130    
131    
132    
133      /**
134       * Creates a new Boolean value argument with the specified default value.
135       *
136       * @param  shortIdentifier   The short identifier for this argument.  It may
137       *                           not be {@code null} if the long identifier is
138       *                           {@code null}.
139       * @param  longIdentifier    The long identifier for this argument.  It may
140       *                           not be {@code null} if the short identifier is
141       *                           {@code null}.
142       * @param  isRequired        Indicates whether this argument is required to
143       *                           be provided.
144       * @param  valuePlaceholder  A placeholder to display in usage information to
145       *                           indicate that a value must be provided.  It may
146       *                           be {@code null} if a default placeholder should
147       *                           be used.
148       * @param  description       A human-readable description for this argument.
149       *                           It must not be {@code null}.
150       * @param  defaultValue      The default value that will be used for this
151       *                           argument if no values are provided.  It may be
152       *                           {@code null} if there should not be a default
153       *                           value.
154       *
155       * @throws  ArgumentException  If there is a problem with the definition of
156       *                             this argument.
157       */
158      public BooleanValueArgument(final Character shortIdentifier,
159                                  final String longIdentifier,
160                                  final boolean isRequired,
161                                  final String valuePlaceholder,
162                                  final String description,
163                                  final Boolean defaultValue)
164             throws ArgumentException
165      {
166        super(shortIdentifier, longIdentifier, isRequired, 1,
167             (valuePlaceholder == null)
168                  ? INFO_PLACEHOLDER_TRUE_FALSE.get()
169                  : valuePlaceholder,
170             description);
171    
172        this.defaultValue = defaultValue;
173    
174        value = null;
175      }
176    
177    
178    
179      /**
180       * Creates a new Boolean value argument that is a "clean" copy of the provided
181       * source argument.
182       *
183       * @param  source  The source argument to use for this argument.
184       */
185      private BooleanValueArgument(final BooleanValueArgument source)
186      {
187        super(source);
188    
189        defaultValue = source.defaultValue;
190        value        = null;
191      }
192    
193    
194    
195      /**
196       * {@inheritDoc}
197       */
198      @Override()
199      public List<String> getValueStringRepresentations(final boolean useDefault)
200      {
201        if (value == null)
202        {
203          if (useDefault && (defaultValue != null))
204          {
205            return Collections.unmodifiableList(Arrays.asList(
206                 defaultValue.toString()));
207          }
208          else
209          {
210            return Collections.emptyList();
211          }
212        }
213        else
214        {
215          return Collections.unmodifiableList(Arrays.asList(value.toString()));
216        }
217      }
218    
219    
220    
221      /**
222       * {@inheritDoc}
223       */
224      @Override()
225      protected boolean hasDefaultValue()
226      {
227        return (defaultValue != null);
228      }
229    
230    
231    
232      /**
233       * Retrieves the default value for this argument, if defined.
234       *
235       * @return  The default value for this argument, or {@code null} if none is
236       *          defined.
237       */
238      public Boolean getDefaultValue()
239      {
240        return defaultValue;
241      }
242    
243    
244    
245      /**
246       * Retrieves the value for this argument, if one was provided.
247       *
248       * @return  The value for this argument.  If no value was provided but a
249       *          default value was defined, then the default value will be
250       *          returned.  If no value was provided and no default value was
251       *          defined, then {@code null} will be returned.
252       */
253      public Boolean getValue()
254      {
255        if (value == null)
256        {
257          return defaultValue;
258        }
259        else
260        {
261          return value;
262        }
263      }
264    
265    
266    
267      /**
268       * {@inheritDoc}
269       */
270      @Override()
271      protected void addValue(final String valueString)
272                throws ArgumentException
273      {
274        if (value != null)
275        {
276          throw new ArgumentException(
277               ERR_ARG_MAX_OCCURRENCES_EXCEEDED.get(getIdentifierString()));
278        }
279    
280        final String lowerStr = StaticUtils.toLowerCase(valueString);
281        if (lowerStr.equals("true") || lowerStr.equals("t") ||
282            lowerStr.equals("yes") || lowerStr.equals("y") ||
283            lowerStr.equals("on") || lowerStr.equals("1"))
284        {
285          value = Boolean.TRUE;
286        }
287        else if (lowerStr.equals("false") || lowerStr.equals("f") ||
288                 lowerStr.equals("no") || lowerStr.equals("n") ||
289                 lowerStr.equals("off") || lowerStr.equals("0"))
290        {
291          value = Boolean.FALSE;
292        }
293        else
294        {
295          throw new ArgumentException(ERR_ARG_VALUE_NOT_ALLOWED.get(
296               valueString, getIdentifierString()));
297        }
298      }
299    
300    
301    
302      /**
303       * {@inheritDoc}
304       */
305      @Override()
306      public String getDataTypeName()
307      {
308        return INFO_BOOLEAN_VALUE_TYPE_NAME.get();
309      }
310    
311    
312    
313      /**
314       * {@inheritDoc}
315       */
316      @Override()
317      public String getValueConstraints()
318      {
319        return INFO_BOOLEAN_VALUE_CONSTRAINTS.get();
320      }
321    
322    
323    
324      /**
325       * {@inheritDoc}
326       */
327      @Override()
328      protected void reset()
329      {
330        super.reset();
331        value = null;
332      }
333    
334    
335    
336      /**
337       * {@inheritDoc}
338       */
339      @Override()
340      public BooleanValueArgument getCleanCopy()
341      {
342        return new BooleanValueArgument(this);
343      }
344    
345    
346    
347      /**
348       * {@inheritDoc}
349       */
350      @Override()
351      protected void addToCommandLine(final List<String> argStrings)
352      {
353        if (value != null)
354        {
355          argStrings.add(getIdentifierString());
356          if (isSensitive())
357          {
358            argStrings.add("***REDACTED***");
359          }
360          else
361          {
362            argStrings.add(String.valueOf(value));
363          }
364        }
365      }
366    
367    
368    
369      /**
370       * {@inheritDoc}
371       */
372      @Override()
373      public void toString(final StringBuilder buffer)
374      {
375        buffer.append("BooleanValueArgument(");
376        appendBasicToStringInfo(buffer);
377    
378        if (defaultValue != null)
379        {
380          buffer.append(", defaultValue=");
381          buffer.append(defaultValue);
382        }
383    
384        buffer.append(')');
385      }
386    }