001    /*
002     * Copyright 2015-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015-2016 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.Collection;
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.util.Debug;
033    import com.unboundid.util.NotMutable;
034    import com.unboundid.util.StaticUtils;
035    import com.unboundid.util.ThreadSafety;
036    import com.unboundid.util.ThreadSafetyLevel;
037    import com.unboundid.util.Validator;
038    
039    import 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)
051    public 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    }