001 /*
002 * Copyright 2008-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2013 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 */
021 package com.unboundid.util.args;
022
023
024
025 import java.util.ArrayList;
026 import java.util.Arrays;
027 import java.util.Collections;
028 import java.util.Iterator;
029 import java.util.List;
030
031 import com.unboundid.ldap.sdk.DN;
032 import com.unboundid.ldap.sdk.LDAPException;
033 import com.unboundid.util.Mutable;
034 import com.unboundid.util.ThreadSafety;
035 import com.unboundid.util.ThreadSafetyLevel;
036
037 import static com.unboundid.util.Debug.*;
038 import 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)
049 public 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 }