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