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.Collections; 025import java.util.List; 026 027import org.apache.directory.api.i18n.I18n; 028 029 030/** 031 * A nameForm description. NameForms define the relationship between a 032 * STRUCTURAL objectClass definition and the attributeTypes allowed to be used 033 * for the naming of an Entry of that objectClass: it defines which attributes 034 * can be used for the Rdn. 035 * <p> 036 * According to ldapbis [MODELS]: 037 * </p> 038 * 039 * <pre> 040 * 4.1.7.2. Name Forms 041 * 042 * A name form "specifies a permissible Rdn for entries of a particular 043 * structural object class. A name form identifies a named object 044 * class and one or more attribute types to be used for naming (i.e. 045 * for the Rdn). Name forms are primitive pieces of specification 046 * used in the definition of DIT structure rules" [X.501]. 047 * 048 * Each name form indicates the structural object class to be named, 049 * a set of required attribute types, and a set of allowed attributes 050 * types. A particular attribute type cannot be listed in both sets. 051 * 052 * Entries governed by the form must be named using a value from each 053 * required attribute type and zero or more values from the allowed 054 * attribute types. 055 * 056 * Each name form is identified by an object identifier (OID) and, 057 * optionally, one or more short names (descriptors). 058 * 059 * Name form descriptions are written according to the ABNF: 060 * 061 * NameFormDescription = LPAREN WSP 062 * numericoid ; object identifier 063 * [ SP "NAME" SP qdescrs ] ; short names (descriptors) 064 * [ SP "DESC" SP qdstring ] ;String description 065 * [ SP "OBSOLETE" ] ; not active 066 * SP "OC" SP oid ; structural object class 067 * SP "MUST" SP oids ; attribute types 068 * [ SP "MAY" SP oids ] ; attribute types 069 * extensions WSP RPAREN ; extensions 070 * 071 * where: 072 * 073 * [numericoid] is object identifier which identifies this name form; 074 * NAME [qdescrs] are short names (descriptors) identifying this name 075 * form; 076 * DESC [qdstring] is a short descriptive string; 077 * OBSOLETE indicates this name form is not active; 078 * OC identifies the structural object class this rule applies to, 079 * MUST and MAY specify the sets of required and allowed, respectively, 080 * naming attributes for this name form; and 081 * [extensions] describe extensions. 082 * 083 * All attribute types in the required ("MUST") and allowed ("MAY") lists 084 * shall be different. 085 * </pre> 086 * 087 * @see <a href="http://www.faqs.org/rfcs/rfc225String2.html">RFC2252 Section 6.22</a> 088 * @see <a 089 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis 090 * [MODELS]</a> 091 * @see DescriptionUtils#getDescription(NameForm) 092 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 093 */ 094public class NameForm extends AbstractSchemaObject 095{ 096 /** The mandatory serialVersionUID */ 097 public static final long serialVersionUID = 1L; 098 099 /** The structural object class OID this rule applies to */ 100 private String structuralObjectClassOid; 101 102 /** The structural object class this rule applies to */ 103 private ObjectClass structuralObjectClass; 104 105 /** The set of required attribute OIDs for this name form */ 106 private List<String> mustAttributeTypeOids; 107 108 /** The set of required AttributeTypes for this name form */ 109 private List<AttributeType> mustAttributeTypes; 110 111 /** The set of allowed attribute OIDs for this name form */ 112 private List<String> mayAttributeTypeOids; 113 114 /** The set of allowed AttributeTypes for this name form */ 115 private List<AttributeType> mayAttributeTypes; 116 117 118 /** 119 * Creates a new instance of MatchingRule. 120 * 121 * @param oid The MatchingRule OID 122 */ 123 public NameForm( String oid ) 124 { 125 super( SchemaObjectType.NAME_FORM, oid ); 126 127 mustAttributeTypeOids = new ArrayList<String>(); 128 mayAttributeTypeOids = new ArrayList<String>(); 129 130 mustAttributeTypes = new ArrayList<AttributeType>(); 131 mayAttributeTypes = new ArrayList<AttributeType>(); 132 } 133 134 135 /** 136 * Gets the STRUCTURAL ObjectClass this name form specifies naming 137 * attributes for. 138 * 139 * @return the ObjectClass's oid this NameForm is for 140 */ 141 public String getStructuralObjectClassOid() 142 { 143 return structuralObjectClassOid; 144 } 145 146 147 /** 148 * Gets the STRUCTURAL ObjectClass this name form specifies naming 149 * attributes for. 150 * 151 * @return the ObjectClass this NameForm is for 152 */ 153 public ObjectClass getStructuralObjectClass() 154 { 155 return structuralObjectClass; 156 } 157 158 159 /** 160 * Sets the structural object class this rule applies to 161 * 162 * @param structuralObjectClassOid the structural object class to set 163 */ 164 public void setStructuralObjectClassOid( String structuralObjectClassOid ) 165 { 166 if ( locked ) 167 { 168 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 169 } 170 171 if ( !isReadOnly ) 172 { 173 this.structuralObjectClassOid = structuralObjectClassOid; 174 } 175 } 176 177 178 /** 179 * Sets the structural object class this rule applies to 180 * 181 * @param structuralObjectClass the structural object class to set 182 */ 183 public void setStructuralObjectClass( ObjectClass structuralObjectClass ) 184 { 185 if ( locked ) 186 { 187 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 188 } 189 190 if ( !isReadOnly ) 191 { 192 this.structuralObjectClass = structuralObjectClass; 193 this.structuralObjectClassOid = structuralObjectClass.getOid(); 194 } 195 } 196 197 198 /** 199 * Gets all the AttributeTypes OIDs of the attributes this NameForm specifies as 200 * having to be used in the given objectClass for naming: as part of the 201 * Rdn. 202 * 203 * @return the AttributeTypes OIDs of the must use attributes 204 */ 205 public List<String> getMustAttributeTypeOids() 206 { 207 return Collections.unmodifiableList( mustAttributeTypeOids ); 208 } 209 210 211 /** 212 * Gets all the AttributeTypes of the attributes this NameForm specifies as 213 * having to be used in the given objectClass for naming: as part of the 214 * Rdn. 215 * 216 * @return the AttributeTypes of the must use attributes 217 */ 218 public List<AttributeType> getMustAttributeTypes() 219 { 220 return Collections.unmodifiableList( mustAttributeTypes ); 221 } 222 223 224 /** 225 * Sets the list of required AttributeTypes OIDs 226 * 227 * @param mustAttributeTypeOids the list of required AttributeTypes OIDs 228 */ 229 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids ) 230 { 231 if ( locked ) 232 { 233 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 234 } 235 236 if ( !isReadOnly ) 237 { 238 this.mustAttributeTypeOids = mustAttributeTypeOids; 239 } 240 } 241 242 243 /** 244 * Sets the list of required AttributeTypes 245 * 246 * @param mustAttributeTypes the list of required AttributeTypes 247 */ 248 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 249 { 250 if ( locked ) 251 { 252 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 253 } 254 255 if ( !isReadOnly ) 256 { 257 this.mustAttributeTypes = mustAttributeTypes; 258 259 // update the OIDS now 260 mustAttributeTypeOids.clear(); 261 262 for ( AttributeType may : mustAttributeTypes ) 263 { 264 mustAttributeTypeOids.add( may.getOid() ); 265 } 266 } 267 } 268 269 270 /** 271 * Add a required AttributeType OID 272 * 273 * @param oid The attributeType OID 274 */ 275 public void addMustAttributeTypeOids( String oid ) 276 { 277 if ( locked ) 278 { 279 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 280 } 281 282 if ( !isReadOnly ) 283 { 284 mustAttributeTypeOids.add( oid ); 285 } 286 } 287 288 289 /** 290 * Add a required AttributeType 291 * 292 * @param attributeType The attributeType 293 */ 294 public void addMustAttributeTypes( AttributeType attributeType ) 295 { 296 if ( locked ) 297 { 298 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 299 } 300 301 if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) ) 302 { 303 mustAttributeTypes.add( attributeType ); 304 mustAttributeTypeOids.add( attributeType.getOid() ); 305 } 306 } 307 308 309 /** 310 * Gets all the AttributeTypes OIDs of the attribute this NameForm specifies as 311 * being usable without requirement in the given objectClass for naming: as 312 * part of the Rdn. 313 * 314 * @return the AttributeTypes OIDs of the may use attributes 315 */ 316 public List<String> getMayAttributeTypeOids() 317 { 318 return Collections.unmodifiableList( mayAttributeTypeOids ); 319 } 320 321 322 /** 323 * Gets all the AttributeTypes of the attribute this NameForm specifies as 324 * being useable without requirement in the given objectClass for naming: as 325 * part of the Rdn. 326 * 327 * @return the AttributeTypes of the may use attributes 328 */ 329 public List<AttributeType> getMayAttributeTypes() 330 { 331 return Collections.unmodifiableList( mayAttributeTypes ); 332 } 333 334 335 /** 336 * Sets the list of allowed AttributeTypes 337 * 338 * @param mayAttributeTypeOids the list of allowed AttributeTypes 339 */ 340 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids ) 341 { 342 if ( locked ) 343 { 344 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 345 } 346 347 if ( !isReadOnly ) 348 { 349 this.mayAttributeTypeOids = mayAttributeTypeOids; 350 } 351 } 352 353 354 /** 355 * Sets the list of allowed AttributeTypes 356 * 357 * @param mayAttributeTypes the list of allowed AttributeTypes 358 */ 359 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 360 { 361 if ( locked ) 362 { 363 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 364 } 365 366 if ( !isReadOnly ) 367 { 368 this.mayAttributeTypes = mayAttributeTypes; 369 370 // update the OIDS now 371 mayAttributeTypeOids.clear(); 372 373 for ( AttributeType may : mayAttributeTypes ) 374 { 375 mayAttributeTypeOids.add( may.getOid() ); 376 } 377 } 378 } 379 380 381 /** 382 * Add an allowed AttributeType 383 * 384 * @param oid The attributeType oid 385 */ 386 public void addMayAttributeTypeOids( String oid ) 387 { 388 if ( locked ) 389 { 390 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 391 } 392 393 if ( !isReadOnly ) 394 { 395 mayAttributeTypeOids.add( oid ); 396 } 397 } 398 399 400 /** 401 * Add an allowed AttributeType 402 * 403 * @param attributeType The attributeType 404 */ 405 public void addMayAttributeTypes( AttributeType attributeType ) 406 { 407 if ( locked ) 408 { 409 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 410 } 411 412 if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) ) 413 { 414 mayAttributeTypes.add( attributeType ); 415 mayAttributeTypeOids.add( attributeType.getOid() ); 416 } 417 } 418 419 420 /** 421 * @see Object#toString() 422 */ 423 public String toString() 424 { 425 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 426 } 427 428 429 /** 430 * Copy a NameForm 431 */ 432 public NameForm copy() 433 { 434 NameForm copy = new NameForm( oid ); 435 436 // Copy the SchemaObject common data 437 copy.copy( this ); 438 439 // Copy the MAY AttributeTypes OIDs 440 copy.mayAttributeTypeOids = new ArrayList<String>(); 441 442 for ( String oid : mayAttributeTypeOids ) 443 { 444 copy.mayAttributeTypeOids.add( oid ); 445 } 446 447 // Copy the MAY AttributeTypes (will be empty) 448 copy.mayAttributeTypes = new ArrayList<AttributeType>(); 449 450 // Copy the MUST AttributeTypes OIDs 451 copy.mustAttributeTypeOids = new ArrayList<String>(); 452 453 for ( String oid : mustAttributeTypeOids ) 454 { 455 copy.mustAttributeTypeOids.add( oid ); 456 } 457 458 // Copy the MUST AttributeTypes ( will be empty ) 459 copy.mustAttributeTypes = new ArrayList<AttributeType>(); 460 461 // Copy the Structural ObjectClass OID 462 copy.structuralObjectClassOid = structuralObjectClassOid; 463 464 // All the references to other Registries object are set to null. 465 copy.structuralObjectClass = null; 466 467 return copy; 468 } 469 470 471 /** 472 * @see Object#equals(Object) 473 */ 474 @Override 475 public boolean equals( Object o ) 476 { 477 if ( !super.equals( o ) ) 478 { 479 return false; 480 } 481 482 if ( !( o instanceof NameForm ) ) 483 { 484 return false; 485 } 486 487 @SuppressWarnings("unused") 488 NameForm that = ( NameForm ) o; 489 490 // TODO : complete the checks 491 return true; 492 } 493 494 495 /** 496 * {@inheritDoc} 497 */ 498 public void clear() 499 { 500 // Clear the common elements 501 super.clear(); 502 503 // Clear the references 504 mayAttributeTypes.clear(); 505 mayAttributeTypeOids.clear(); 506 mustAttributeTypes.clear(); 507 mustAttributeTypeOids.clear(); 508 structuralObjectClass = null; 509 } 510}