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   *    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 &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_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 }