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