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