001/*
002 * Copyright 2015-2017 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-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.ArrayList;
026import java.util.Collection;
027import java.util.Collections;
028import java.util.Iterator;
029import java.util.List;
030
031import com.unboundid.ldap.sdk.DN;
032import com.unboundid.util.Debug;
033import com.unboundid.util.NotMutable;
034import com.unboundid.util.StaticUtils;
035import com.unboundid.util.ThreadSafety;
036import com.unboundid.util.ThreadSafetyLevel;
037import com.unboundid.util.Validator;
038
039import static com.unboundid.util.args.ArgsMessages.*;
040
041
042
043/**
044 * This class provides an implementation of an argument value validator that is
045 * expected to be used with string or DN arguments and ensures that all values
046 * for the argument are valid DNs that are within one or more specified
047 * subtrees.
048 */
049@NotMutable()
050@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
051public final class RequireDNInSubtreeArgumentValueValidator
052       extends ArgumentValueValidator
053{
054  // The set of permitted base DNs for values of the associated argument.
055  private final List<DN> baseDNs;
056
057
058
059  /**
060   * Creates a new instance of this argument value validator with the provided
061   * information.
062   *
063   * @param  baseDNs  The set of permitted base DNs for values of the associated
064   *                  argument.  It must not be {@code null} or empty.
065   */
066  public RequireDNInSubtreeArgumentValueValidator(final DN... baseDNs)
067  {
068    this(StaticUtils.toList(baseDNs));
069  }
070
071
072
073  /**
074   * Creates a new instance of this argument value validator with the provided
075   * information.
076   *
077   * @param  baseDNs  The set of permitted base DNs for values of the associated
078   *                  argument.  It must not be {@code null} or empty.
079   */
080  public RequireDNInSubtreeArgumentValueValidator(final Collection<DN> baseDNs)
081  {
082    Validator.ensureNotNull(baseDNs);
083    Validator.ensureFalse(baseDNs.isEmpty());
084
085    this.baseDNs = Collections.unmodifiableList(new ArrayList<DN>(baseDNs));
086  }
087
088
089
090  /**
091   * Retrieves a list of the permitted base DNs for this argument value
092   * validator.
093   *
094   * @return  A list of the permitted base DNs for this argument value
095   *          validator.
096   */
097  public List<DN> getBaseDNs()
098  {
099    return baseDNs;
100  }
101
102
103
104  /**
105   * {@inheritDoc}
106   */
107  @Override()
108  public void validateArgumentValue(final Argument argument,
109                                    final String valueString)
110         throws ArgumentException
111  {
112    final DN dn;
113    try
114    {
115      dn = new DN(valueString);
116    }
117    catch (final Exception e)
118    {
119      Debug.debugException(e);
120      throw new ArgumentException(
121           ERR_REQUIRE_DN_IN_SUBTREE_VALIDATOR_VALUE_NOT_DN.get(valueString,
122                argument.getIdentifierString()),
123           e);
124    }
125
126
127    if (baseDNs.size() == 1)
128    {
129      if (! dn.isDescendantOf(baseDNs.get(0), true))
130      {
131        throw new ArgumentException(
132             ERR_REQUIRE_DN_IN_SUBTREE_VALIDATOR_VALUE_NOT_IN_SUBTREE.get(
133                  valueString, argument.getIdentifierString(),
134                  String.valueOf(baseDNs.get(0))));
135      }
136    }
137    else
138    {
139      final StringBuilder dnList = new StringBuilder();
140      final Iterator<DN> iterator = baseDNs.iterator();
141      while (iterator.hasNext())
142      {
143        final DN baseDN = iterator.next();
144        if (dn.isDescendantOf(baseDN, true))
145        {
146          return;
147        }
148
149        dnList.append('\'');
150        dnList.append(baseDN);
151        dnList.append('\'');
152
153        if (iterator.hasNext())
154        {
155          dnList.append(", ");
156        }
157      }
158
159      throw new ArgumentException(
160           ERR_REQUIRE_DN_IN_SUBTREE_VALIDATOR_VALUE_NOT_IN_SUBTREES.get(
161                valueString, argument.getIdentifierString(),
162                dnList.toString()));
163    }
164  }
165
166
167
168  /**
169   * Retrieves a string representation of this argument value validator.
170   *
171   * @return  A string representation of this argument value validator.
172   */
173  @Override()
174  public String toString()
175  {
176    final StringBuilder buffer = new StringBuilder();
177    toString(buffer);
178    return buffer.toString();
179  }
180
181
182
183  /**
184   * Appends a string representation of this argument value validator to the
185   * provided buffer.
186   *
187   * @param  buffer  The buffer to which the string representation should be
188   *                 appended.
189   */
190  public void toString(final StringBuilder buffer)
191  {
192    buffer.append("RequireDNInSubtreeArgumentValueValidator(baseDNs={");
193
194    final Iterator<DN> iterator = baseDNs.iterator();
195    while (iterator.hasNext())
196    {
197      buffer.append('\'');
198      buffer.append(iterator.next().toString());
199      buffer.append('\'');
200
201      if (iterator.hasNext())
202      {
203        buffer.append(", ");
204      }
205    }
206
207    buffer.append("})");
208  }
209}