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 * @see DescriptionUtils#getDescription(DitContentRule) 112 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 113 */ 114public class DitContentRule extends AbstractSchemaObject 115{ 116 /** The mandatory serialVersionUID */ 117 public static final long serialVersionUID = 1L; 118 119 /** The list of Auxiliary ObjectClass OIDs entries may belong to */ 120 private List<String> auxObjectClassOids; 121 122 /** The list of Auxiliary ObjectClass entries may belong to */ 123 private List<ObjectClass> auxObjectClasses; 124 125 /** The list of allowed AttributeType OIDs */ 126 private List<String> mayAttributeTypeOids; 127 128 /** The list of allowed AttributeTypes */ 129 private List<AttributeType> mayAttributeTypes; 130 131 /** The list of required AttributeType OIDs */ 132 private List<String> mustAttributeTypeOids; 133 134 /** The list of required AttributeTypes */ 135 private List<AttributeType> mustAttributeTypes; 136 137 /** The list of precluded AttributeType OIDs */ 138 private List<String> notAttributeTypeOids; 139 140 /** The list of precluded AttributeTypes */ 141 private List<AttributeType> notAttributeTypes; 142 143 144 /** 145 * Creates a DitContentRule object using a unique OID. 146 * 147 * @param oid the OID for this DitContentRule 148 */ 149 public DitContentRule( String oid ) 150 { 151 super( SchemaObjectType.DIT_CONTENT_RULE, oid ); 152 153 mayAttributeTypeOids = new ArrayList<String>(); 154 mustAttributeTypeOids = new ArrayList<String>(); 155 notAttributeTypeOids = new ArrayList<String>(); 156 auxObjectClassOids = new ArrayList<String>(); 157 158 mayAttributeTypes = new ArrayList<AttributeType>(); 159 mustAttributeTypes = new ArrayList<AttributeType>(); 160 notAttributeTypes = new ArrayList<AttributeType>(); 161 auxObjectClasses = new ArrayList<ObjectClass>(); 162 } 163 164 165 /** 166 * @return the auxObjectClassOids 167 */ 168 public List<String> getAuxObjectClassOids() 169 { 170 return auxObjectClassOids; 171 } 172 173 174 /** 175 * Add an Auxiliary ObjectClass Oid 176 * 177 * @param oid The ObjectClass oid 178 */ 179 public void addAuxObjectClassOidOids( String oid ) 180 { 181 if ( locked ) 182 { 183 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 184 } 185 186 if ( !isReadOnly ) 187 { 188 auxObjectClassOids.add( oid ); 189 } 190 } 191 192 193 /** 194 * Add an Auxiliary ObjectClass 195 * 196 * @param objectClass The ObjectClass 197 */ 198 public void addAuxObjectClasses( ObjectClass objectClass ) 199 { 200 if ( locked ) 201 { 202 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 203 } 204 205 if ( !isReadOnly && !auxObjectClassOids.contains( objectClass.getOid() ) ) 206 { 207 auxObjectClasses.add( objectClass ); 208 auxObjectClassOids.add( objectClass.getOid() ); 209 } 210 } 211 212 213 /** 214 * @param auxObjectClassOids the auxObjectClassOids to set 215 */ 216 public void setAuxObjectClassOids( List<String> auxObjectClassOids ) 217 { 218 if ( locked ) 219 { 220 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 221 } 222 223 if ( !isReadOnly ) 224 { 225 this.auxObjectClassOids = auxObjectClassOids; 226 } 227 } 228 229 230 /** 231 * @param auxObjectClasses the auxObjectClasses to set 232 */ 233 public void setAuxObjectClasses( List<ObjectClass> auxObjectClasses ) 234 { 235 if ( locked ) 236 { 237 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 238 } 239 240 if ( !isReadOnly ) 241 { 242 this.auxObjectClasses = auxObjectClasses; 243 244 // update the OIDS now 245 auxObjectClassOids.clear(); 246 247 for ( ObjectClass oc : auxObjectClasses ) 248 { 249 auxObjectClassOids.add( oc.getOid() ); 250 } 251 } 252 } 253 254 255 /** 256 * @return the auxObjectClasses 257 */ 258 public List<ObjectClass> getAuxObjectClasses() 259 { 260 return auxObjectClasses; 261 } 262 263 264 /** 265 * @return the mayAttributeTypeOids 266 */ 267 public List<String> getMayAttributeTypeOids() 268 { 269 return mayAttributeTypeOids; 270 } 271 272 273 /** 274 * Add an allowed AttributeType 275 * 276 * @param oid The attributeType oid 277 */ 278 public void addMayAttributeTypeOids( String oid ) 279 { 280 if ( locked ) 281 { 282 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 283 } 284 285 if ( !isReadOnly ) 286 { 287 mayAttributeTypeOids.add( oid ); 288 } 289 } 290 291 292 /** 293 * Add an allowed AttributeType 294 * 295 * @param attributeType The attributeType 296 */ 297 public void addMayAttributeTypes( AttributeType attributeType ) 298 { 299 if ( locked ) 300 { 301 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 302 } 303 304 if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) ) 305 { 306 mayAttributeTypes.add( attributeType ); 307 mayAttributeTypeOids.add( attributeType.getOid() ); 308 } 309 } 310 311 312 /** 313 * @param mayAttributeTypeOids the mayAttributeTypeOids to set 314 */ 315 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids ) 316 { 317 if ( locked ) 318 { 319 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 320 } 321 322 if ( !isReadOnly ) 323 { 324 this.mayAttributeTypeOids = mayAttributeTypeOids; 325 } 326 } 327 328 329 /** 330 * Sets the list of allowed AttributeTypes 331 * 332 * @param mayAttributeTypes the list of allowed AttributeTypes 333 */ 334 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 335 { 336 if ( locked ) 337 { 338 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 339 } 340 341 if ( !isReadOnly ) 342 { 343 this.mayAttributeTypes = mayAttributeTypes; 344 345 // update the OIDS now 346 mayAttributeTypeOids.clear(); 347 348 for ( AttributeType may : mayAttributeTypes ) 349 { 350 mayAttributeTypeOids.add( may.getOid() ); 351 } 352 } 353 } 354 355 356 /** 357 * @return the mayAttributeTypes 358 */ 359 public List<AttributeType> getMayAttributeTypes() 360 { 361 return mayAttributeTypes; 362 } 363 364 365 /** 366 * @return the mustAttributeTypeOids 367 */ 368 public List<String> getMustAttributeTypeOids() 369 { 370 return mustAttributeTypeOids; 371 } 372 373 374 /** 375 * Add a required AttributeType OID 376 * 377 * @param oid The attributeType OID 378 */ 379 public void addMustAttributeTypeOids( String oid ) 380 { 381 if ( locked ) 382 { 383 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 384 } 385 386 if ( !isReadOnly ) 387 { 388 mustAttributeTypeOids.add( oid ); 389 } 390 } 391 392 393 /** 394 * Add a required AttributeType 395 * 396 * @param attributeType The attributeType 397 */ 398 public void addMustAttributeTypes( AttributeType attributeType ) 399 { 400 if ( locked ) 401 { 402 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 403 } 404 405 if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) ) 406 { 407 mustAttributeTypes.add( attributeType ); 408 mustAttributeTypeOids.add( attributeType.getOid() ); 409 } 410 } 411 412 413 /** 414 * @param mustAttributeTypeOids the mustAttributeTypeOids to set 415 */ 416 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids ) 417 { 418 if ( locked ) 419 { 420 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 421 } 422 423 if ( !isReadOnly ) 424 { 425 this.mustAttributeTypeOids = mustAttributeTypeOids; 426 } 427 } 428 429 430 /** 431 * Sets the list of required AttributeTypes 432 * 433 * @param mustAttributeTypes the list of required AttributeTypes 434 */ 435 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 436 { 437 if ( locked ) 438 { 439 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 440 } 441 442 if ( !isReadOnly ) 443 { 444 this.mustAttributeTypes = mustAttributeTypes; 445 446 // update the OIDS now 447 mustAttributeTypeOids.clear(); 448 449 for ( AttributeType may : mustAttributeTypes ) 450 { 451 mustAttributeTypeOids.add( may.getOid() ); 452 } 453 } 454 } 455 456 457 /** 458 * @return the mustAttributeTypes 459 */ 460 public List<AttributeType> getMustAttributeTypes() 461 { 462 return mustAttributeTypes; 463 } 464 465 466 /** 467 * @return the notAttributeTypeOids 468 */ 469 public List<String> getNotAttributeTypeOids() 470 { 471 return notAttributeTypeOids; 472 } 473 474 475 /** 476 * Add a precluded AttributeType 477 * 478 * @param oid The attributeType oid 479 */ 480 public void addNotAttributeTypeOids( String oid ) 481 { 482 if ( locked ) 483 { 484 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 485 } 486 487 if ( !isReadOnly ) 488 { 489 notAttributeTypeOids.add( oid ); 490 } 491 } 492 493 494 /** 495 * Add a precluded AttributeType 496 * 497 * @param attributeType The attributeType 498 */ 499 public void addNotAttributeTypes( AttributeType attributeType ) 500 { 501 if ( locked ) 502 { 503 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 504 } 505 506 if ( !isReadOnly && !notAttributeTypeOids.contains( attributeType.getOid() ) ) 507 { 508 notAttributeTypes.add( attributeType ); 509 notAttributeTypeOids.add( attributeType.getOid() ); 510 } 511 } 512 513 514 /** 515 * @param notAttributeTypeOids the notAttributeTypeOids to set 516 */ 517 public void setNotAttributeTypeOids( List<String> notAttributeTypeOids ) 518 { 519 if ( locked ) 520 { 521 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 522 } 523 524 if ( !isReadOnly ) 525 { 526 this.notAttributeTypeOids = notAttributeTypeOids; 527 } 528 } 529 530 531 /** 532 * Sets the list of precluded AttributeTypes 533 * 534 * @param notAttributeTypes the list of precluded AttributeTypes 535 */ 536 public void setNotAttributeTypes( List<AttributeType> notAttributeTypes ) 537 { 538 if ( locked ) 539 { 540 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 541 } 542 543 if ( !isReadOnly ) 544 { 545 this.notAttributeTypes = notAttributeTypes; 546 547 // update the OIDS now 548 notAttributeTypeOids.clear(); 549 550 for ( AttributeType not : notAttributeTypes ) 551 { 552 notAttributeTypeOids.add( not.getOid() ); 553 } 554 } 555 } 556 557 558 /** 559 * @return the notAttributeTypes 560 */ 561 public List<AttributeType> getNotAttributeTypes() 562 { 563 return notAttributeTypes; 564 } 565 566 567 /** 568 * @see Object#toString() 569 */ 570 public String toString() 571 { 572 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 573 } 574 575 576 /** 577 * Copy a DitContentRule 578 */ 579 public DitContentRule copy() 580 { 581 DitContentRule copy = new DitContentRule( oid ); 582 583 // Copy the SchemaObject common data 584 copy.copy( this ); 585 586 // copy the AUX ObjectClasses OIDs 587 copy.auxObjectClassOids = new ArrayList<String>(); 588 589 for ( String oid : auxObjectClassOids ) 590 { 591 copy.auxObjectClassOids.add( oid ); 592 } 593 594 // copy the AUX ObjectClasses ( will be empty ) 595 copy.auxObjectClasses = new ArrayList<ObjectClass>(); 596 597 // Clone the MAY AttributeTypes OIDs 598 copy.mayAttributeTypeOids = new ArrayList<String>(); 599 600 for ( String oid : mayAttributeTypeOids ) 601 { 602 copy.mayAttributeTypeOids.add( oid ); 603 } 604 605 // Clone the MAY AttributeTypes ( will be empty ) 606 copy.mayAttributeTypes = new ArrayList<AttributeType>(); 607 608 // Clone the MUST AttributeTypes OIDs 609 copy.mustAttributeTypeOids = new ArrayList<String>(); 610 611 for ( String oid : mustAttributeTypeOids ) 612 { 613 copy.mustAttributeTypeOids.add( oid ); 614 } 615 616 // Clone the MUST AttributeTypes ( will be empty ) 617 copy.mustAttributeTypes = new ArrayList<AttributeType>(); 618 619 // Clone the NOT AttributeTypes OIDs 620 copy.notAttributeTypeOids = new ArrayList<String>(); 621 622 for ( String oid : notAttributeTypeOids ) 623 { 624 copy.notAttributeTypeOids.add( oid ); 625 } 626 627 // Clone the NOT AttributeTypes ( will be empty ) 628 copy.notAttributeTypes = new ArrayList<AttributeType>(); 629 630 return copy; 631 } 632 633 634 /** 635 * @see Object#equals(Object) 636 */ 637 @Override 638 public boolean equals( Object o ) 639 { 640 if ( !super.equals( o ) ) 641 { 642 return false; 643 } 644 645 if ( !( o instanceof DitContentRule ) ) 646 { 647 return false; 648 } 649 650 @SuppressWarnings("unused") 651 DitContentRule that = ( DitContentRule ) o; 652 653 // TODO : complete the check 654 return true; 655 } 656 657 658 /** 659 * {@inheritDoc} 660 */ 661 public void clear() 662 { 663 // Clear the common elements 664 super.clear(); 665 666 // Clear the references 667 auxObjectClasses.clear(); 668 auxObjectClassOids.clear(); 669 mayAttributeTypes.clear(); 670 mayAttributeTypeOids.clear(); 671 mustAttributeTypes.clear(); 672 mustAttributeTypeOids.clear(); 673 notAttributeTypes.clear(); 674 notAttributeTypeOids.clear(); 675 } 676}