001/* 002 * Copyright 2008-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2015 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.ArrayList; 026import java.util.Arrays; 027import java.util.Collections; 028import java.util.Iterator; 029import java.util.List; 030 031import com.unboundid.ldap.sdk.DN; 032import com.unboundid.ldap.sdk.LDAPException; 033import com.unboundid.util.Mutable; 034import com.unboundid.util.ThreadSafety; 035import com.unboundid.util.ThreadSafetyLevel; 036 037import static com.unboundid.util.Debug.*; 038import static com.unboundid.util.args.ArgsMessages.*; 039 040 041 042/** 043 * This class defines an argument that is intended to hold one or more 044 * distinguished name values. DN arguments must take values, and those values 045 * must be able to be parsed as distinguished names. 046 */ 047@Mutable() 048@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 049public final class DNArgument 050 extends Argument 051{ 052 /** 053 * The serial version UID for this serializable class. 054 */ 055 private static final long serialVersionUID = 7956577383262400167L; 056 057 058 059 // The set of values assigned to this argument. 060 private final ArrayList<DN> values; 061 062 // The argument value validators that have been registered for this argument. 063 private final List<ArgumentValueValidator> validators; 064 065 // The list of default values for this argument. 066 private final List<DN> defaultValues; 067 068 069 070 /** 071 * Creates a new DN argument with the provided information. It will not have 072 * a default value. 073 * 074 * @param shortIdentifier The short identifier for this argument. It may 075 * not be {@code null} if the long identifier is 076 * {@code null}. 077 * @param longIdentifier The long identifier for this argument. It may 078 * not be {@code null} if the short identifier is 079 * {@code null}. 080 * @param isRequired Indicates whether this argument is required to 081 * be provided. 082 * @param maxOccurrences The maximum number of times this argument may be 083 * provided on the command line. A value less than 084 * or equal to zero indicates that it may be present 085 * any number of times. 086 * @param valuePlaceholder A placeholder to display in usage information to 087 * indicate that a value must be provided. It must 088 * not be {@code null}. 089 * @param description A human-readable description for this argument. 090 * It must not be {@code null}. 091 * 092 * @throws ArgumentException If there is a problem with the definition of 093 * this argument. 094 */ 095 public DNArgument(final Character shortIdentifier, 096 final String longIdentifier, final boolean isRequired, 097 final int maxOccurrences, final String valuePlaceholder, 098 final String description) 099 throws ArgumentException 100 { 101 this(shortIdentifier, longIdentifier, isRequired, maxOccurrences, 102 valuePlaceholder, description, (List<DN>) null); 103 } 104 105 106 107 /** 108 * Creates a new DN argument with the provided information. 109 * 110 * @param shortIdentifier The short identifier for this argument. It may 111 * not be {@code null} if the long identifier is 112 * {@code null}. 113 * @param longIdentifier The long identifier for this argument. It may 114 * not be {@code null} if the short identifier is 115 * {@code null}. 116 * @param isRequired Indicates whether this argument is required to 117 * be provided. 118 * @param maxOccurrences The maximum number of times this argument may be 119 * provided on the command line. A value less than 120 * or equal to zero indicates that it may be present 121 * any number of times. 122 * @param valuePlaceholder A placeholder to display in usage information to 123 * indicate that a value must be provided. It must 124 * not be {@code null}. 125 * @param description A human-readable description for this argument. 126 * It must not be {@code null}. 127 * @param defaultValue The default value to use for this argument if no 128 * values were provided. 129 * 130 * @throws ArgumentException If there is a problem with the definition of 131 * this argument. 132 */ 133 public DNArgument(final Character shortIdentifier, 134 final String longIdentifier, final boolean isRequired, 135 final int maxOccurrences, final String valuePlaceholder, 136 final String description, final DN defaultValue) 137 throws ArgumentException 138 { 139 this(shortIdentifier, longIdentifier, isRequired, maxOccurrences, 140 valuePlaceholder, description, 141 ((defaultValue == null) ? null : Arrays.asList(defaultValue))); 142 } 143 144 145 146 /** 147 * Creates a new DN argument with the provided information. 148 * 149 * @param shortIdentifier The short identifier for this argument. It may 150 * not be {@code null} if the long identifier is 151 * {@code null}. 152 * @param longIdentifier The long identifier for this argument. It may 153 * not be {@code null} if the short identifier is 154 * {@code null}. 155 * @param isRequired Indicates whether this argument is required to 156 * be provided. 157 * @param maxOccurrences The maximum number of times this argument may be 158 * provided on the command line. A value less than 159 * or equal to zero indicates that it may be present 160 * any number of times. 161 * @param valuePlaceholder A placeholder to display in usage information to 162 * indicate that a value must be provided. It must 163 * not be {@code null}. 164 * @param description A human-readable description for this argument. 165 * It must not be {@code null}. 166 * @param defaultValues The set of default values to use for this 167 * argument if no values were provided. 168 * 169 * @throws ArgumentException If there is a problem with the definition of 170 * this argument. 171 */ 172 public DNArgument(final Character shortIdentifier, 173 final String longIdentifier, final boolean isRequired, 174 final int maxOccurrences, final String valuePlaceholder, 175 final String description, final List<DN> defaultValues) 176 throws ArgumentException 177 { 178 super(shortIdentifier, longIdentifier, isRequired, maxOccurrences, 179 valuePlaceholder, description); 180 181 if (valuePlaceholder == null) 182 { 183 throw new ArgumentException(ERR_ARG_MUST_TAKE_VALUE.get( 184 getIdentifierString())); 185 } 186 187 if ((defaultValues == null) || defaultValues.isEmpty()) 188 { 189 this.defaultValues = null; 190 } 191 else 192 { 193 this.defaultValues = Collections.unmodifiableList(defaultValues); 194 } 195 196 values = new ArrayList<DN>(5); 197 validators = new ArrayList<ArgumentValueValidator>(5); 198 } 199 200 201 202 /** 203 * Creates a new DN argument that is a "clean" copy of the provided source 204 * argument. 205 * 206 * @param source The source argument to use for this argument. 207 */ 208 private DNArgument(final DNArgument source) 209 { 210 super(source); 211 212 defaultValues = source.defaultValues; 213 values = new ArrayList<DN>(5); 214 validators = new ArrayList<ArgumentValueValidator>(source.validators); 215 } 216 217 218 219 /** 220 * Retrieves the list of default values for this argument, which will be used 221 * if no values were provided. 222 * 223 * @return The list of default values for this argument, or {@code null} if 224 * there are no default values. 225 */ 226 public List<DN> getDefaultValues() 227 { 228 return defaultValues; 229 } 230 231 232 233 /** 234 * Updates this argument to ensure that the provided validator will be invoked 235 * for any values provided to this argument. This validator will be invoked 236 * after all other validation has been performed for this argument. 237 * 238 * @param validator The argument value validator to be invoked. It must not 239 * be {@code null}. 240 */ 241 public void addValueValidator(final ArgumentValueValidator validator) 242 { 243 validators.add(validator); 244 } 245 246 247 248 /** 249 * {@inheritDoc} 250 */ 251 @Override() 252 protected void addValue(final String valueString) 253 throws ArgumentException 254 { 255 final DN parsedDN; 256 try 257 { 258 parsedDN = new DN(valueString); 259 } 260 catch (LDAPException le) 261 { 262 debugException(le); 263 throw new ArgumentException(ERR_DN_VALUE_NOT_DN.get(valueString, 264 getIdentifierString(), le.getMessage()), 265 le); 266 } 267 268 if (values.size() >= getMaxOccurrences()) 269 { 270 throw new ArgumentException(ERR_ARG_MAX_OCCURRENCES_EXCEEDED.get( 271 getIdentifierString())); 272 } 273 274 for (final ArgumentValueValidator v : validators) 275 { 276 v.validateArgumentValue(this, valueString); 277 } 278 279 values.add(parsedDN); 280 } 281 282 283 284 /** 285 * Retrieves the value for this argument, or the default value if none was 286 * provided. If there are multiple values, then the first will be returned. 287 * 288 * @return The value for this argument, or the default value if none was 289 * provided, or {@code null} if there is no value and no default 290 * value. 291 */ 292 public DN getValue() 293 { 294 if (values.isEmpty()) 295 { 296 if ((defaultValues == null) || defaultValues.isEmpty()) 297 { 298 return null; 299 } 300 else 301 { 302 return defaultValues.get(0); 303 } 304 } 305 else 306 { 307 return values.get(0); 308 } 309 } 310 311 312 313 /** 314 * Retrieves the set of values for this argument. 315 * 316 * @return The set of values for this argument. 317 */ 318 public List<DN> getValues() 319 { 320 if (values.isEmpty() && (defaultValues != null)) 321 { 322 return defaultValues; 323 } 324 325 return Collections.unmodifiableList(values); 326 } 327 328 329 330 /** 331 * Retrieves a string representation of the value for this argument, or a 332 * string representation of the default value if none was provided. If there 333 * are multiple values, then the first will be returned. 334 * 335 * @return The string representation of the value for this argument, or the 336 * string representation of the default value if none was provided, 337 * or {@code null} if there is no value and no default value. 338 */ 339 public String getStringValue() 340 { 341 final DN valueDN = getValue(); 342 if (valueDN == null) 343 { 344 return null; 345 } 346 347 return valueDN.toString(); 348 } 349 350 351 352 /** 353 * {@inheritDoc} 354 */ 355 @Override() 356 protected boolean hasDefaultValue() 357 { 358 return ((defaultValues != null) && (! defaultValues.isEmpty())); 359 } 360 361 362 363 /** 364 * {@inheritDoc} 365 */ 366 @Override() 367 public String getDataTypeName() 368 { 369 return INFO_DN_TYPE_NAME.get(); 370 } 371 372 373 374 /** 375 * {@inheritDoc} 376 */ 377 @Override() 378 public String getValueConstraints() 379 { 380 return INFO_DN_CONSTRAINTS.get(); 381 } 382 383 384 385 /** 386 * {@inheritDoc} 387 */ 388 @Override() 389 public DNArgument getCleanCopy() 390 { 391 return new DNArgument(this); 392 } 393 394 395 396 /** 397 * {@inheritDoc} 398 */ 399 @Override() 400 public void toString(final StringBuilder buffer) 401 { 402 buffer.append("DNArgument("); 403 appendBasicToStringInfo(buffer); 404 405 if ((defaultValues != null) && (! defaultValues.isEmpty())) 406 { 407 if (defaultValues.size() == 1) 408 { 409 buffer.append(", defaultValue='"); 410 buffer.append(defaultValues.get(0).toString()); 411 } 412 else 413 { 414 buffer.append(", defaultValues={"); 415 416 final Iterator<DN> iterator = defaultValues.iterator(); 417 while (iterator.hasNext()) 418 { 419 buffer.append('\''); 420 buffer.append(iterator.next().toString()); 421 buffer.append('\''); 422 423 if (iterator.hasNext()) 424 { 425 buffer.append(", "); 426 } 427 } 428 429 buffer.append('}'); 430 } 431 } 432 433 buffer.append(')'); 434 } 435}