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 "rule governing the content of entries of a
42 * particular structural object class" [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 "NAME" SP qdescrs ] ; short names (descriptors)
83 * [ SP "DESC" SP qdstring ] ; description
84 * [ SP "OBSOLETE" ] ; not active
85 * [ SP "AUX" SP oids ] ; auxiliary object classes
86 * [ SP "MUST" SP oids ] ; attribute types
87 * [ SP "MAY" SP oids ] ; attribute types
88 * [ SP "NOT" 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 }