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 */ 020 package org.apache.directory.shared.ldap.schema; 021 022 023 import java.util.ArrayList; 024 import java.util.List; 025 026 import org.apache.directory.shared.i18n.I18n; 027 import org.apache.directory.shared.ldap.exception.LdapException; 028 import org.apache.directory.shared.ldap.exception.LdapProtocolErrorException; 029 import org.apache.directory.shared.ldap.schema.registries.AttributeTypeRegistry; 030 import org.apache.directory.shared.ldap.schema.registries.ObjectClassRegistry; 031 import org.apache.directory.shared.ldap.schema.registries.Registries; 032 033 034 /** 035 * An objectClass definition. 036 * <p> 037 * According to ldapbis [MODELS]: 038 * </p> 039 * 040 * <pre> 041 * Object Class definitions are written according to the ABNF: 042 * 043 * ObjectClassDescription = LPAREN WSP 044 * numericoid ; object identifier 045 * [ SP "NAME" SP qdescrs ] ; short names (descriptors) 046 * [ SP "DESC" SP qdstring ] ; description 047 * [ SP "OBSOLETE" ] ; not active 048 * [ SP "SUP" SP oids ] ; superior object classes 049 * [ SP kind ] ; kind of class 050 * [ SP "MUST" SP oids ] ; attribute types 051 * [ SP "MAY" SP oids ] ; attribute types 052 * extensions WSP RPAREN 053 * 054 * kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" 055 * 056 * where: 057 * [numericoid] is object identifier assigned to this object class; 058 * NAME [qdescrs] are short names (descriptors) identifying this object 059 * class; 060 * DESC [qdstring] is a short descriptive string; 061 * OBSOLETE indicates this object class is not active; 062 * SUP [oids] specifies the direct superclasses of this object class; 063 * the kind of object class is indicated by one of ABSTRACT, 064 * STRUCTURAL, or AUXILIARY, default is STRUCTURAL; 065 * MUST and MAY specify the sets of required and allowed attribute 066 * types, respectively; and 067 * [extensions] describe extensions. 068 * </pre> 069 * 070 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC2252 Section 4.4</a> 071 * @see <a 072 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis 073 * [MODELS]</a> 074 * @see DescriptionUtils#getDescription(ObjectClass) 075 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 076 * @version $Rev: 927122 $ 077 */ 078 public class ObjectClass extends AbstractSchemaObject 079 { 080 /** The serialVersionUID */ 081 private static final long serialVersionUID = 1L; 082 083 /** The ObjectClass type : ABSTRACT, AUXILIARY or STRUCTURAL */ 084 private ObjectClassTypeEnum objectClassType = ObjectClassTypeEnum.STRUCTURAL; 085 086 /** The ObjectClass superior OIDs */ 087 private List<String> superiorOids; 088 089 /** The ObjectClass superiors */ 090 private List<ObjectClass> superiors; 091 092 /** The list of allowed AttributeType OIDs */ 093 private List<String> mayAttributeTypeOids; 094 095 /** The list of allowed AttributeTypes */ 096 private List<AttributeType> mayAttributeTypes; 097 098 /** The list of required AttributeType OIDs */ 099 private List<String> mustAttributeTypeOids; 100 101 /** The list of required AttributeTypes */ 102 private List<AttributeType> mustAttributeTypes; 103 104 105 /** 106 * Creates a new instance of MatchingRuleUseDescription 107 * @param oid the OID for this objectClass 108 */ 109 public ObjectClass( String oid ) 110 { 111 super( SchemaObjectType.OBJECT_CLASS, oid ); 112 113 mayAttributeTypeOids = new ArrayList<String>(); 114 mustAttributeTypeOids = new ArrayList<String>(); 115 superiorOids = new ArrayList<String>(); 116 117 mayAttributeTypes = new ArrayList<AttributeType>(); 118 mustAttributeTypes = new ArrayList<AttributeType>(); 119 superiors = new ArrayList<ObjectClass>(); 120 objectClassType = ObjectClassTypeEnum.STRUCTURAL; 121 } 122 123 124 private void buildSuperiors( List<Throwable> errors, Registries registries ) 125 { 126 ObjectClassRegistry ocRegistry = registries.getObjectClassRegistry(); 127 128 if ( superiorOids != null ) 129 { 130 superiors = new ArrayList<ObjectClass>( superiorOids.size() ); 131 132 for ( String superiorName : superiorOids ) 133 { 134 try 135 { 136 ObjectClass superior = ocRegistry.lookup( ocRegistry.getOidByName( superiorName ) ); 137 138 // Before adding the superior, check that the ObjectClass type is consistent 139 switch ( objectClassType ) 140 { 141 case ABSTRACT: 142 if ( superior.objectClassType != ObjectClassTypeEnum.ABSTRACT ) 143 { 144 // An ABSTRACT OC can only inherit from ABSTRACT OCs 145 String msg = I18n.err( I18n.ERR_04318, oid , superior.getObjectType() , superior ); 146 147 Throwable error = new LdapProtocolErrorException( msg ); 148 errors.add( error ); 149 return; 150 } 151 152 break; 153 154 case AUXILIARY: 155 if ( superior.objectClassType == ObjectClassTypeEnum.STRUCTURAL ) 156 { 157 // An AUXILIARY OC can only inherit from STRUCTURAL OCs 158 String msg = I18n.err( I18n.ERR_04319, oid, superior ); 159 160 Throwable error = new LdapProtocolErrorException( msg ); 161 errors.add( error ); 162 return; 163 } 164 165 break; 166 167 case STRUCTURAL: 168 if ( superior.objectClassType == ObjectClassTypeEnum.AUXILIARY ) 169 { 170 // A STRUCTURAL OC can only inherit from AUXILIARY OCs 171 String msg = I18n.err( I18n.ERR_04320, oid, superior ); 172 173 Throwable error = new LdapProtocolErrorException( msg ); 174 errors.add( error ); 175 return; 176 } 177 178 break; 179 } 180 181 superiors.add( superior ); 182 } 183 catch ( LdapException ne ) 184 { 185 // Cannot find the OC 186 String msg = I18n.err( I18n.ERR_04321, oid, superiorName ); 187 188 Throwable error = new LdapProtocolErrorException( msg ); 189 errors.add( error ); 190 return; 191 } 192 } 193 } 194 } 195 196 197 private void buildMay( List<Throwable> errors, Registries registries ) 198 { 199 AttributeTypeRegistry atRegistry = registries.getAttributeTypeRegistry(); 200 201 if ( mayAttributeTypeOids != null ) 202 { 203 mayAttributeTypes = new ArrayList<AttributeType>( mayAttributeTypeOids.size() ); 204 205 for ( String mayAttributeTypeName : mayAttributeTypeOids ) 206 { 207 try 208 { 209 AttributeType attributeType = atRegistry.lookup( mayAttributeTypeName ); 210 211 if ( mayAttributeTypes.contains( attributeType ) ) 212 { 213 // Already registered : this is an error 214 String msg = I18n.err( I18n.ERR_04322, oid, mayAttributeTypeName ); 215 Throwable error = new LdapProtocolErrorException( msg ); 216 errors.add( error ); 217 break; 218 } 219 220 mayAttributeTypes.add( attributeType ); 221 } 222 catch ( LdapException ne ) 223 { 224 // Cannot find the AT 225 String msg = I18n.err( I18n.ERR_04323, oid, mayAttributeTypeName ); 226 227 Throwable error = new LdapProtocolErrorException( msg ); 228 errors.add( error ); 229 break; 230 } 231 } 232 } 233 } 234 235 236 private void buildMust( List<Throwable> errors, Registries registries ) 237 { 238 AttributeTypeRegistry atRegistry = registries.getAttributeTypeRegistry(); 239 240 if ( mustAttributeTypeOids != null ) 241 { 242 mustAttributeTypes = new ArrayList<AttributeType>( mustAttributeTypeOids.size() ); 243 244 for ( String mustAttributeTypeName : mustAttributeTypeOids ) 245 { 246 try 247 { 248 AttributeType attributeType = atRegistry.lookup( mustAttributeTypeName ); 249 250 if ( mustAttributeTypes.contains( attributeType ) ) 251 { 252 // Already registered : this is an error 253 String msg = I18n.err( I18n.ERR_04324, oid, mustAttributeTypeName ); 254 255 Throwable error = new LdapProtocolErrorException( msg ); 256 errors.add( error ); 257 break; 258 } 259 260 // Check that the MUST AT is not also present in the MAY AT 261 if ( mayAttributeTypes.contains( attributeType ) ) 262 { 263 // Already registered : this is an error 264 String msg = I18n.err( I18n.ERR_04325, oid, mustAttributeTypeName ); 265 266 Throwable error = new LdapProtocolErrorException( msg ); 267 errors.add( error ); 268 break; 269 } 270 271 mustAttributeTypes.add( attributeType ); 272 } 273 catch ( LdapException ne ) 274 { 275 // Cannot find the AT 276 String msg = I18n.err( I18n.ERR_04326, oid, mustAttributeTypeName ); 277 278 Throwable error = new LdapProtocolErrorException( msg ); 279 errors.add( error ); 280 break; 281 } 282 } 283 } 284 } 285 286 287 /** 288 * Inject the ObjectClass into the registries, updating the references to 289 * other SchemaObject 290 * 291 * @param errors The errors we got while adding the ObjectClass to the registries 292 * @param registries The Registries 293 * @throws Exception on failure 294 * 295 */ 296 public void addToRegistries( List<Throwable> errors, Registries registries ) throws LdapException 297 { 298 if ( registries != null ) 299 { 300 // The superiors 301 buildSuperiors( errors, registries ); 302 303 // The MAY AttributeTypes 304 buildMay( errors, registries ); 305 306 // The MUST AttributeTypes 307 buildMust( errors, registries ); 308 309 /** 310 * Add the OC references (using and usedBy) : 311 * OC -> AT (MAY and MUST) 312 * OC -> OC (SUPERIORS) 313 */ 314 for ( AttributeType mayAttributeType : mayAttributeTypes ) 315 { 316 registries.addReference( this, mayAttributeType ); 317 } 318 319 for ( AttributeType mustAttributeType : mustAttributeTypes ) 320 { 321 registries.addReference( this, mustAttributeType ); 322 } 323 324 for ( ObjectClass superiorObjectClass : superiors ) 325 { 326 registries.addReference( this, superiorObjectClass ); 327 } 328 } 329 } 330 331 332 /** 333 * Remove the ObjectClass from the registries, updating the references to 334 * other SchemaObject. 335 * 336 * If one of the referenced SchemaObject does not exist (SUPERIORS, MAY, MUST), 337 * an exception is thrown. 338 * 339 * @param errors The errors we got while removing the ObjectClass from the registries 340 * @param registries The Registries 341 * @exception If the ObjectClass is not valid 342 */ 343 public void removeFromRegistries( List<Throwable> errors, Registries registries ) throws LdapException 344 { 345 if ( registries != null ) 346 { 347 ObjectClassRegistry objectClassRegistry = registries.getObjectClassRegistry(); 348 349 // Unregister this ObjectClass into the Descendant map 350 objectClassRegistry.unregisterDescendants( this, superiors ); 351 352 /** 353 * Remove the OC references (using and usedBy) : 354 * OC -> AT (for MAY and MUST) 355 * OC -> OC 356 */ 357 if ( mayAttributeTypes != null ) 358 { 359 for ( AttributeType may : mayAttributeTypes ) 360 { 361 registries.delReference( this, may ); 362 } 363 } 364 365 if ( mustAttributeTypes != null ) 366 { 367 for ( AttributeType must : mustAttributeTypes ) 368 { 369 registries.delReference( this, must ); 370 } 371 } 372 373 if ( superiors != null ) 374 { 375 for ( ObjectClass superior : superiors ) 376 { 377 registries.delReference( this, superior ); 378 } 379 } 380 } 381 } 382 383 384 /** 385 * @return the mayAttributeTypeOids 386 */ 387 public List<String> getMayAttributeTypeOids() 388 { 389 return mayAttributeTypeOids; 390 } 391 392 393 /** 394 * @return the mayAttributeTypes 395 */ 396 public List<AttributeType> getMayAttributeTypes() 397 { 398 return mayAttributeTypes; 399 } 400 401 402 /** 403 * Add some allowed AttributeType 404 * 405 * @param oids The attributeType oids 406 */ 407 public void addMayAttributeTypeOids( String... oids ) 408 { 409 if ( locked ) 410 { 411 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 412 } 413 414 if ( !isReadOnly ) 415 { 416 for ( String oid : oids ) 417 { 418 mayAttributeTypeOids.add( oid ); 419 } 420 } 421 } 422 423 424 /** 425 * Add some allowed AttributeTypes 426 * 427 * @param attributeTypes The attributeTypes 428 */ 429 public void addMayAttributeTypes( AttributeType... attributeTypes ) 430 { 431 if ( locked ) 432 { 433 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 434 } 435 436 if ( !isReadOnly ) 437 { 438 for ( AttributeType attributeType : attributeTypes ) 439 { 440 if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) ) 441 { 442 mayAttributeTypes.add( attributeType ); 443 mayAttributeTypeOids.add( attributeType.getOid() ); 444 } 445 } 446 } 447 } 448 449 450 /** 451 * @param mayAttributeTypeOids the mayAttributeTypeOids to set 452 */ 453 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids ) 454 { 455 if ( locked ) 456 { 457 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 458 } 459 460 if ( !isReadOnly ) 461 { 462 this.mayAttributeTypeOids = mayAttributeTypeOids; 463 } 464 } 465 466 467 /** 468 * Sets the list of allowed AttributeTypes 469 * 470 * @param mayAttributeTypes the list of allowed AttributeTypes 471 */ 472 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 473 { 474 if ( locked ) 475 { 476 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 477 } 478 479 if ( !isReadOnly ) 480 { 481 this.mayAttributeTypes = mayAttributeTypes; 482 483 // update the OIDS now 484 mayAttributeTypeOids.clear(); 485 486 for ( AttributeType may : mayAttributeTypes ) 487 { 488 mayAttributeTypeOids.add( may.getOid() ); 489 } 490 } 491 } 492 493 494 /** 495 * Update the associated MAY AttributeType, even if the SchemaObject is readOnly 496 * 497 * @param mayAttributeTypes the list of allowed AttributeTypes 498 */ 499 public void updateMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 500 { 501 this.mayAttributeTypes.clear(); 502 this.mayAttributeTypes.addAll( mayAttributeTypes ); 503 504 // update the OIDS now 505 mayAttributeTypeOids.clear(); 506 507 for ( AttributeType may : mayAttributeTypes ) 508 { 509 mayAttributeTypeOids.add( may.getOid() ); 510 } 511 } 512 513 514 /** 515 * @return the mustAttributeTypeOids 516 */ 517 public List<String> getMustAttributeTypeOids() 518 { 519 return mustAttributeTypeOids; 520 } 521 522 523 /** 524 * @return the mustAttributeTypes 525 */ 526 public List<AttributeType> getMustAttributeTypes() 527 { 528 return mustAttributeTypes; 529 } 530 531 532 /** 533 * Add some required AttributeType OIDs 534 * 535 * @param oid The attributeType OIDs 536 */ 537 public void addMustAttributeTypeOids( String... oids ) 538 { 539 if ( locked ) 540 { 541 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 542 } 543 544 if ( !isReadOnly ) 545 { 546 for ( String oid : oids ) 547 { 548 mustAttributeTypeOids.add( oid ); 549 } 550 } 551 } 552 553 554 /** 555 * Add some required AttributeTypes 556 * 557 * @param attributeTypes The attributeTypse 558 */ 559 public void addMustAttributeTypes( AttributeType... attributeTypes ) 560 { 561 if ( locked ) 562 { 563 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 564 } 565 566 if ( !isReadOnly ) 567 { 568 for ( AttributeType attributeType : attributeTypes ) 569 { 570 if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) ) 571 { 572 mustAttributeTypes.add( attributeType ); 573 mustAttributeTypeOids.add( attributeType.getOid() ); 574 } 575 } 576 } 577 } 578 579 580 /** 581 * @param mustAttributeTypeOids the mustAttributeTypeOids to set 582 */ 583 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids ) 584 { 585 if ( locked ) 586 { 587 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 588 } 589 590 if ( !isReadOnly ) 591 { 592 this.mustAttributeTypeOids = mustAttributeTypeOids; 593 } 594 } 595 596 597 /** 598 * Sets the list of required AttributeTypes 599 * 600 * @param mustAttributeTypes the list of required AttributeTypes 601 */ 602 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 603 { 604 if ( locked ) 605 { 606 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 607 } 608 609 if ( !isReadOnly ) 610 { 611 this.mustAttributeTypes = mustAttributeTypes; 612 613 // update the OIDS now 614 mustAttributeTypeOids.clear(); 615 616 for ( AttributeType may : mustAttributeTypes ) 617 { 618 mustAttributeTypeOids.add( may.getOid() ); 619 } 620 } 621 } 622 623 624 /** 625 * Update the associated MUST AttributeType, even if the SchemaObject is readOnly 626 * 627 * @param mayAttributeTypes the list of allowed AttributeTypes 628 */ 629 public void updateMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 630 { 631 this.mustAttributeTypes.clear(); 632 this.mustAttributeTypes.addAll( mustAttributeTypes ); 633 634 // update the OIDS now 635 mustAttributeTypeOids.clear(); 636 637 for ( AttributeType must : mustAttributeTypes ) 638 { 639 mustAttributeTypeOids.add( must.getOid() ); 640 } 641 } 642 643 644 /** 645 * Gets the superclasses of this ObjectClass. 646 * 647 * @return the superclasses 648 */ 649 public List<ObjectClass> getSuperiors() 650 { 651 return superiors; 652 } 653 654 655 /** 656 * Gets the superclasses OIDsof this ObjectClass. 657 * 658 * @return the superclasses OIDs 659 */ 660 public List<String> getSuperiorOids() 661 { 662 return superiorOids; 663 } 664 665 666 /** 667 * Add some superior ObjectClass OIDs 668 * 669 * @param oids The superior ObjectClass OIDs 670 */ 671 public void addSuperiorOids( String... oids ) 672 { 673 if ( locked ) 674 { 675 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 676 } 677 678 if ( !isReadOnly ) 679 { 680 for ( String oid : oids ) 681 { 682 if ( !superiorOids.contains( oid ) ) 683 { 684 superiorOids.add( oid ); 685 } 686 } 687 } 688 } 689 690 691 /** 692 * Add some superior ObjectClasses 693 * 694 * @param objectClasses The superior ObjectClasses 695 */ 696 public void addSuperior( ObjectClass... objectClasses ) 697 { 698 if ( locked ) 699 { 700 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 701 } 702 703 if ( !isReadOnly ) 704 { 705 for ( ObjectClass objectClass : objectClasses ) 706 { 707 if ( !superiorOids.contains( objectClass.getOid() ) ) 708 { 709 superiorOids.add( objectClass.getOid() ); 710 superiors.add( objectClass ); 711 } 712 } 713 } 714 } 715 716 717 /** 718 * Sets the superior object classes 719 * 720 * @param superiors the object classes to set 721 */ 722 public void setSuperiors( List<ObjectClass> superiors ) 723 { 724 if ( locked ) 725 { 726 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 727 } 728 729 if ( !isReadOnly ) 730 { 731 this.superiors = superiors; 732 733 // update the OIDS now 734 superiorOids.clear(); 735 736 for ( ObjectClass oc : superiors ) 737 { 738 superiorOids.add( oc.getOid() ); 739 } 740 } 741 } 742 743 744 /** 745 * Update the associated SUPERIORS ObjectClasses, even if the SchemaObject is readOnly 746 * 747 * @param superiors the object classes to set 748 */ 749 public void updateSuperiors( List<ObjectClass> superiors ) 750 { 751 this.superiors.clear(); 752 this.superiors.addAll( superiors ); 753 754 // update the OIDS now 755 superiorOids.clear(); 756 757 for ( ObjectClass oc : superiors ) 758 { 759 superiorOids.add( oc.getOid() ); 760 } 761 } 762 763 764 /** 765 * Sets the superior object class OIDs 766 * 767 * @param superiorOids the object class OIDs to set 768 */ 769 public void setSuperiorOids( List<String> superiorOids ) 770 { 771 if ( locked ) 772 { 773 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 774 } 775 776 if ( !isReadOnly ) 777 { 778 this.superiorOids = superiorOids; 779 } 780 } 781 782 783 /** 784 * Gets the type of this ObjectClass as a type safe enum. 785 * 786 * @return the ObjectClass type as an enum 787 */ 788 public ObjectClassTypeEnum getType() 789 { 790 return objectClassType; 791 } 792 793 794 /** 795 * Set the ObjectClass type, one of ABSTRACT, AUXILIARY or STRUCTURAL. 796 * 797 * @param objectClassType The ObjectClassType value 798 */ 799 public void setType( ObjectClassTypeEnum objectClassType ) 800 { 801 if ( locked ) 802 { 803 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 804 } 805 806 if ( !isReadOnly ) 807 { 808 this.objectClassType = objectClassType; 809 } 810 } 811 812 813 /** 814 * Tells if the current ObjectClass is STRUCTURAL 815 * 816 * @return <code>true</code> if the ObjectClass is STRUCTURAL 817 */ 818 public boolean isStructural() 819 { 820 return objectClassType == ObjectClassTypeEnum.STRUCTURAL; 821 } 822 823 824 /** 825 * Tells if the current ObjectClass is ABSTRACT 826 * 827 * @return <code>true</code> if the ObjectClass is ABSTRACT 828 */ 829 public boolean isAbstract() 830 { 831 return objectClassType == ObjectClassTypeEnum.ABSTRACT; 832 } 833 834 835 /** 836 * Tells if the current ObjectClass is AUXILIARY 837 * 838 * @return <code>true</code> if the ObjectClass is AUXILIARY 839 */ 840 public boolean isAuxiliary() 841 { 842 return objectClassType == ObjectClassTypeEnum.AUXILIARY; 843 } 844 845 846 /** 847 * @see Object#toString() 848 */ 849 public String toString() 850 { 851 return objectType + " " + DescriptionUtils.getDescription( this ); 852 } 853 854 855 /** 856 * Copy an ObjectClass 857 */ 858 public ObjectClass copy() 859 { 860 ObjectClass copy = new ObjectClass( oid ); 861 862 // Copy the SchemaObject common data 863 copy.copy( this ); 864 865 // Copy the ObjectClass type 866 copy.objectClassType = objectClassType; 867 868 // Copy the Superiors ObjectClasses OIDs 869 copy.superiorOids = new ArrayList<String>(); 870 871 for ( String oid : superiorOids ) 872 { 873 copy.superiorOids.add( oid ); 874 } 875 876 // Copy the Superiors ObjectClasses ( will be empty ) 877 copy.superiors = new ArrayList<ObjectClass>(); 878 879 // Copy the MAY AttributeTypes OIDs 880 copy.mayAttributeTypeOids = new ArrayList<String>(); 881 882 for ( String oid : mayAttributeTypeOids ) 883 { 884 copy.mayAttributeTypeOids.add( oid ); 885 } 886 887 // Copy the MAY AttributeTypes ( will be empty ) 888 copy.mayAttributeTypes = new ArrayList<AttributeType>(); 889 890 // Copy the MUST AttributeTypes OIDs 891 copy.mustAttributeTypeOids = new ArrayList<String>(); 892 893 for ( String oid : mustAttributeTypeOids ) 894 { 895 copy.mustAttributeTypeOids.add( oid ); 896 } 897 898 // Copy the MUST AttributeTypes ( will be empty ) 899 copy.mustAttributeTypes = new ArrayList<AttributeType>(); 900 901 return copy; 902 } 903 904 905 /** 906 * @see Object#equals(Object) 907 */ 908 public boolean equals( Object o ) 909 { 910 if ( !super.equals( o ) ) 911 { 912 return false; 913 } 914 915 if ( !( o instanceof ObjectClass ) ) 916 { 917 return false; 918 } 919 920 ObjectClass that = ( ObjectClass ) o; 921 922 // The ObjectClassType 923 if ( objectClassType != that.objectClassType ) 924 { 925 return false; 926 } 927 928 // The Superiors OIDs 929 if ( superiorOids.size() != that.superiorOids.size() ) 930 { 931 return false; 932 } 933 934 // One way 935 for ( String oid : superiorOids ) 936 { 937 if ( !that.superiorOids.contains( oid ) ) 938 { 939 return false; 940 } 941 } 942 943 // The other way 944 for ( String oid : that.superiorOids ) 945 { 946 if ( !superiorOids.contains( oid ) ) 947 { 948 return false; 949 } 950 } 951 952 // The Superiors 953 if ( superiors.size() != that.superiors.size() ) 954 { 955 return false; 956 } 957 958 // One way 959 for ( ObjectClass oid : superiors ) 960 { 961 if ( !that.superiors.contains( oid ) ) 962 { 963 return false; 964 } 965 } 966 967 // The other way 968 for ( ObjectClass oid : that.superiors ) 969 { 970 if ( !superiors.contains( oid ) ) 971 { 972 return false; 973 } 974 } 975 976 // The MAY OIDs 977 if ( mayAttributeTypeOids.size() != that.mayAttributeTypeOids.size() ) 978 { 979 return false; 980 } 981 982 // One way 983 for ( String oid : mayAttributeTypeOids ) 984 { 985 if ( !that.mayAttributeTypeOids.contains( oid ) ) 986 { 987 return false; 988 } 989 } 990 991 // The other way 992 for ( String oid : that.mayAttributeTypeOids ) 993 { 994 if ( !mayAttributeTypeOids.contains( oid ) ) 995 { 996 return false; 997 } 998 } 999 1000 // The MAY 1001 if ( mayAttributeTypes.size() != that.mayAttributeTypes.size() ) 1002 { 1003 return false; 1004 } 1005 1006 // One way 1007 for ( AttributeType oid : mayAttributeTypes ) 1008 { 1009 if ( !that.mayAttributeTypes.contains( oid ) ) 1010 { 1011 return false; 1012 } 1013 } 1014 1015 // The other way 1016 for ( AttributeType oid : that.mayAttributeTypes ) 1017 { 1018 if ( !mayAttributeTypes.contains( oid ) ) 1019 { 1020 return false; 1021 } 1022 } 1023 1024 // The MUST OIDs 1025 if ( mustAttributeTypeOids.size() != that.mustAttributeTypeOids.size() ) 1026 { 1027 return false; 1028 } 1029 1030 // One way 1031 for ( String oid : mustAttributeTypeOids ) 1032 { 1033 if ( !that.mustAttributeTypeOids.contains( oid ) ) 1034 { 1035 return false; 1036 } 1037 } 1038 1039 // The other way 1040 for ( String oid : that.mustAttributeTypeOids ) 1041 { 1042 if ( !mustAttributeTypeOids.contains( oid ) ) 1043 { 1044 return false; 1045 } 1046 } 1047 1048 // The MUST 1049 if ( mustAttributeTypes.size() != that.mustAttributeTypes.size() ) 1050 { 1051 return false; 1052 } 1053 1054 // One way 1055 for ( AttributeType oid : mustAttributeTypes ) 1056 { 1057 if ( !that.mustAttributeTypes.contains( oid ) ) 1058 { 1059 return false; 1060 } 1061 } 1062 1063 // The other way 1064 for ( AttributeType oid : that.mustAttributeTypes ) 1065 { 1066 if ( !mustAttributeTypes.contains( oid ) ) 1067 { 1068 return false; 1069 } 1070 } 1071 1072 return true; 1073 } 1074 1075 1076 /** 1077 * {@inheritDoc} 1078 */ 1079 public void clear() 1080 { 1081 // Clear the common elements 1082 super.clear(); 1083 1084 // Clear the references 1085 mayAttributeTypes.clear(); 1086 mayAttributeTypeOids.clear(); 1087 mustAttributeTypes.clear(); 1088 mustAttributeTypeOids.clear(); 1089 superiors.clear(); 1090 superiorOids.clear(); 1091 } 1092 }