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   * @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 }