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