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_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 168 } 169 170 this.structuralObjectClassOid = structuralObjectClassOid; 171 } 172 173 174 /** 175 * Sets the structural object class this rule applies to 176 * 177 * @param structuralObjectClass the structural object class to set 178 */ 179 public void setStructuralObjectClass( ObjectClass structuralObjectClass ) 180 { 181 if ( locked ) 182 { 183 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 184 } 185 186 this.structuralObjectClass = structuralObjectClass; 187 this.structuralObjectClassOid = structuralObjectClass.getOid(); 188 } 189 190 191 /** 192 * Gets all the AttributeTypes OIDs of the attributes this NameForm specifies as 193 * having to be used in the given objectClass for naming: as part of the 194 * Rdn. 195 * 196 * @return the AttributeTypes OIDs of the must use attributes 197 */ 198 public List<String> getMustAttributeTypeOids() 199 { 200 return Collections.unmodifiableList( mustAttributeTypeOids ); 201 } 202 203 204 /** 205 * Gets all the AttributeTypes of the attributes this NameForm specifies as 206 * having to be used in the given objectClass for naming: as part of the 207 * Rdn. 208 * 209 * @return the AttributeTypes of the must use attributes 210 */ 211 public List<AttributeType> getMustAttributeTypes() 212 { 213 return Collections.unmodifiableList( mustAttributeTypes ); 214 } 215 216 217 /** 218 * Sets the list of required AttributeTypes OIDs 219 * 220 * @param mustAttributeTypeOids the list of required AttributeTypes OIDs 221 */ 222 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids ) 223 { 224 if ( locked ) 225 { 226 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 227 } 228 229 this.mustAttributeTypeOids = mustAttributeTypeOids; 230 } 231 232 233 /** 234 * Sets the list of required AttributeTypes 235 * 236 * @param mustAttributeTypes the list of required AttributeTypes 237 */ 238 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes ) 239 { 240 if ( locked ) 241 { 242 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 243 } 244 245 this.mustAttributeTypes = mustAttributeTypes; 246 247 // update the OIDS now 248 mustAttributeTypeOids.clear(); 249 250 for ( AttributeType may : mustAttributeTypes ) 251 { 252 mustAttributeTypeOids.add( may.getOid() ); 253 } 254 } 255 256 257 /** 258 * Add a required AttributeType OID 259 * 260 * @param oid The attributeType OID 261 */ 262 public void addMustAttributeTypeOids( String oid ) 263 { 264 if ( locked ) 265 { 266 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 267 } 268 269 mustAttributeTypeOids.add( oid ); 270 } 271 272 273 /** 274 * Add a required AttributeType 275 * 276 * @param attributeType The attributeType 277 */ 278 public void addMustAttributeTypes( AttributeType attributeType ) 279 { 280 if ( locked ) 281 { 282 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 283 } 284 285 if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) ) 286 { 287 mustAttributeTypes.add( attributeType ); 288 mustAttributeTypeOids.add( attributeType.getOid() ); 289 } 290 } 291 292 293 /** 294 * Gets all the AttributeTypes OIDs of the attribute this NameForm specifies as 295 * being usable without requirement in the given objectClass for naming: as 296 * part of the Rdn. 297 * 298 * @return the AttributeTypes OIDs of the may use attributes 299 */ 300 public List<String> getMayAttributeTypeOids() 301 { 302 return Collections.unmodifiableList( mayAttributeTypeOids ); 303 } 304 305 306 /** 307 * Gets all the AttributeTypes of the attribute this NameForm specifies as 308 * being useable without requirement in the given objectClass for naming: as 309 * part of the Rdn. 310 * 311 * @return the AttributeTypes of the may use attributes 312 */ 313 public List<AttributeType> getMayAttributeTypes() 314 { 315 return Collections.unmodifiableList( mayAttributeTypes ); 316 } 317 318 319 /** 320 * Sets the list of allowed AttributeTypes 321 * 322 * @param mayAttributeTypeOids the list of allowed AttributeTypes 323 */ 324 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids ) 325 { 326 if ( locked ) 327 { 328 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 329 } 330 331 this.mayAttributeTypeOids = mayAttributeTypeOids; 332 } 333 334 335 /** 336 * Sets the list of allowed AttributeTypes 337 * 338 * @param mayAttributeTypes the list of allowed AttributeTypes 339 */ 340 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes ) 341 { 342 if ( locked ) 343 { 344 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 345 } 346 347 this.mayAttributeTypes = mayAttributeTypes; 348 349 // update the OIDS now 350 mayAttributeTypeOids.clear(); 351 352 for ( AttributeType may : mayAttributeTypes ) 353 { 354 mayAttributeTypeOids.add( may.getOid() ); 355 } 356 } 357 358 359 /** 360 * Add an allowed AttributeType 361 * 362 * @param oid The attributeType oid 363 */ 364 public void addMayAttributeTypeOids( String oid ) 365 { 366 if ( locked ) 367 { 368 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 369 } 370 371 mayAttributeTypeOids.add( oid ); 372 } 373 374 375 /** 376 * Add an allowed AttributeType 377 * 378 * @param attributeType The attributeType 379 */ 380 public void addMayAttributeTypes( AttributeType attributeType ) 381 { 382 if ( locked ) 383 { 384 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 385 } 386 387 if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) ) 388 { 389 mayAttributeTypes.add( attributeType ); 390 mayAttributeTypeOids.add( attributeType.getOid() ); 391 } 392 } 393 394 395 /** 396 * @see Object#toString() 397 */ 398 @Override 399 public String toString() 400 { 401 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 402 } 403 404 405 /** 406 * Copy a NameForm 407 */ 408 @Override 409 public NameForm copy() 410 { 411 NameForm copy = new NameForm( oid ); 412 413 // Copy the SchemaObject common data 414 copy.copy( this ); 415 416 // Copy the MAY AttributeTypes OIDs 417 copy.mayAttributeTypeOids = new ArrayList<>(); 418 419 for ( String oid : mayAttributeTypeOids ) 420 { 421 copy.mayAttributeTypeOids.add( oid ); 422 } 423 424 // Copy the MAY AttributeTypes (will be empty) 425 copy.mayAttributeTypes = new ArrayList<>(); 426 427 // Copy the MUST AttributeTypes OIDs 428 copy.mustAttributeTypeOids = new ArrayList<>(); 429 430 for ( String oid : mustAttributeTypeOids ) 431 { 432 copy.mustAttributeTypeOids.add( oid ); 433 } 434 435 // Copy the MUST AttributeTypes ( will be empty ) 436 copy.mustAttributeTypes = new ArrayList<>(); 437 438 // Copy the Structural ObjectClass OID 439 copy.structuralObjectClassOid = structuralObjectClassOid; 440 441 // All the references to other Registries object are set to null. 442 copy.structuralObjectClass = null; 443 444 return copy; 445 } 446 447 448 /** 449 * @see Object#equals(Object) 450 */ 451 @Override 452 public int hashCode() 453 { 454 int hash = h; 455 456 // TODO: complete this method 457 458 return hash; 459 } 460 461 /** 462 * @see Object#equals(Object) 463 */ 464 @Override 465 public boolean equals( Object o ) 466 { 467 if ( !super.equals( o ) ) 468 { 469 return false; 470 } 471 472 if ( !( o instanceof NameForm ) ) 473 { 474 return false; 475 } 476 477 @SuppressWarnings("unused") 478 NameForm that = ( NameForm ) o; 479 480 // TODO : complete the checks 481 return true; 482 } 483 484 485 /** 486 * {@inheritDoc} 487 */ 488 @Override 489 public void clear() 490 { 491 // Clear the common elements 492 super.clear(); 493 494 // Clear the references 495 mayAttributeTypes.clear(); 496 mayAttributeTypeOids.clear(); 497 mustAttributeTypes.clear(); 498 mustAttributeTypeOids.clear(); 499 structuralObjectClass = null; 500 } 501}