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 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
92 */
93 public class NameForm extends AbstractSchemaObject
94 {
95 /** The mandatory serialVersionUID */
96 public static final long serialVersionUID = 1L;
97
98 /** The structural object class OID this rule applies to */
99 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 }