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}