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