View Javadoc
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 &quot;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&quot; [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 &quot;NAME&quot; SP qdescrs ]  ; short names (descriptors)
64   *         [ SP &quot;DESC&quot; SP qdstring ] ;String description
65   *         [ SP &quot;OBSOLETE&quot; ]         ; not active
66   *         SP &quot;OC&quot; SP oid            ; structural object class
67   *         SP &quot;MUST&quot; SP oids         ; attribute types
68   *         [ SP &quot;MAY&quot; 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 (&quot;MUST&quot;) and allowed (&quot;MAY&quot;) 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 }