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  * @see DescriptionUtils#getDescription(DitContentRule)
112  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
113  */
114 public class DitContentRule extends AbstractSchemaObject
115 {
116     /** The mandatory serialVersionUID */
117     public static final long serialVersionUID = 1L;
118 
119     /** The list of Auxiliary ObjectClass OIDs entries may belong to */
120     private List<String> auxObjectClassOids;
121 
122     /** The list of Auxiliary ObjectClass entries may belong to */
123     private List<ObjectClass> auxObjectClasses;
124 
125     /** The list of allowed AttributeType OIDs */
126     private List<String> mayAttributeTypeOids;
127 
128     /** The list of allowed AttributeTypes */
129     private List<AttributeType> mayAttributeTypes;
130 
131     /** The list of required AttributeType OIDs */
132     private List<String> mustAttributeTypeOids;
133 
134     /** The list of required AttributeTypes */
135     private List<AttributeType> mustAttributeTypes;
136 
137     /** The list of precluded AttributeType OIDs */
138     private List<String> notAttributeTypeOids;
139 
140     /** The list of precluded AttributeTypes */
141     private List<AttributeType> notAttributeTypes;
142 
143 
144     /**
145      * Creates a DitContentRule object using a unique OID.
146      * 
147      * @param oid the OID for this DitContentRule
148      */
149     public DitContentRule( String oid )
150     {
151         super( SchemaObjectType.DIT_CONTENT_RULE, oid );
152 
153         mayAttributeTypeOids = new ArrayList<String>();
154         mustAttributeTypeOids = new ArrayList<String>();
155         notAttributeTypeOids = new ArrayList<String>();
156         auxObjectClassOids = new ArrayList<String>();
157 
158         mayAttributeTypes = new ArrayList<AttributeType>();
159         mustAttributeTypes = new ArrayList<AttributeType>();
160         notAttributeTypes = new ArrayList<AttributeType>();
161         auxObjectClasses = new ArrayList<ObjectClass>();
162     }
163 
164 
165     /**
166      * @return the auxObjectClassOids
167      */
168     public List<String> getAuxObjectClassOids()
169     {
170         return auxObjectClassOids;
171     }
172 
173 
174     /**
175      * Add an Auxiliary ObjectClass Oid
176      *
177      * @param oid The ObjectClass oid
178      */
179     public void addAuxObjectClassOidOids( String oid )
180     {
181         if ( locked )
182         {
183             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
184         }
185 
186         if ( !isReadOnly )
187         {
188             auxObjectClassOids.add( oid );
189         }
190     }
191 
192 
193     /**
194      * Add an Auxiliary ObjectClass
195      *
196      * @param objectClass The ObjectClass
197      */
198     public void addAuxObjectClasses( ObjectClass objectClass )
199     {
200         if ( locked )
201         {
202             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
203         }
204 
205         if ( !isReadOnly && !auxObjectClassOids.contains( objectClass.getOid() ) )
206         {
207             auxObjectClasses.add( objectClass );
208             auxObjectClassOids.add( objectClass.getOid() );
209         }
210     }
211 
212 
213     /**
214      * @param auxObjectClassOids the auxObjectClassOids to set
215      */
216     public void setAuxObjectClassOids( List<String> auxObjectClassOids )
217     {
218         if ( locked )
219         {
220             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
221         }
222 
223         if ( !isReadOnly )
224         {
225             this.auxObjectClassOids = auxObjectClassOids;
226         }
227     }
228 
229 
230     /**
231      * @param auxObjectClasses the auxObjectClasses to set
232      */
233     public void setAuxObjectClasses( List<ObjectClass> auxObjectClasses )
234     {
235         if ( locked )
236         {
237             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
238         }
239 
240         if ( !isReadOnly )
241         {
242             this.auxObjectClasses = auxObjectClasses;
243 
244             // update the OIDS now
245             auxObjectClassOids.clear();
246 
247             for ( ObjectClass oc : auxObjectClasses )
248             {
249                 auxObjectClassOids.add( oc.getOid() );
250             }
251         }
252     }
253 
254 
255     /**
256      * @return the auxObjectClasses
257      */
258     public List<ObjectClass> getAuxObjectClasses()
259     {
260         return auxObjectClasses;
261     }
262 
263 
264     /**
265      * @return the mayAttributeTypeOids
266      */
267     public List<String> getMayAttributeTypeOids()
268     {
269         return mayAttributeTypeOids;
270     }
271 
272 
273     /**
274      * Add an allowed AttributeType
275      *
276      * @param oid The attributeType oid
277      */
278     public void addMayAttributeTypeOids( String oid )
279     {
280         if ( locked )
281         {
282             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
283         }
284 
285         if ( !isReadOnly )
286         {
287             mayAttributeTypeOids.add( oid );
288         }
289     }
290 
291 
292     /**
293      * Add an allowed AttributeType
294      *
295      * @param attributeType The attributeType
296      */
297     public void addMayAttributeTypes( AttributeType attributeType )
298     {
299         if ( locked )
300         {
301             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
302         }
303 
304         if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
305         {
306             mayAttributeTypes.add( attributeType );
307             mayAttributeTypeOids.add( attributeType.getOid() );
308         }
309     }
310 
311 
312     /**
313      * @param mayAttributeTypeOids the mayAttributeTypeOids to set
314      */
315     public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids )
316     {
317         if ( locked )
318         {
319             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
320         }
321 
322         if ( !isReadOnly )
323         {
324             this.mayAttributeTypeOids = mayAttributeTypeOids;
325         }
326     }
327 
328 
329     /**
330      * Sets the list of allowed AttributeTypes
331      *
332      * @param mayAttributeTypes the list of allowed AttributeTypes
333      */
334     public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes )
335     {
336         if ( locked )
337         {
338             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
339         }
340 
341         if ( !isReadOnly )
342         {
343             this.mayAttributeTypes = mayAttributeTypes;
344 
345             // update the OIDS now
346             mayAttributeTypeOids.clear();
347 
348             for ( AttributeType may : mayAttributeTypes )
349             {
350                 mayAttributeTypeOids.add( may.getOid() );
351             }
352         }
353     }
354 
355 
356     /**
357      * @return the mayAttributeTypes
358      */
359     public List<AttributeType> getMayAttributeTypes()
360     {
361         return mayAttributeTypes;
362     }
363 
364 
365     /**
366      * @return the mustAttributeTypeOids
367      */
368     public List<String> getMustAttributeTypeOids()
369     {
370         return mustAttributeTypeOids;
371     }
372 
373 
374     /**
375      * Add a required AttributeType OID
376      *
377      * @param oid The attributeType OID
378      */
379     public void addMustAttributeTypeOids( String oid )
380     {
381         if ( locked )
382         {
383             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
384         }
385 
386         if ( !isReadOnly )
387         {
388             mustAttributeTypeOids.add( oid );
389         }
390     }
391 
392 
393     /**
394      * Add a required AttributeType
395      *
396      * @param attributeType The attributeType
397      */
398     public void addMustAttributeTypes( AttributeType attributeType )
399     {
400         if ( locked )
401         {
402             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
403         }
404 
405         if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
406         {
407             mustAttributeTypes.add( attributeType );
408             mustAttributeTypeOids.add( attributeType.getOid() );
409         }
410     }
411 
412 
413     /**
414      * @param mustAttributeTypeOids the mustAttributeTypeOids to set
415      */
416     public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids )
417     {
418         if ( locked )
419         {
420             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
421         }
422 
423         if ( !isReadOnly )
424         {
425             this.mustAttributeTypeOids = mustAttributeTypeOids;
426         }
427     }
428 
429 
430     /**
431      * Sets the list of required AttributeTypes
432      *
433      * @param mustAttributeTypes the list of required AttributeTypes
434      */
435     public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes )
436     {
437         if ( locked )
438         {
439             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
440         }
441 
442         if ( !isReadOnly )
443         {
444             this.mustAttributeTypes = mustAttributeTypes;
445 
446             // update the OIDS now
447             mustAttributeTypeOids.clear();
448 
449             for ( AttributeType may : mustAttributeTypes )
450             {
451                 mustAttributeTypeOids.add( may.getOid() );
452             }
453         }
454     }
455 
456 
457     /**
458      * @return the mustAttributeTypes
459      */
460     public List<AttributeType> getMustAttributeTypes()
461     {
462         return mustAttributeTypes;
463     }
464 
465 
466     /**
467      * @return the notAttributeTypeOids
468      */
469     public List<String> getNotAttributeTypeOids()
470     {
471         return notAttributeTypeOids;
472     }
473 
474 
475     /**
476      * Add a precluded AttributeType
477      *
478      * @param oid The attributeType oid
479      */
480     public void addNotAttributeTypeOids( String oid )
481     {
482         if ( locked )
483         {
484             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
485         }
486 
487         if ( !isReadOnly )
488         {
489             notAttributeTypeOids.add( oid );
490         }
491     }
492 
493 
494     /**
495      * Add a precluded AttributeType
496      *
497      * @param attributeType The attributeType
498      */
499     public void addNotAttributeTypes( AttributeType attributeType )
500     {
501         if ( locked )
502         {
503             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
504         }
505 
506         if ( !isReadOnly && !notAttributeTypeOids.contains( attributeType.getOid() ) )
507         {
508             notAttributeTypes.add( attributeType );
509             notAttributeTypeOids.add( attributeType.getOid() );
510         }
511     }
512 
513 
514     /**
515      * @param notAttributeTypeOids the notAttributeTypeOids to set
516      */
517     public void setNotAttributeTypeOids( List<String> notAttributeTypeOids )
518     {
519         if ( locked )
520         {
521             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
522         }
523 
524         if ( !isReadOnly )
525         {
526             this.notAttributeTypeOids = notAttributeTypeOids;
527         }
528     }
529 
530 
531     /**
532      * Sets the list of precluded AttributeTypes
533      *
534      * @param notAttributeTypes the list of precluded AttributeTypes
535      */
536     public void setNotAttributeTypes( List<AttributeType> notAttributeTypes )
537     {
538         if ( locked )
539         {
540             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
541         }
542 
543         if ( !isReadOnly )
544         {
545             this.notAttributeTypes = notAttributeTypes;
546 
547             // update the OIDS now
548             notAttributeTypeOids.clear();
549 
550             for ( AttributeType not : notAttributeTypes )
551             {
552                 notAttributeTypeOids.add( not.getOid() );
553             }
554         }
555     }
556 
557 
558     /**
559      * @return the notAttributeTypes
560      */
561     public List<AttributeType> getNotAttributeTypes()
562     {
563         return notAttributeTypes;
564     }
565 
566 
567     /**
568      * @see Object#toString()
569      */
570     public String toString()
571     {
572         return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
573     }
574 
575 
576     /**
577      * Copy a DitContentRule
578      */
579     public DitContentRule copy()
580     {
581         DitContentRule copy = new DitContentRule( oid );
582 
583         // Copy the SchemaObject common data
584         copy.copy( this );
585 
586         // copy the AUX ObjectClasses OIDs
587         copy.auxObjectClassOids = new ArrayList<String>();
588 
589         for ( String oid : auxObjectClassOids )
590         {
591             copy.auxObjectClassOids.add( oid );
592         }
593 
594         // copy the AUX ObjectClasses ( will be empty )
595         copy.auxObjectClasses = new ArrayList<ObjectClass>();
596 
597         // Clone the MAY AttributeTypes OIDs
598         copy.mayAttributeTypeOids = new ArrayList<String>();
599 
600         for ( String oid : mayAttributeTypeOids )
601         {
602             copy.mayAttributeTypeOids.add( oid );
603         }
604 
605         // Clone the MAY AttributeTypes ( will be empty )
606         copy.mayAttributeTypes = new ArrayList<AttributeType>();
607 
608         // Clone the MUST AttributeTypes OIDs
609         copy.mustAttributeTypeOids = new ArrayList<String>();
610 
611         for ( String oid : mustAttributeTypeOids )
612         {
613             copy.mustAttributeTypeOids.add( oid );
614         }
615 
616         // Clone the MUST AttributeTypes ( will be empty )
617         copy.mustAttributeTypes = new ArrayList<AttributeType>();
618 
619         // Clone the NOT AttributeTypes OIDs
620         copy.notAttributeTypeOids = new ArrayList<String>();
621 
622         for ( String oid : notAttributeTypeOids )
623         {
624             copy.notAttributeTypeOids.add( oid );
625         }
626 
627         // Clone the NOT AttributeTypes ( will be empty )
628         copy.notAttributeTypes = new ArrayList<AttributeType>();
629 
630         return copy;
631     }
632 
633 
634     /**
635      * @see Object#equals(Object)
636      */
637     @Override
638     public boolean equals( Object o )
639     {
640         if ( !super.equals( o ) )
641         {
642             return false;
643         }
644 
645         if ( !( o instanceof DitContentRule ) )
646         {
647             return false;
648         }
649 
650         @SuppressWarnings("unused")
651         DitContentRule that = ( DitContentRule ) o;
652 
653         // TODO : complete the check
654         return true;
655     }
656 
657 
658     /**
659      * {@inheritDoc}
660      */
661     public void clear()
662     {
663         // Clear the common elements
664         super.clear();
665 
666         // Clear the references
667         auxObjectClasses.clear();
668         auxObjectClassOids.clear();
669         mayAttributeTypes.clear();
670         mayAttributeTypeOids.clear();
671         mustAttributeTypes.clear();
672         mustAttributeTypeOids.clear();
673         notAttributeTypes.clear();
674         notAttributeTypeOids.clear();
675     }
676 }