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