001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2011-2014 ForgeRock AS. 015 */ 016 017package org.forgerock.opendj.ldap.schema; 018 019import org.forgerock.opendj.ldap.DN; 020import org.forgerock.opendj.ldap.Entry; 021import org.forgerock.opendj.ldap.LdapException; 022 023/** 024 * This class provides various schema validation policy options for controlling 025 * how entries should be validated against the directory schema. 026 */ 027public final class SchemaValidationPolicy { 028 /** 029 * A call-back which will be called during DIT structure rule schema 030 * validation in order to retrieve the parent of the entry being validated. 031 */ 032 public static interface EntryResolver { 033 /** 034 * Returns the named entry in order to enforce DIT structure rules. 035 * 036 * @param dn 037 * The name of the entry to be returned. 038 * @return The named entry. 039 * @throws LdapException 040 * If the entry could not be retrieved. 041 */ 042 Entry getEntry(DN dn) throws LdapException; 043 } 044 045 /** 046 * An enumeration of the possible actions which can be performed when a 047 * schema validation failure is encountered. 048 */ 049 public static enum Action { 050 /** 051 * Schema validation will not be performed. 052 */ 053 IGNORE, 054 055 /** 056 * Schema validation will be performed, but failures will not cause the 057 * overall validation to fail. Error messages will be returned. 058 */ 059 WARN, 060 061 /** 062 * Schema validation will be performed and failures will cause the 063 * overall validation to fail. Error messages will be returned. 064 */ 065 REJECT; 066 067 private Action() { 068 // Nothing to do. 069 } 070 071 /** 072 * Returns {@code true} if this policy is {@code IGNORE}. 073 * 074 * @return {@code true} if this policy is {@code IGNORE}. 075 */ 076 public boolean isIgnore() { 077 return this == IGNORE; 078 } 079 080 /** 081 * Returns {@code true} if this policy is {@code REJECT}. 082 * 083 * @return {@code true} if this policy is {@code REJECT}. 084 */ 085 public boolean isReject() { 086 return this == REJECT; 087 } 088 089 /** 090 * Returns {@code true} if this policy is {@code WARN}. 091 * 092 * @return {@code true} if this policy is {@code WARN}. 093 */ 094 public boolean isWarn() { 095 return this == WARN; 096 } 097 098 /** 099 * Returns {@code true} if this policy is {@code WARN} or {@code REJECT} 100 * . 101 * 102 * @return {@code true} if this policy is {@code WARN} or {@code REJECT} 103 * . 104 */ 105 public boolean needsChecking() { 106 return this != IGNORE; 107 } 108 } 109 110 /** 111 * Creates a copy of the provided schema validation policy. 112 * 113 * @param policy 114 * The policy to be copied. 115 * @return The copy of the provided schema validation policy. 116 */ 117 public static SchemaValidationPolicy copyOf(final SchemaValidationPolicy policy) { 118 return defaultPolicy().assign(policy); 119 } 120 121 /** 122 * Creates a new schema validation policy with default settings. More 123 * specifically: 124 * <ul> 125 * <li>Entries not having a single structural object class will be rejected 126 * <li>Entries having attributes which are not permitted by its object 127 * classes or DIT content rule (if present) will be rejected 128 * <li>Entries not conforming to name forms will be rejected 129 * <li>DIT structure rules will not be ignored 130 * </ul> 131 * 132 * @return The new schema validation policy. 133 */ 134 public static SchemaValidationPolicy defaultPolicy() { 135 return new SchemaValidationPolicy(); 136 } 137 138 /** 139 * Creates a new schema validation policy which will not perform any schema 140 * validation. 141 * 142 * @return The new schema validation policy. 143 */ 144 public static SchemaValidationPolicy ignoreAll() { 145 return new SchemaValidationPolicy().checkAttributesAndObjectClasses(Action.IGNORE) 146 .checkAttributeValues(Action.IGNORE).checkDITContentRules(Action.IGNORE) 147 .checkNameForms(Action.IGNORE).requireSingleStructuralObjectClass(Action.IGNORE); 148 } 149 150 private Action checkNameForms = Action.REJECT; 151 private Action checkDITStructureRules = Action.IGNORE; 152 private Action checkDITContentRules = Action.REJECT; 153 private Action requireSingleStructuralObjectClass = Action.REJECT; 154 private Action checkAttributesAndObjectClasses = Action.REJECT; 155 private Action checkAttributeValues = Action.REJECT; 156 private EntryResolver checkDITStructureRulesEntryResolver; 157 158 /** Prevent direct instantiation. */ 159 private SchemaValidationPolicy() { 160 // Nothing to do. 161 } 162 163 /** 164 * Returns the policy for verifying that the user attributes in an entry 165 * conform to its object classes. More specifically, an entry must contain 166 * all required user attributes, and must not contain any user attributes 167 * which are not declared as required or optional by its object classes. 168 * <p> 169 * By default entries which have missing or additional user attributes will 170 * be rejected. 171 * 172 * @return The policy for verifying that the user attributes in an entry 173 * conform to its object classes. 174 */ 175 public Action checkAttributesAndObjectClasses() { 176 return checkAttributesAndObjectClasses; 177 } 178 179 /** 180 * Specifies the policy for verifying that the user attributes in an entry 181 * conform to its object classes. More specifically, an entry must contain 182 * all required user attributes, and must not contain any user attributes 183 * which are not declared as required or optional by its object classes. 184 * <p> 185 * By default entries which have missing or additional user attributes will 186 * be rejected. 187 * 188 * @param policy 189 * The policy for verifying that the user attributes in an entry 190 * conform to its object classes. 191 * @return A reference to this {@code SchemaValidationPolicy}. 192 */ 193 public SchemaValidationPolicy checkAttributesAndObjectClasses(final Action policy) { 194 this.checkAttributesAndObjectClasses = policy; 195 return this; 196 } 197 198 /** 199 * Returns the policy for verifying that the user attributes in an entry 200 * conform to their associated attribute type descriptions. This may 201 * include: 202 * <ul> 203 * <li>checking that there is at least one value 204 * <li>checking that single-valued attributes contain only a single value 205 * <li>checking that there are no duplicate values according to the 206 * attribute's default equality matching rule 207 * <li>checking that attributes which require BER encoding specify the 208 * {@code ;binary} attribute option 209 * <li>checking that the values are valid according to the attribute's 210 * syntax. 211 * </ul> 212 * Schema validation implementations specify exactly which of the above 213 * checks will be performed. 214 * <p> 215 * By default entries which have invalid attribute values will be rejected. 216 * 217 * @return The policy for verifying that the user attributes in an entry 218 * conform to their associated attribute type descriptions. 219 */ 220 public Action checkAttributeValues() { 221 return checkAttributeValues; 222 } 223 224 /** 225 * Specifies the policy for verifying that the user attributes in an entry 226 * conform to their associated attribute type descriptions. This may 227 * include: 228 * <ul> 229 * <li>checking that there is at least one value 230 * <li>checking that single-valued attributes contain only a single value 231 * <li>checking that there are no duplicate values according to the 232 * attribute's default equality matching rule 233 * <li>checking that attributes which require BER encoding specify the 234 * {@code ;binary} attribute option 235 * <li>checking that the values are valid according to the attribute's 236 * syntax. 237 * </ul> 238 * Schema validation implementations specify exactly which of the above 239 * checks will be performed. 240 * <p> 241 * By default entries which have invalid attribute values will be rejected. 242 * 243 * @param policy 244 * The policy for verifying that the user attributes in an entry 245 * conform to their associated attribute type descriptions. 246 * @return A reference to this {@code SchemaValidationPolicy}. 247 */ 248 public SchemaValidationPolicy checkAttributeValues(final Action policy) { 249 this.checkAttributeValues = policy; 250 return this; 251 } 252 253 /** 254 * Returns the policy for validating entries against content rules defined 255 * in the schema. 256 * <p> 257 * By default content rules will be ignored during validation. 258 * 259 * @return The policy for validating entries against content rules defined 260 * in the schema. 261 */ 262 public Action checkDITContentRules() { 263 return checkDITContentRules; 264 } 265 266 /** 267 * Specifies the policy for validating entries against content rules defined 268 * in the schema. 269 * <p> 270 * By default content rules will be ignored during validation. 271 * 272 * @param policy 273 * The policy for validating entries against content rules 274 * defined in the schema. 275 * @return A reference to this {@code SchemaValidationPolicy}. 276 */ 277 public SchemaValidationPolicy checkDITContentRules(final Action policy) { 278 this.checkDITContentRules = policy; 279 return this; 280 } 281 282 /** 283 * Returns the policy for validating entries against structure rules defined 284 * in the schema. 285 * <p> 286 * By default structure rules will be ignored during validation. 287 * 288 * @return The policy for validating entries against structure rules defined 289 * in the schema. 290 */ 291 public Action checkDITStructureRules() { 292 return checkDITStructureRules; 293 } 294 295 /** 296 * Specifies the policy for validating entries against structure rules 297 * defined in the schema. 298 * <p> 299 * By default structure rules will be ignored during validation. 300 * 301 * @param policy 302 * The policy for validating entries against structure rules 303 * defined in the schema. 304 * @param resolver 305 * The parent entry resolver which should be used for retrieving 306 * the parent entry during DIT structure rule validation. 307 * @return A reference to this {@code SchemaValidationPolicy}. 308 * @throws IllegalArgumentException 309 * If {@code resolver} was {@code null} and 310 * {@code checkDITStructureRules} is either {@code WARN} or 311 * {@code REJECT}. 312 */ 313 public SchemaValidationPolicy checkDITStructureRules(final Action policy, 314 final EntryResolver resolver) { 315 if (checkDITStructureRules.needsChecking() && resolver == null) { 316 throw new IllegalArgumentException( 317 "Validation of structure rules enabled by resolver was null"); 318 } 319 this.checkDITStructureRules = policy; 320 this.checkDITStructureRulesEntryResolver = resolver; 321 return this; 322 } 323 324 /** 325 * Returns parent entry resolver which should be used for retrieving the 326 * parent entry during DIT structure rule validation. 327 * <p> 328 * By default no resolver is defined because structure rules will be ignored 329 * during validation. 330 * 331 * @return The parent entry resolver which should be used for retrieving the 332 * parent entry during DIT structure rule validation. 333 */ 334 public EntryResolver checkDITStructureRulesEntryResolver() { 335 return checkDITStructureRulesEntryResolver; 336 } 337 338 /** 339 * Returns the policy for validating entries against name forms defined in 340 * the schema. 341 * <p> 342 * By default name forms will be ignored during validation. 343 * 344 * @return The policy for validating entries against name forms defined in 345 * the schema. 346 */ 347 public Action checkNameForms() { 348 return checkNameForms; 349 } 350 351 /** 352 * Specifies the policy for validating entries against name forms defined in 353 * the schema. 354 * <p> 355 * By default name forms will be ignored during validation. 356 * 357 * @param policy 358 * The policy for validating entries against name forms defined 359 * in the schema. 360 * @return A reference to this {@code SchemaValidationPolicy}. 361 */ 362 public SchemaValidationPolicy checkNameForms(final Action policy) { 363 this.checkNameForms = policy; 364 return this; 365 } 366 367 /** 368 * Returns the policy for verifying that entries have only a single 369 * structural object class. 370 * <p> 371 * By default entries which do not have a structural object class or which 372 * have more than one structural object class will be rejected. 373 * 374 * @return The policy for checking that entries have one and only one 375 * structural object class. 376 */ 377 public Action requireSingleStructuralObjectClass() { 378 return requireSingleStructuralObjectClass; 379 } 380 381 /** 382 * Specifies the policy for verifying that entries have only a single 383 * structural object class. 384 * <p> 385 * By default entries which do not have a structural object class or which 386 * have more than one structural object class will be rejected. 387 * 388 * @param policy 389 * The policy for checking that entries have one and only one 390 * structural object class. 391 * @return A reference to this {@code SchemaValidationPolicy}. 392 */ 393 public SchemaValidationPolicy requireSingleStructuralObjectClass(final Action policy) { 394 this.requireSingleStructuralObjectClass = policy; 395 return this; 396 } 397 398 /** 399 * Returns a strict view of the provided schema if the this policy is 400 * configured to check attributes and object class, or a non-strict view of 401 * the schema if not. 402 * 403 * @param schema 404 * The schema to be adapted according to this policy. 405 * @return A strict or non-strict view of {@code schema} depending on 406 * {@link #checkAttributesAndObjectClasses()}. 407 */ 408 public Schema adaptSchemaForValidation(final Schema schema) { 409 return checkAttributesAndObjectClasses().needsChecking() ? schema.asStrictSchema() : schema 410 .asNonStrictSchema(); 411 } 412 413 /** Assigns the provided options to this set of options. */ 414 SchemaValidationPolicy assign(final SchemaValidationPolicy policy) { 415 this.checkAttributeValues = policy.checkAttributeValues; 416 this.checkNameForms = policy.checkNameForms; 417 this.checkAttributesAndObjectClasses = policy.checkAttributesAndObjectClasses; 418 this.checkDITContentRules = policy.checkDITContentRules; 419 this.checkDITStructureRules = policy.checkDITStructureRules; 420 this.checkDITStructureRulesEntryResolver = policy.checkDITStructureRulesEntryResolver; 421 this.requireSingleStructuralObjectClass = policy.requireSingleStructuralObjectClass; 422 return this; 423 } 424 425}