1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.directory.api.ldap.model.schema;
21
22
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26
27 import org.apache.directory.api.i18n.I18n;
28
29
30 /**
31 * A nameForm description. NameForms define the relationship between a
32 * STRUCTURAL objectClass definition and the attributeTypes allowed to be used
33 * for the naming of an Entry of that objectClass: it defines which attributes
34 * can be used for the Rdn.
35 * <p>
36 * According to ldapbis [MODELS]:
37 * </p>
38 *
39 * <pre>
40 * 4.1.7.2. Name Forms
41 *
42 * A name form "specifies a permissible Rdn for entries of a particular
43 * structural object class. A name form identifies a named object
44 * class and one or more attribute types to be used for naming (i.e.
45 * for the Rdn). Name forms are primitive pieces of specification
46 * used in the definition of DIT structure rules" [X.501].
47 *
48 * Each name form indicates the structural object class to be named,
49 * a set of required attribute types, and a set of allowed attributes
50 * types. A particular attribute type cannot be listed in both sets.
51 *
52 * Entries governed by the form must be named using a value from each
53 * required attribute type and zero or more values from the allowed
54 * attribute types.
55 *
56 * Each name form is identified by an object identifier (OID) and,
57 * optionally, one or more short names (descriptors).
58 *
59 * Name form descriptions are written according to the ABNF:
60 *
61 * NameFormDescription = LPAREN WSP
62 * numericoid ; object identifier
63 * [ SP "NAME" SP qdescrs ] ; short names (descriptors)
64 * [ SP "DESC" SP qdstring ] ;String description
65 * [ SP "OBSOLETE" ] ; not active
66 * SP "OC" SP oid ; structural object class
67 * SP "MUST" SP oids ; attribute types
68 * [ SP "MAY" SP oids ] ; attribute types
69 * extensions WSP RPAREN ; extensions
70 *
71 * where:
72 *
73 * [numericoid] is object identifier which identifies this name form;
74 * NAME [qdescrs] are short names (descriptors) identifying this name
75 * form;
76 * DESC [qdstring] is a short descriptive string;
77 * OBSOLETE indicates this name form is not active;
78 * OC identifies the structural object class this rule applies to,
79 * MUST and MAY specify the sets of required and allowed, respectively,
80 * naming attributes for this name form; and
81 * [extensions] describe extensions.
82 *
83 * All attribute types in the required ("MUST") and allowed ("MAY") lists
84 * shall be different.
85 * </pre>
86 *
87 * @see <a href="http://www.faqs.org/rfcs/rfc225String2.html">RFC2252 Section 6.22</a>
88 * @see <a
89 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
90 * [MODELS]</a>
91 * @see DescriptionUtils#getDescription(NameForm)
92 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
93 */
94 public class NameForm extends AbstractSchemaObject
95 {
96 /** The mandatory serialVersionUID */
97 public static final long serialVersionUID = 1L;
98
99 /** 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 }