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 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 092 */ 093public class NameForm extends AbstractSchemaObject 094{ 095 /** The mandatory serialVersionUID */ 096 public static final long serialVersionUID = 1L; 097 098 /** The structural object class OID this rule applies to */ 099 private String structuralObjectClassOid; 100 101 /** The structural object class this rule applies to */ 102 private ObjectClass structuralObjectClass; 103 104 /** The set of required attribute OIDs for this name form */ 105 private List<String> mustAttributeTypeOids; 106 107 /** The set of required AttributeTypes for this name form */ 108 private List<AttributeType> mustAttributeTypes; 109 110 /** The set of allowed attribute OIDs for this name form */ 111 private List<String> mayAttributeTypeOids; 112 113 /** The set of allowed AttributeTypes for this name form */ 114 private List<AttributeType> mayAttributeTypes; 115 116 117 /** 118 * Creates a new instance of MatchingRule. 119 * 120 * @param oid The MatchingRule OID 121 */ 122 public NameForm( String oid ) 123 { 124 super( SchemaObjectType.NAME_FORM, oid ); 125 126 mustAttributeTypeOids = new ArrayList<>(); 127 mayAttributeTypeOids = new ArrayList<>(); 128 129 mustAttributeTypes = new ArrayList<>(); 130 mayAttributeTypes = new ArrayList<>(); 131 } 132 133 134 /** 135 * Gets the STRUCTURAL ObjectClass this name form specifies naming 136 * attributes for. 137 * 138 * @return the ObjectClass's oid this NameForm is for 139 */ 140 public String getStructuralObjectClassOid() 141 { 142 return structuralObjectClassOid; 143 } 144 145 146 /** 147 * Gets the STRUCTURAL ObjectClass this name form specifies naming 148 * attributes for. 149 * 150 * @return the ObjectClass this NameForm is for 151 */ 152 public ObjectClass getStructuralObjectClass() 153 { 154 return structuralObjectClass; 155 } 156 157 158 /** 159 * Sets the structural object class this rule applies to 160 * 161 * @param structuralObjectClassOid the structural object class to set 162 */ 163 public void setStructuralObjectClassOid( String structuralObjectClassOid ) 164 { 165 if ( locked ) 166 { 167 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 168 } 169 170 if ( !isReadOnly ) 171 { 172 this.structuralObjectClassOid = structuralObjectClassOid; 173 } 174 } 175 176 177 /** 178 * Sets the structural object class this rule applies to 179 * 180 * @param structuralObjectClass the structural object class to set 181 */ 182 public void setStructuralObjectClass( ObjectClass structuralObjectClass ) 183 { 184 if ( locked ) 185 { 186 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 187 } 188 189 if ( !isReadOnly ) 190 { 191 this.structuralObjectClass = structuralObjectClass; 192 this.structuralObjectClassOid = structuralObjectClass.getOid(); 193 } 194 } 195 196 197 /** 198 * Gets all the AttributeTypes OIDs of the attributes this NameForm specifies as 199 * having to be used in the given objectClass for naming: as part of the 200 * Rdn. 201 * 202 * @return the AttributeTypes OIDs of the must use attributes 203 */ 204 public List<String> getMustAttributeTypeOids() 205 { 206 return Collections.unmodifiableList( mustAttributeTypeOids ); 207 } 208 209 210 /** 211 * Gets all the AttributeTypes of the attributes this NameForm specifies as 212 * having to be used in the given objectClass for naming: as part of the 213 * Rdn. 214 * 215 * @return the AttributeTypes of the must use attributes 216 */ 217 public List<AttributeType> getMustAttributeTypes() 218 { 219 return Collections.unmodifiableList( mustAttributeTypes ); 220 } 221 222 223 /** 224 * Sets the list of required AttributeTypes OIDs 225 * 226 * @param mustAttributeTypeOids the list of required AttributeTypes OIDs 227 */ 228 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids ) 229 { 230 if ( locked ) 231 { 232 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 233 } 234 235 if ( !isReadOnly ) 236 { 237 this.mustAttributeTypeOids = mustAttributeTypeOids; 238 } 239 } 240 241 242 /** 243 * Sets the list of required AttributeTypes 244 * 245 * @param mustAttributeTypes the list of required AttributeTypes 246 */ 247 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 248 { 249 if ( locked ) 250 { 251 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 252 } 253 254 if ( !isReadOnly ) 255 { 256 this.mustAttributeTypes = mustAttributeTypes; 257 258 // update the OIDS now 259 mustAttributeTypeOids.clear(); 260 261 for ( AttributeType may : mustAttributeTypes ) 262 { 263 mustAttributeTypeOids.add( may.getOid() ); 264 } 265 } 266 } 267 268 269 /** 270 * Add a required AttributeType OID 271 * 272 * @param oid The attributeType OID 273 */ 274 public void addMustAttributeTypeOids( String oid ) 275 { 276 if ( locked ) 277 { 278 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 279 } 280 281 if ( !isReadOnly ) 282 { 283 mustAttributeTypeOids.add( oid ); 284 } 285 } 286 287 288 /** 289 * Add a required AttributeType 290 * 291 * @param attributeType The attributeType 292 */ 293 public void addMustAttributeTypes( AttributeType attributeType ) 294 { 295 if ( locked ) 296 { 297 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 298 } 299 300 if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) ) 301 { 302 mustAttributeTypes.add( attributeType ); 303 mustAttributeTypeOids.add( attributeType.getOid() ); 304 } 305 } 306 307 308 /** 309 * Gets all the AttributeTypes OIDs of the attribute this NameForm specifies as 310 * being usable without requirement in the given objectClass for naming: as 311 * part of the Rdn. 312 * 313 * @return the AttributeTypes OIDs of the may use attributes 314 */ 315 public List<String> getMayAttributeTypeOids() 316 { 317 return Collections.unmodifiableList( mayAttributeTypeOids ); 318 } 319 320 321 /** 322 * Gets all the AttributeTypes of the attribute this NameForm specifies as 323 * being useable without requirement in the given objectClass for naming: as 324 * part of the Rdn. 325 * 326 * @return the AttributeTypes of the may use attributes 327 */ 328 public List<AttributeType> getMayAttributeTypes() 329 { 330 return Collections.unmodifiableList( mayAttributeTypes ); 331 } 332 333 334 /** 335 * Sets the list of allowed AttributeTypes 336 * 337 * @param mayAttributeTypeOids the list of allowed AttributeTypes 338 */ 339 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids ) 340 { 341 if ( locked ) 342 { 343 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 344 } 345 346 if ( !isReadOnly ) 347 { 348 this.mayAttributeTypeOids = mayAttributeTypeOids; 349 } 350 } 351 352 353 /** 354 * Sets the list of allowed AttributeTypes 355 * 356 * @param mayAttributeTypes the list of allowed AttributeTypes 357 */ 358 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 359 { 360 if ( locked ) 361 { 362 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 363 } 364 365 if ( !isReadOnly ) 366 { 367 this.mayAttributeTypes = mayAttributeTypes; 368 369 // update the OIDS now 370 mayAttributeTypeOids.clear(); 371 372 for ( AttributeType may : mayAttributeTypes ) 373 { 374 mayAttributeTypeOids.add( may.getOid() ); 375 } 376 } 377 } 378 379 380 /** 381 * Add an allowed AttributeType 382 * 383 * @param oid The attributeType oid 384 */ 385 public void addMayAttributeTypeOids( String oid ) 386 { 387 if ( locked ) 388 { 389 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 390 } 391 392 if ( !isReadOnly ) 393 { 394 mayAttributeTypeOids.add( oid ); 395 } 396 } 397 398 399 /** 400 * Add an allowed AttributeType 401 * 402 * @param attributeType The attributeType 403 */ 404 public void addMayAttributeTypes( AttributeType attributeType ) 405 { 406 if ( locked ) 407 { 408 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 409 } 410 411 if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) ) 412 { 413 mayAttributeTypes.add( attributeType ); 414 mayAttributeTypeOids.add( attributeType.getOid() ); 415 } 416 } 417 418 419 /** 420 * @see Object#toString() 421 */ 422 @Override 423 public String toString() 424 { 425 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 426 } 427 428 429 /** 430 * Copy a NameForm 431 */ 432 @Override 433 public NameForm copy() 434 { 435 NameForm copy = new NameForm( oid ); 436 437 // Copy the SchemaObject common data 438 copy.copy( this ); 439 440 // Copy the MAY AttributeTypes OIDs 441 copy.mayAttributeTypeOids = new ArrayList<>(); 442 443 for ( String oid : mayAttributeTypeOids ) 444 { 445 copy.mayAttributeTypeOids.add( oid ); 446 } 447 448 // Copy the MAY AttributeTypes (will be empty) 449 copy.mayAttributeTypes = new ArrayList<>(); 450 451 // Copy the MUST AttributeTypes OIDs 452 copy.mustAttributeTypeOids = new ArrayList<>(); 453 454 for ( String oid : mustAttributeTypeOids ) 455 { 456 copy.mustAttributeTypeOids.add( oid ); 457 } 458 459 // Copy the MUST AttributeTypes ( will be empty ) 460 copy.mustAttributeTypes = new ArrayList<>(); 461 462 // Copy the Structural ObjectClass OID 463 copy.structuralObjectClassOid = structuralObjectClassOid; 464 465 // All the references to other Registries object are set to null. 466 copy.structuralObjectClass = null; 467 468 return copy; 469 } 470 471 472 /** 473 * @see Object#equals(Object) 474 */ 475 @Override 476 public boolean equals( Object o ) 477 { 478 if ( !super.equals( o ) ) 479 { 480 return false; 481 } 482 483 if ( !( o instanceof NameForm ) ) 484 { 485 return false; 486 } 487 488 @SuppressWarnings("unused") 489 NameForm that = ( NameForm ) o; 490 491 // TODO : complete the checks 492 return true; 493 } 494 495 496 /** 497 * {@inheritDoc} 498 */ 499 @Override 500 public void clear() 501 { 502 // Clear the common elements 503 super.clear(); 504 505 // Clear the references 506 mayAttributeTypes.clear(); 507 mayAttributeTypeOids.clear(); 508 mustAttributeTypes.clear(); 509 mustAttributeTypeOids.clear(); 510 structuralObjectClass = null; 511 } 512}