001/* 002 * Copyright 2010-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2010-2024 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-2024 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}