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 026 027/** 028 * An objectClass definition. 029 * <p> 030 * According to ldapbis [MODELS]: 031 * </p> 032 * 033 * <pre> 034 * Object Class definitions are written according to the ABNF: 035 * 036 * ObjectClassDescription = LPAREN WSP 037 * numericoid ; object identifier 038 * [ SP "NAME" SP qdescrs ] ; short names (descriptors) 039 * [ SP "DESC" SP qdstring ] ; description 040 * [ SP "OBSOLETE" ] ; not active 041 * [ SP "SUP" SP oids ] ; superior object classes 042 * [ SP kind ] ; kind of class 043 * [ SP "MUST" SP oids ] ; attribute types 044 * [ SP "MAY" SP oids ] ; attribute types 045 * extensions WSP RPAREN 046 * 047 * kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" 048 * 049 * where: 050 * [numericoid] is object identifier assigned to this object class; 051 * NAME [qdescrs] are short names (descriptors) identifying this object 052 * class; 053 * DESC [qdstring] is a short descriptive string; 054 * OBSOLETE indicates this object class is not active; 055 * SUP [oids] specifies the direct superclasses of this object class; 056 * the kind of object class is indicated by one of ABSTRACT, 057 * STRUCTURAL, or AUXILIARY, default is STRUCTURAL; 058 * MUST and MAY specify the sets of required and allowed attribute 059 * types, respectively; and 060 * [extensions] describe extensions. 061 * </pre> 062 * 063 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC2252 Section 4.4</a> 064 * @see <a 065 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis 066 * [MODELS]</a> 067 * @see DescriptionUtils#getDescription(ObjectClass) 068 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 069 */ 070public class ObjectClass extends AbstractSchemaObject 071{ 072 /** The mandatory serialVersionUID */ 073 public static final long serialVersionUID = 1L; 074 075 /** The ObjectClass type : ABSTRACT, AUXILIARY or STRUCTURAL */ 076 protected ObjectClassTypeEnum objectClassType = ObjectClassTypeEnum.STRUCTURAL; 077 078 /** The ObjectClass superior OIDs */ 079 protected List<String> superiorOids; 080 081 /** The ObjectClass superiors */ 082 protected List<ObjectClass> superiors; 083 084 /** The list of allowed AttributeType OIDs */ 085 protected List<String> mayAttributeTypeOids; 086 087 /** The list of allowed AttributeTypes */ 088 protected List<AttributeType> mayAttributeTypes; 089 090 /** The list of required AttributeType OIDs */ 091 protected List<String> mustAttributeTypeOids; 092 093 /** The list of required AttributeTypes */ 094 protected List<AttributeType> mustAttributeTypes; 095 096 097 /** 098 * Creates a new instance of MatchingRuleUseDescription 099 * @param oid the OID for this objectClass 100 */ 101 public ObjectClass( String oid ) 102 { 103 super( SchemaObjectType.OBJECT_CLASS, oid ); 104 105 mayAttributeTypeOids = new ArrayList<String>(); 106 mustAttributeTypeOids = new ArrayList<String>(); 107 superiorOids = new ArrayList<String>(); 108 109 mayAttributeTypes = new ArrayList<AttributeType>(); 110 mustAttributeTypes = new ArrayList<AttributeType>(); 111 superiors = new ArrayList<ObjectClass>(); 112 objectClassType = ObjectClassTypeEnum.STRUCTURAL; 113 } 114 115 116 /** 117 * @return the mayAttributeTypeOids 118 */ 119 public List<String> getMayAttributeTypeOids() 120 { 121 return mayAttributeTypeOids; 122 } 123 124 125 /** 126 * @return the mayAttributeTypes 127 */ 128 public List<AttributeType> getMayAttributeTypes() 129 { 130 return mayAttributeTypes; 131 } 132 133 134 /** 135 * @return the mustAttributeTypeOids 136 */ 137 public List<String> getMustAttributeTypeOids() 138 { 139 return mustAttributeTypeOids; 140 } 141 142 143 /** 144 * @return the mustAttributeTypes 145 */ 146 public List<AttributeType> getMustAttributeTypes() 147 { 148 return mustAttributeTypes; 149 } 150 151 152 /** 153 * Gets the superclasses of this ObjectClass. 154 * 155 * @return the superclasses 156 */ 157 public List<ObjectClass> getSuperiors() 158 { 159 return superiors; 160 } 161 162 163 /** 164 * Gets the superclasses OIDsof this ObjectClass. 165 * 166 * @return the superclasses OIDs 167 */ 168 public List<String> getSuperiorOids() 169 { 170 return superiorOids; 171 } 172 173 174 /** 175 * Gets the type of this ObjectClass as a type safe enum. 176 * 177 * @return the ObjectClass type as an enum 178 */ 179 public ObjectClassTypeEnum getType() 180 { 181 return objectClassType; 182 } 183 184 185 /** 186 * Tells if the current ObjectClass is STRUCTURAL 187 * 188 * @return <code>true</code> if the ObjectClass is STRUCTURAL 189 */ 190 public boolean isStructural() 191 { 192 return objectClassType == ObjectClassTypeEnum.STRUCTURAL; 193 } 194 195 196 /** 197 * Tells if the current ObjectClass is ABSTRACT 198 * 199 * @return <code>true</code> if the ObjectClass is ABSTRACT 200 */ 201 public boolean isAbstract() 202 { 203 return objectClassType == ObjectClassTypeEnum.ABSTRACT; 204 } 205 206 207 /** 208 * Tells if the current ObjectClass is AUXILIARY 209 * 210 * @return <code>true</code> if the ObjectClass is AUXILIARY 211 */ 212 public boolean isAuxiliary() 213 { 214 return objectClassType == ObjectClassTypeEnum.AUXILIARY; 215 } 216 217 218 /** 219 * {@inheritDoc} 220 */ 221 public String toString() 222 { 223 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 224 } 225 226 227 /** 228 * Copy an ObjectClass 229 */ 230 public ObjectClass copy() 231 { 232 ObjectClass copy = new ObjectClass( oid ); 233 234 // Copy the SchemaObject common data 235 copy.copy( this ); 236 237 // Copy the ObjectClass type 238 copy.objectClassType = objectClassType; 239 240 // Copy the Superiors ObjectClasses OIDs 241 copy.superiorOids = new ArrayList<String>(); 242 243 for ( String oid : superiorOids ) 244 { 245 copy.superiorOids.add( oid ); 246 } 247 248 // Copy the Superiors ObjectClasses ( will be empty ) 249 copy.superiors = new ArrayList<ObjectClass>(); 250 251 // Copy the MAY AttributeTypes OIDs 252 copy.mayAttributeTypeOids = new ArrayList<String>(); 253 254 for ( String oid : mayAttributeTypeOids ) 255 { 256 copy.mayAttributeTypeOids.add( oid ); 257 } 258 259 // Copy the MAY AttributeTypes ( will be empty ) 260 copy.mayAttributeTypes = new ArrayList<AttributeType>(); 261 262 // Copy the MUST AttributeTypes OIDs 263 copy.mustAttributeTypeOids = new ArrayList<String>(); 264 265 for ( String oid : mustAttributeTypeOids ) 266 { 267 copy.mustAttributeTypeOids.add( oid ); 268 } 269 270 // Copy the MUST AttributeTypes ( will be empty ) 271 copy.mustAttributeTypes = new ArrayList<AttributeType>(); 272 273 return copy; 274 } 275 276 277 /** 278 * @see Object#equals(Object) 279 */ 280 @Override 281 public boolean equals( Object o ) 282 { 283 if ( !super.equals( o ) ) 284 { 285 return false; 286 } 287 288 if ( !( o instanceof ObjectClass ) ) 289 { 290 return false; 291 } 292 293 ObjectClass that = ( ObjectClass ) o; 294 295 // The ObjectClassType 296 if ( objectClassType != that.objectClassType ) 297 { 298 return false; 299 } 300 301 // The Superiors OIDs 302 if ( superiorOids.size() != that.superiorOids.size() ) 303 { 304 return false; 305 } 306 307 // One way 308 for ( String oid : superiorOids ) 309 { 310 if ( !that.superiorOids.contains( oid ) ) 311 { 312 return false; 313 } 314 } 315 316 // The other way 317 for ( String oid : that.superiorOids ) 318 { 319 if ( !superiorOids.contains( oid ) ) 320 { 321 return false; 322 } 323 } 324 325 // The Superiors 326 if ( superiors.size() != that.superiors.size() ) 327 { 328 return false; 329 } 330 331 // One way 332 for ( ObjectClass oid : superiors ) 333 { 334 if ( !that.superiors.contains( oid ) ) 335 { 336 return false; 337 } 338 } 339 340 // The other way 341 for ( ObjectClass oid : that.superiors ) 342 { 343 if ( !superiors.contains( oid ) ) 344 { 345 return false; 346 } 347 } 348 349 // The MAY OIDs 350 if ( mayAttributeTypeOids.size() != that.mayAttributeTypeOids.size() ) 351 { 352 return false; 353 } 354 355 // One way 356 for ( String oid : mayAttributeTypeOids ) 357 { 358 if ( !that.mayAttributeTypeOids.contains( oid ) ) 359 { 360 return false; 361 } 362 } 363 364 // The other way 365 for ( String oid : that.mayAttributeTypeOids ) 366 { 367 if ( !mayAttributeTypeOids.contains( oid ) ) 368 { 369 return false; 370 } 371 } 372 373 // The MAY 374 if ( mayAttributeTypes.size() != that.mayAttributeTypes.size() ) 375 { 376 return false; 377 } 378 379 // One way 380 for ( AttributeType oid : mayAttributeTypes ) 381 { 382 if ( !that.mayAttributeTypes.contains( oid ) ) 383 { 384 return false; 385 } 386 } 387 388 // The other way 389 for ( AttributeType oid : that.mayAttributeTypes ) 390 { 391 if ( !mayAttributeTypes.contains( oid ) ) 392 { 393 return false; 394 } 395 } 396 397 // The MUST OIDs 398 if ( mustAttributeTypeOids.size() != that.mustAttributeTypeOids.size() ) 399 { 400 return false; 401 } 402 403 // One way 404 for ( String oid : mustAttributeTypeOids ) 405 { 406 if ( !that.mustAttributeTypeOids.contains( oid ) ) 407 { 408 return false; 409 } 410 } 411 412 // The other way 413 for ( String oid : that.mustAttributeTypeOids ) 414 { 415 if ( !mustAttributeTypeOids.contains( oid ) ) 416 { 417 return false; 418 } 419 } 420 421 // The MUST 422 if ( mustAttributeTypes.size() != that.mustAttributeTypes.size() ) 423 { 424 return false; 425 } 426 427 // One way 428 for ( AttributeType oid : mustAttributeTypes ) 429 { 430 if ( !that.mustAttributeTypes.contains( oid ) ) 431 { 432 return false; 433 } 434 } 435 436 // The other way 437 for ( AttributeType oid : that.mustAttributeTypes ) 438 { 439 if ( !mustAttributeTypes.contains( oid ) ) 440 { 441 return false; 442 } 443 } 444 445 return true; 446 } 447}