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