001/*
002 * Copyright 2010-2017 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2010-2017 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 */
021package com.unboundid.util.args;
022
023
024
025import java.util.Arrays;
026import java.util.Collections;
027import java.util.List;
028
029import com.unboundid.util.Mutable;
030import com.unboundid.util.StaticUtils;
031import com.unboundid.util.ThreadSafety;
032import com.unboundid.util.ThreadSafetyLevel;
033
034import 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)
054public 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}