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}