001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.model.schema; 021 022 023import java.util.ArrayList; 024import java.util.List; 025 026import org.apache.directory.api.i18n.I18n; 027 028/** 029 * A ditContentRule specification. ditContentRules identify the content of 030 * entries of a particular structural objectClass. They specify the AUXILIARY 031 * objectClasses and additional attribute types permitted to appear, or excluded 032 * from appearing in entries of the indicated STRUCTURAL objectClass. 033 * <p> 034 * According to ldapbis [MODELS]: 035 * </p> 036 * 037 * <pre> 038 * 4.1.6. DIT Content Rules 039 * 040 * A DIT content rule is a "rule governing the content of entries of a 041 * particular structural object class" [X.501]. 042 * 043 * For DIT entries of a particular structural object class, a DIT content 044 * rule specifies which auxiliary object classes the entries are allowed 045 * to belong to and which additional attributes (by type) are required, 046 * allowed or not allowed to appear in the entries. 047 * 048 * The list of precluded attributes cannot include any attribute listed 049 * as mandatory in rule, the structural object class, or any of the 050 * allowed auxiliary object classes. 051 * 052 * Each content rule is identified by the object identifier, as well as 053 * any short names (descriptors), of the structural object class it 054 * applies to. 055 * 056 * An entry may only belong to auxiliary object classes listed in the 057 * governing content rule. 058 * 059 * An entry must contain all attributes required by the object classes 060 * the entry belongs to as well as all attributed required by the 061 * governing content rule. 062 * 063 * An entry may contain any non-precluded attributes allowed by the 064 * object classes the entry belongs to as well as all attributes allowed 065 * by the governing content rule. 066 * 067 * An entry cannot include any attribute precluded by the governing 068 * content rule. 069 * 070 * An entry is governed by (if present and active in the subschema) the 071 * DIT content rule which applies to the structural object class of the 072 * entry (see Section 2.4.2). If no active rule is present for the 073 * entry's structural object class, the entry's content is governed by 074 * the structural object class (and possibly other aspects of user and 075 * system schema). 076 * 077 * DIT content rule descriptions are written according to the ABNF: 078 * 079 * DITContentRuleDescription = LPAREN WSP 080 * numericoid ; object identifier 081 * [ SP "NAME" SP qdescrs ] ; short names (descriptors) 082 * [ SP "DESC" SP qdstring ] ; description 083 * [ SP "OBSOLETE" ] ; not active 084 * [ SP "AUX" SP oids ] ; auxiliary object classes 085 * [ SP "MUST" SP oids ] ; attribute types 086 * [ SP "MAY" SP oids ] ; attribute types 087 * [ SP "NOT" SP oids ] ; attribute types 088 * extensions WSP RPAREN ; extensions 089 * 090 * where: 091 * 092 * [numericoid] is the object identifier of the structural object class 093 * associated with this DIT content rule; 094 * NAME [qdescrs] are short names (descriptors) identifying this DIT 095 * content rule; 096 * DESC [qdstring] is a short descriptive string; 097 * OBSOLETE indicates this DIT content rule use is not active; 098 * AUX specifies a list of auxiliary object classes which entries 099 * subject to this DIT content rule may belong to; 100 * MUST, MAY, and NOT specify lists of attribute types which are 101 * required, allowed, or precluded, respectively, from appearing in 102 * entries subject to this DIT content rule; and 103 * [extensions] describe extensions. 104 * </pre> 105 * 106 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC 2252 Section 5.4.3</a> 107 * @see <a 108 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis 109 * [MODELS]</a> 110 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 111 */ 112public class DitContentRule extends AbstractSchemaObject 113{ 114 /** The mandatory serialVersionUID */ 115 public static final long serialVersionUID = 1L; 116 117 /** The list of Auxiliary ObjectClass OIDs entries may belong to */ 118 private List<String> auxObjectClassOids; 119 120 /** The list of Auxiliary ObjectClass entries may belong to */ 121 private List<ObjectClass> auxObjectClasses; 122 123 /** The list of allowed AttributeType OIDs */ 124 private List<String> mayAttributeTypeOids; 125 126 /** The list of allowed AttributeTypes */ 127 private List<AttributeType> mayAttributeTypes; 128 129 /** The list of required AttributeType OIDs */ 130 private List<String> mustAttributeTypeOids; 131 132 /** The list of required AttributeTypes */ 133 private List<AttributeType> mustAttributeTypes; 134 135 /** The list of precluded AttributeType OIDs */ 136 private List<String> notAttributeTypeOids; 137 138 /** The list of precluded AttributeTypes */ 139 private List<AttributeType> notAttributeTypes; 140 141 142 /** 143 * Creates a DitContentRule object using a unique OID. 144 * 145 * @param oid the OID for this DitContentRule 146 */ 147 public DitContentRule( String oid ) 148 { 149 super( SchemaObjectType.DIT_CONTENT_RULE, oid ); 150 151 mayAttributeTypeOids = new ArrayList<>(); 152 mustAttributeTypeOids = new ArrayList<>(); 153 notAttributeTypeOids = new ArrayList<>(); 154 auxObjectClassOids = new ArrayList<>(); 155 156 mayAttributeTypes = new ArrayList<>(); 157 mustAttributeTypes = new ArrayList<>(); 158 notAttributeTypes = new ArrayList<>(); 159 auxObjectClasses = new ArrayList<>(); 160 } 161 162 163 /** 164 * @return the auxObjectClassOids 165 */ 166 public List<String> getAuxObjectClassOids() 167 { 168 return auxObjectClassOids; 169 } 170 171 172 /** 173 * Add an Auxiliary ObjectClass Oid 174 * 175 * @param oid The ObjectClass oid 176 */ 177 public void addAuxObjectClassOidOids( String oid ) 178 { 179 if ( locked ) 180 { 181 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 182 } 183 184 auxObjectClassOids.add( oid ); 185 } 186 187 188 /** 189 * Add an Auxiliary ObjectClass 190 * 191 * @param objectClass The ObjectClass 192 */ 193 public void addAuxObjectClasses( ObjectClass objectClass ) 194 { 195 if ( locked ) 196 { 197 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 198 } 199 200 if ( !auxObjectClassOids.contains( objectClass.getOid() ) ) 201 { 202 auxObjectClasses.add( objectClass ); 203 auxObjectClassOids.add( objectClass.getOid() ); 204 } 205 } 206 207 208 /** 209 * @param auxObjectClassOids the auxObjectClassOids to set 210 */ 211 public void setAuxObjectClassOids( List<String> auxObjectClassOids ) 212 { 213 if ( locked ) 214 { 215 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 216 } 217 218 this.auxObjectClassOids = auxObjectClassOids; 219 } 220 221 222 /** 223 * @param auxObjectClasses the auxObjectClasses to set 224 */ 225 public void setAuxObjectClasses( List<ObjectClass> auxObjectClasses ) 226 { 227 if ( locked ) 228 { 229 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 230 } 231 232 this.auxObjectClasses = auxObjectClasses; 233 234 // update the OIDS now 235 auxObjectClassOids.clear(); 236 237 for ( ObjectClass oc : auxObjectClasses ) 238 { 239 auxObjectClassOids.add( oc.getOid() ); 240 } 241 } 242 243 244 /** 245 * @return the auxObjectClasses 246 */ 247 public List<ObjectClass> getAuxObjectClasses() 248 { 249 return auxObjectClasses; 250 } 251 252 253 /** 254 * @return the mayAttributeTypeOids 255 */ 256 public List<String> getMayAttributeTypeOids() 257 { 258 return mayAttributeTypeOids; 259 } 260 261 262 /** 263 * Add an allowed AttributeType 264 * 265 * @param oid The attributeType oid 266 */ 267 public void addMayAttributeTypeOids( String oid ) 268 { 269 if ( locked ) 270 { 271 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 272 } 273 274 mayAttributeTypeOids.add( oid ); 275 } 276 277 278 /** 279 * Add an allowed AttributeType 280 * 281 * @param attributeType The attributeType 282 */ 283 public void addMayAttributeTypes( AttributeType attributeType ) 284 { 285 if ( locked ) 286 { 287 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 288 } 289 290 if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) ) 291 { 292 mayAttributeTypes.add( attributeType ); 293 mayAttributeTypeOids.add( attributeType.getOid() ); 294 } 295 } 296 297 298 /** 299 * @param mayAttributeTypeOids the mayAttributeTypeOids to set 300 */ 301 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids ) 302 { 303 if ( locked ) 304 { 305 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 306 } 307 308 this.mayAttributeTypeOids = mayAttributeTypeOids; 309 } 310 311 312 /** 313 * Sets the list of allowed AttributeTypes 314 * 315 * @param mayAttributeTypes the list of allowed AttributeTypes 316 */ 317 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 318 { 319 if ( locked ) 320 { 321 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 322 } 323 324 this.mayAttributeTypes = mayAttributeTypes; 325 326 // update the OIDS now 327 mayAttributeTypeOids.clear(); 328 329 for ( AttributeType may : mayAttributeTypes ) 330 { 331 mayAttributeTypeOids.add( may.getOid() ); 332 } 333 } 334 335 336 /** 337 * @return the mayAttributeTypes 338 */ 339 public List<AttributeType> getMayAttributeTypes() 340 { 341 return mayAttributeTypes; 342 } 343 344 345 /** 346 * @return the mustAttributeTypeOids 347 */ 348 public List<String> getMustAttributeTypeOids() 349 { 350 return mustAttributeTypeOids; 351 } 352 353 354 /** 355 * Add a required AttributeType OID 356 * 357 * @param oid The attributeType OID 358 */ 359 public void addMustAttributeTypeOids( String oid ) 360 { 361 if ( locked ) 362 { 363 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 364 } 365 366 mustAttributeTypeOids.add( oid ); 367 } 368 369 370 /** 371 * Add a required AttributeType 372 * 373 * @param attributeType The attributeType 374 */ 375 public void addMustAttributeTypes( AttributeType attributeType ) 376 { 377 if ( locked ) 378 { 379 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 380 } 381 382 if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) ) 383 { 384 mustAttributeTypes.add( attributeType ); 385 mustAttributeTypeOids.add( attributeType.getOid() ); 386 } 387 } 388 389 390 /** 391 * @param mustAttributeTypeOids the mustAttributeTypeOids to set 392 */ 393 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids ) 394 { 395 if ( locked ) 396 { 397 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 398 } 399 400 this.mustAttributeTypeOids = mustAttributeTypeOids; 401 } 402 403 404 /** 405 * Sets the list of required AttributeTypes 406 * 407 * @param mustAttributeTypes the list of required AttributeTypes 408 */ 409 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 410 { 411 if ( locked ) 412 { 413 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 414 } 415 416 this.mustAttributeTypes = mustAttributeTypes; 417 418 // update the OIDS now 419 mustAttributeTypeOids.clear(); 420 421 for ( AttributeType may : mustAttributeTypes ) 422 { 423 mustAttributeTypeOids.add( may.getOid() ); 424 } 425 } 426 427 428 /** 429 * @return the mustAttributeTypes 430 */ 431 public List<AttributeType> getMustAttributeTypes() 432 { 433 return mustAttributeTypes; 434 } 435 436 437 /** 438 * @return the notAttributeTypeOids 439 */ 440 public List<String> getNotAttributeTypeOids() 441 { 442 return notAttributeTypeOids; 443 } 444 445 446 /** 447 * Add a precluded AttributeType 448 * 449 * @param oid The attributeType oid 450 */ 451 public void addNotAttributeTypeOids( String oid ) 452 { 453 if ( locked ) 454 { 455 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 456 } 457 458 notAttributeTypeOids.add( oid ); 459 } 460 461 462 /** 463 * Add a precluded AttributeType 464 * 465 * @param attributeType The attributeType 466 */ 467 public void addNotAttributeTypes( AttributeType attributeType ) 468 { 469 if ( locked ) 470 { 471 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 472 } 473 474 if ( !notAttributeTypeOids.contains( attributeType.getOid() ) ) 475 { 476 notAttributeTypes.add( attributeType ); 477 notAttributeTypeOids.add( attributeType.getOid() ); 478 } 479 } 480 481 482 /** 483 * @param notAttributeTypeOids the notAttributeTypeOids to set 484 */ 485 public void setNotAttributeTypeOids( List<String> notAttributeTypeOids ) 486 { 487 if ( locked ) 488 { 489 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 490 } 491 492 this.notAttributeTypeOids = notAttributeTypeOids; 493 } 494 495 496 /** 497 * Sets the list of precluded AttributeTypes 498 * 499 * @param notAttributeTypes the list of precluded AttributeTypes 500 */ 501 public void setNotAttributeTypes( List<AttributeType> notAttributeTypes ) 502 { 503 if ( locked ) 504 { 505 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 506 } 507 508 this.notAttributeTypes = notAttributeTypes; 509 510 // update the OIDS now 511 notAttributeTypeOids.clear(); 512 513 for ( AttributeType not : notAttributeTypes ) 514 { 515 notAttributeTypeOids.add( not.getOid() ); 516 } 517 } 518 519 520 /** 521 * @return the notAttributeTypes 522 */ 523 public List<AttributeType> getNotAttributeTypes() 524 { 525 return notAttributeTypes; 526 } 527 528 529 /** 530 * @see Object#toString() 531 */ 532 @Override 533 public String toString() 534 { 535 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 536 } 537 538 539 /** 540 * Copy a DitContentRule 541 */ 542 @Override 543 public DitContentRule copy() 544 { 545 DitContentRule copy = new DitContentRule( oid ); 546 547 // Copy the SchemaObject common data 548 copy.copy( this ); 549 550 // copy the AUX ObjectClasses OIDs 551 copy.auxObjectClassOids = new ArrayList<>(); 552 553 for ( String oid : auxObjectClassOids ) 554 { 555 copy.auxObjectClassOids.add( oid ); 556 } 557 558 // copy the AUX ObjectClasses ( will be empty ) 559 copy.auxObjectClasses = new ArrayList<>(); 560 561 // Clone the MAY AttributeTypes OIDs 562 copy.mayAttributeTypeOids = new ArrayList<>(); 563 564 for ( String oid : mayAttributeTypeOids ) 565 { 566 copy.mayAttributeTypeOids.add( oid ); 567 } 568 569 // Clone the MAY AttributeTypes ( will be empty ) 570 copy.mayAttributeTypes = new ArrayList<>(); 571 572 // Clone the MUST AttributeTypes OIDs 573 copy.mustAttributeTypeOids = new ArrayList<>(); 574 575 for ( String oid : mustAttributeTypeOids ) 576 { 577 copy.mustAttributeTypeOids.add( oid ); 578 } 579 580 // Clone the MUST AttributeTypes ( will be empty ) 581 copy.mustAttributeTypes = new ArrayList<>(); 582 583 // Clone the NOT AttributeTypes OIDs 584 copy.notAttributeTypeOids = new ArrayList<>(); 585 586 for ( String oid : notAttributeTypeOids ) 587 { 588 copy.notAttributeTypeOids.add( oid ); 589 } 590 591 // Clone the NOT AttributeTypes ( will be empty ) 592 copy.notAttributeTypes = new ArrayList<>(); 593 594 return copy; 595 } 596 597 598 /** 599 * @see Object#equals(Object) 600 */ 601 @Override 602 public int hashCode() 603 { 604 int hash = h; 605 606 // TODO: complete this method 607 608 return hash; 609 } 610 611 612 /** 613 * @see Object#equals(Object) 614 */ 615 @Override 616 public boolean equals( Object o ) 617 { 618 if ( !super.equals( o ) ) 619 { 620 return false; 621 } 622 623 if ( !( o instanceof DitContentRule ) ) 624 { 625 return false; 626 } 627 628 @SuppressWarnings("unused") 629 DitContentRule that = ( DitContentRule ) o; 630 631 // TODO : complete the check 632 return true; 633 } 634 635 636 /** 637 * {@inheritDoc} 638 */ 639 @Override 640 public void clear() 641 { 642 // Clear the common elements 643 super.clear(); 644 645 // Clear the references 646 auxObjectClasses.clear(); 647 auxObjectClassOids.clear(); 648 mayAttributeTypes.clear(); 649 mayAttributeTypeOids.clear(); 650 mustAttributeTypes.clear(); 651 mustAttributeTypeOids.clear(); 652 notAttributeTypes.clear(); 653 notAttributeTypeOids.clear(); 654 } 655}