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