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.List;
25  
26  import org.apache.directory.api.i18n.I18n;
27  
28  
29  /**
30   * A ditContentRule specification. ditContentRules identify the content of
31   * entries of a particular structural objectClass. They specify the AUXILIARY
32   * objectClasses and additional attribute types permitted to appear, or excluded
33   * from appearing in entries of the indicated STRUCTURAL objectClass.
34   * <p>
35   * According to ldapbis [MODELS]:
36   * </p>
37   * 
38   * <pre>
39   *  4.1.6. DIT Content Rules
40   * 
41   *    A DIT content rule is a &quot;rule governing the content of entries of a
42   *    particular structural object class&quot; [X.501].
43   * 
44   *    For DIT entries of a particular structural object class, a DIT content
45   *    rule specifies which auxiliary object classes the entries are allowed
46   *    to belong to and which additional attributes (by type) are required,
47   *    allowed or not allowed to appear in the entries.
48   * 
49   *    The list of precluded attributes cannot include any attribute listed
50   *    as mandatory in rule, the structural object class, or any of the
51   *    allowed auxiliary object classes.
52   * 
53   *    Each content rule is identified by the object identifier, as well as
54   *    any short names (descriptors), of the structural object class it
55   *    applies to.
56   * 
57   *    An entry may only belong to auxiliary object classes listed in the
58   *    governing content rule.
59   * 
60   *    An entry must contain all attributes required by the object classes
61   *    the entry belongs to as well as all attributed required by the
62   *    governing content rule.
63   * 
64   *    An entry may contain any non-precluded attributes allowed by the
65   *    object classes the entry belongs to as well as all attributes allowed
66   *    by the governing content rule.
67   * 
68   *    An entry cannot include any attribute precluded by the governing
69   *    content rule.
70   * 
71   *    An entry is governed by (if present and active in the subschema) the
72   *    DIT content rule which applies to the structural object class of the
73   *    entry (see Section 2.4.2).  If no active rule is present for the
74   *    entry's structural object class, the entry's content is governed by
75   *    the structural object class (and possibly other aspects of user and
76   *    system schema).
77   * 
78   *    DIT content rule descriptions are written according to the ABNF:
79   * 
80   *      DITContentRuleDescription = LPAREN WSP
81   *          numericoid                ; object identifier
82   *          [ SP &quot;NAME&quot; SP qdescrs ]  ; short names (descriptors)
83   *          [ SP &quot;DESC&quot; SP qdstring ] ; description
84   *          [ SP &quot;OBSOLETE&quot; ]         ; not active
85   *          [ SP &quot;AUX&quot; SP oids ]      ; auxiliary object classes
86   *          [ SP &quot;MUST&quot; SP oids ]     ; attribute types
87   *          [ SP &quot;MAY&quot; SP oids ]      ; attribute types
88   *          [ SP &quot;NOT&quot; SP oids ]      ; attribute types
89   *          extensions WSP RPAREN     ; extensions
90   * 
91   *    where:
92   * 
93   *      [numericoid] is the object identifier of the structural object class
94   *          associated with this DIT content rule;
95   *      NAME [qdescrs] are short names (descriptors) identifying this DIT
96   *          content rule;
97   *      DESC [qdstring] is a short descriptive string;
98   *      OBSOLETE indicates this DIT content rule use is not active;
99   *      AUX specifies a list of auxiliary object classes which entries
100  *          subject to this DIT content rule may belong to;
101  *      MUST, MAY, and NOT specify lists of attribute types which are
102  *          required, allowed, or precluded, respectively, from appearing in
103  *          entries subject to this DIT content rule; and
104  *      [extensions] describe extensions.
105  * </pre>
106  * 
107  * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC 2252 Section 5.4.3</a>
108  * @see <a
109  *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
110  *      [MODELS]</a>
111  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
112  */
113 public class DitContentRule extends AbstractSchemaObject
114 {
115     /** The mandatory serialVersionUID */
116     public static final long serialVersionUID = 1L;
117 
118     /** The list of Auxiliary ObjectClass OIDs entries may belong to */
119     private List<String> auxObjectClassOids;
120 
121     /** The list of Auxiliary ObjectClass entries may belong to */
122     private List<ObjectClass> auxObjectClasses;
123 
124     /** The list of allowed AttributeType OIDs */
125     private List<String> mayAttributeTypeOids;
126 
127     /** The list of allowed AttributeTypes */
128     private List<AttributeType> mayAttributeTypes;
129 
130     /** The list of required AttributeType OIDs */
131     private List<String> mustAttributeTypeOids;
132 
133     /** The list of required AttributeTypes */
134     private List<AttributeType> mustAttributeTypes;
135 
136     /** The list of precluded AttributeType OIDs */
137     private List<String> notAttributeTypeOids;
138 
139     /** The list of precluded AttributeTypes */
140     private List<AttributeType> notAttributeTypes;
141 
142 
143     /**
144      * Creates a DitContentRule object using a unique OID.
145      * 
146      * @param oid the OID for this DitContentRule
147      */
148     public DitContentRule( String oid )
149     {
150         super( SchemaObjectType.DIT_CONTENT_RULE, oid );
151 
152         mayAttributeTypeOids = new ArrayList<>();
153         mustAttributeTypeOids = new ArrayList<>();
154         notAttributeTypeOids = new ArrayList<>();
155         auxObjectClassOids = new ArrayList<>();
156 
157         mayAttributeTypes = new ArrayList<>();
158         mustAttributeTypes = new ArrayList<>();
159         notAttributeTypes = new ArrayList<>();
160         auxObjectClasses = new ArrayList<>();
161     }
162 
163 
164     /**
165      * @return the auxObjectClassOids
166      */
167     public List<String> getAuxObjectClassOids()
168     {
169         return auxObjectClassOids;
170     }
171 
172 
173     /**
174      * Add an Auxiliary ObjectClass Oid
175      *
176      * @param oid The ObjectClass oid
177      */
178     public void addAuxObjectClassOidOids( String oid )
179     {
180         if ( locked )
181         {
182             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
183         }
184 
185         if ( !isReadOnly )
186         {
187             auxObjectClassOids.add( oid );
188         }
189     }
190 
191 
192     /**
193      * Add an Auxiliary ObjectClass
194      *
195      * @param objectClass The ObjectClass
196      */
197     public void addAuxObjectClasses( ObjectClass objectClass )
198     {
199         if ( locked )
200         {
201             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
202         }
203 
204         if ( !isReadOnly && !auxObjectClassOids.contains( objectClass.getOid() ) )
205         {
206             auxObjectClasses.add( objectClass );
207             auxObjectClassOids.add( objectClass.getOid() );
208         }
209     }
210 
211 
212     /**
213      * @param auxObjectClassOids the auxObjectClassOids to set
214      */
215     public void setAuxObjectClassOids( List<String> auxObjectClassOids )
216     {
217         if ( locked )
218         {
219             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
220         }
221 
222         if ( !isReadOnly )
223         {
224             this.auxObjectClassOids = auxObjectClassOids;
225         }
226     }
227 
228 
229     /**
230      * @param auxObjectClasses the auxObjectClasses to set
231      */
232     public void setAuxObjectClasses( List<ObjectClass> auxObjectClasses )
233     {
234         if ( locked )
235         {
236             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
237         }
238 
239         if ( !isReadOnly )
240         {
241             this.auxObjectClasses = auxObjectClasses;
242 
243             // update the OIDS now
244             auxObjectClassOids.clear();
245 
246             for ( ObjectClass oc : auxObjectClasses )
247             {
248                 auxObjectClassOids.add( oc.getOid() );
249             }
250         }
251     }
252 
253 
254     /**
255      * @return the auxObjectClasses
256      */
257     public List<ObjectClass> getAuxObjectClasses()
258     {
259         return auxObjectClasses;
260     }
261 
262 
263     /**
264      * @return the mayAttributeTypeOids
265      */
266     public List<String> getMayAttributeTypeOids()
267     {
268         return mayAttributeTypeOids;
269     }
270 
271 
272     /**
273      * Add an allowed AttributeType
274      *
275      * @param oid The attributeType oid
276      */
277     public void addMayAttributeTypeOids( String oid )
278     {
279         if ( locked )
280         {
281             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
282         }
283 
284         if ( !isReadOnly )
285         {
286             mayAttributeTypeOids.add( oid );
287         }
288     }
289 
290 
291     /**
292      * Add an allowed AttributeType
293      *
294      * @param attributeType The attributeType
295      */
296     public void addMayAttributeTypes( AttributeType attributeType )
297     {
298         if ( locked )
299         {
300             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
301         }
302 
303         if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
304         {
305             mayAttributeTypes.add( attributeType );
306             mayAttributeTypeOids.add( attributeType.getOid() );
307         }
308     }
309 
310 
311     /**
312      * @param mayAttributeTypeOids the mayAttributeTypeOids to set
313      */
314     public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids )
315     {
316         if ( locked )
317         {
318             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
319         }
320 
321         if ( !isReadOnly )
322         {
323             this.mayAttributeTypeOids = mayAttributeTypeOids;
324         }
325     }
326 
327 
328     /**
329      * Sets the list of allowed AttributeTypes
330      *
331      * @param mayAttributeTypes the list of allowed AttributeTypes
332      */
333     public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes )
334     {
335         if ( locked )
336         {
337             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
338         }
339 
340         if ( !isReadOnly )
341         {
342             this.mayAttributeTypes = mayAttributeTypes;
343 
344             // update the OIDS now
345             mayAttributeTypeOids.clear();
346 
347             for ( AttributeType may : mayAttributeTypes )
348             {
349                 mayAttributeTypeOids.add( may.getOid() );
350             }
351         }
352     }
353 
354 
355     /**
356      * @return the mayAttributeTypes
357      */
358     public List<AttributeType> getMayAttributeTypes()
359     {
360         return mayAttributeTypes;
361     }
362 
363 
364     /**
365      * @return the mustAttributeTypeOids
366      */
367     public List<String> getMustAttributeTypeOids()
368     {
369         return mustAttributeTypeOids;
370     }
371 
372 
373     /**
374      * Add a required AttributeType OID
375      *
376      * @param oid The attributeType OID
377      */
378     public void addMustAttributeTypeOids( String oid )
379     {
380         if ( locked )
381         {
382             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
383         }
384 
385         if ( !isReadOnly )
386         {
387             mustAttributeTypeOids.add( oid );
388         }
389     }
390 
391 
392     /**
393      * Add a required AttributeType
394      *
395      * @param attributeType The attributeType
396      */
397     public void addMustAttributeTypes( AttributeType attributeType )
398     {
399         if ( locked )
400         {
401             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
402         }
403 
404         if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
405         {
406             mustAttributeTypes.add( attributeType );
407             mustAttributeTypeOids.add( attributeType.getOid() );
408         }
409     }
410 
411 
412     /**
413      * @param mustAttributeTypeOids the mustAttributeTypeOids to set
414      */
415     public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids )
416     {
417         if ( locked )
418         {
419             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
420         }
421 
422         if ( !isReadOnly )
423         {
424             this.mustAttributeTypeOids = mustAttributeTypeOids;
425         }
426     }
427 
428 
429     /**
430      * Sets the list of required AttributeTypes
431      *
432      * @param mustAttributeTypes the list of required AttributeTypes
433      */
434     public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes )
435     {
436         if ( locked )
437         {
438             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
439         }
440 
441         if ( !isReadOnly )
442         {
443             this.mustAttributeTypes = mustAttributeTypes;
444 
445             // update the OIDS now
446             mustAttributeTypeOids.clear();
447 
448             for ( AttributeType may : mustAttributeTypes )
449             {
450                 mustAttributeTypeOids.add( may.getOid() );
451             }
452         }
453     }
454 
455 
456     /**
457      * @return the mustAttributeTypes
458      */
459     public List<AttributeType> getMustAttributeTypes()
460     {
461         return mustAttributeTypes;
462     }
463 
464 
465     /**
466      * @return the notAttributeTypeOids
467      */
468     public List<String> getNotAttributeTypeOids()
469     {
470         return notAttributeTypeOids;
471     }
472 
473 
474     /**
475      * Add a precluded AttributeType
476      *
477      * @param oid The attributeType oid
478      */
479     public void addNotAttributeTypeOids( String oid )
480     {
481         if ( locked )
482         {
483             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
484         }
485 
486         if ( !isReadOnly )
487         {
488             notAttributeTypeOids.add( oid );
489         }
490     }
491 
492 
493     /**
494      * Add a precluded AttributeType
495      *
496      * @param attributeType The attributeType
497      */
498     public void addNotAttributeTypes( AttributeType attributeType )
499     {
500         if ( locked )
501         {
502             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
503         }
504 
505         if ( !isReadOnly && !notAttributeTypeOids.contains( attributeType.getOid() ) )
506         {
507             notAttributeTypes.add( attributeType );
508             notAttributeTypeOids.add( attributeType.getOid() );
509         }
510     }
511 
512 
513     /**
514      * @param notAttributeTypeOids the notAttributeTypeOids to set
515      */
516     public void setNotAttributeTypeOids( List<String> notAttributeTypeOids )
517     {
518         if ( locked )
519         {
520             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
521         }
522 
523         if ( !isReadOnly )
524         {
525             this.notAttributeTypeOids = notAttributeTypeOids;
526         }
527     }
528 
529 
530     /**
531      * Sets the list of precluded AttributeTypes
532      *
533      * @param notAttributeTypes the list of precluded AttributeTypes
534      */
535     public void setNotAttributeTypes( List<AttributeType> notAttributeTypes )
536     {
537         if ( locked )
538         {
539             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
540         }
541 
542         if ( !isReadOnly )
543         {
544             this.notAttributeTypes = notAttributeTypes;
545 
546             // update the OIDS now
547             notAttributeTypeOids.clear();
548 
549             for ( AttributeType not : notAttributeTypes )
550             {
551                 notAttributeTypeOids.add( not.getOid() );
552             }
553         }
554     }
555 
556 
557     /**
558      * @return the notAttributeTypes
559      */
560     public List<AttributeType> getNotAttributeTypes()
561     {
562         return notAttributeTypes;
563     }
564 
565 
566     /**
567      * @see Object#toString()
568      */
569     @Override
570     public String toString()
571     {
572         return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
573     }
574 
575 
576     /**
577      * Copy a DitContentRule
578      */
579     @Override
580     public DitContentRule copy()
581     {
582         DitContentRule copy = new DitContentRule( oid );
583 
584         // Copy the SchemaObject common data
585         copy.copy( this );
586 
587         // copy the AUX ObjectClasses OIDs
588         copy.auxObjectClassOids = new ArrayList<>();
589 
590         for ( String oid : auxObjectClassOids )
591         {
592             copy.auxObjectClassOids.add( oid );
593         }
594 
595         // copy the AUX ObjectClasses ( will be empty )
596         copy.auxObjectClasses = new ArrayList<>();
597 
598         // Clone the MAY AttributeTypes OIDs
599         copy.mayAttributeTypeOids = new ArrayList<>();
600 
601         for ( String oid : mayAttributeTypeOids )
602         {
603             copy.mayAttributeTypeOids.add( oid );
604         }
605 
606         // Clone the MAY AttributeTypes ( will be empty )
607         copy.mayAttributeTypes = new ArrayList<>();
608 
609         // Clone the MUST AttributeTypes OIDs
610         copy.mustAttributeTypeOids = new ArrayList<>();
611 
612         for ( String oid : mustAttributeTypeOids )
613         {
614             copy.mustAttributeTypeOids.add( oid );
615         }
616 
617         // Clone the MUST AttributeTypes ( will be empty )
618         copy.mustAttributeTypes = new ArrayList<>();
619 
620         // Clone the NOT AttributeTypes OIDs
621         copy.notAttributeTypeOids = new ArrayList<>();
622 
623         for ( String oid : notAttributeTypeOids )
624         {
625             copy.notAttributeTypeOids.add( oid );
626         }
627 
628         // Clone the NOT AttributeTypes ( will be empty )
629         copy.notAttributeTypes = new ArrayList<>();
630 
631         return copy;
632     }
633 
634 
635     /**
636      * @see Object#equals(Object)
637      */
638     @Override
639     public boolean equals( Object o )
640     {
641         if ( !super.equals( o ) )
642         {
643             return false;
644         }
645 
646         if ( !( o instanceof DitContentRule ) )
647         {
648             return false;
649         }
650 
651         @SuppressWarnings("unused")
652         DitContentRule that = ( DitContentRule ) o;
653 
654         // TODO : complete the check
655         return true;
656     }
657 
658 
659     /**
660      * {@inheritDoc}
661      */
662     @Override
663     public void clear()
664     {
665         // Clear the common elements
666         super.clear();
667 
668         // Clear the references
669         auxObjectClasses.clear();
670         auxObjectClassOids.clear();
671         mayAttributeTypes.clear();
672         mayAttributeTypeOids.clear();
673         mustAttributeTypes.clear();
674         mustAttributeTypeOids.clear();
675         notAttributeTypes.clear();
676         notAttributeTypeOids.clear();
677     }
678 }