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 * https://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_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 }