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