001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.schema;
021
022
023 import java.util.ArrayList;
024 import java.util.List;
025
026 import javax.naming.NamingException;
027
028 import org.apache.directory.shared.ldap.schema.registries.AttributeTypeRegistry;
029 import org.apache.directory.shared.ldap.schema.registries.ObjectClassRegistry;
030 import org.apache.directory.shared.ldap.schema.registries.Registries;
031
032
033 /**
034 * A ditContentRule specification. ditContentRules identify the content of
035 * entries of a particular structural objectClass. They specify the AUXILIARY
036 * objectClasses and additional attribute types permitted to appear, or excluded
037 * from appearing in entries of the indicated STRUCTURAL objectClass.
038 * <p>
039 * According to ldapbis [MODELS]:
040 * </p>
041 *
042 * <pre>
043 * 4.1.6. DIT Content Rules
044 *
045 * A DIT content rule is a "rule governing the content of entries of a
046 * particular structural object class" [X.501].
047 *
048 * For DIT entries of a particular structural object class, a DIT content
049 * rule specifies which auxiliary object classes the entries are allowed
050 * to belong to and which additional attributes (by type) are required,
051 * allowed or not allowed to appear in the entries.
052 *
053 * The list of precluded attributes cannot include any attribute listed
054 * as mandatory in rule, the structural object class, or any of the
055 * allowed auxiliary object classes.
056 *
057 * Each content rule is identified by the object identifier, as well as
058 * any short names (descriptors), of the structural object class it
059 * applies to.
060 *
061 * An entry may only belong to auxiliary object classes listed in the
062 * governing content rule.
063 *
064 * An entry must contain all attributes required by the object classes
065 * the entry belongs to as well as all attributed required by the
066 * governing content rule.
067 *
068 * An entry may contain any non-precluded attributes allowed by the
069 * object classes the entry belongs to as well as all attributes allowed
070 * by the governing content rule.
071 *
072 * An entry cannot include any attribute precluded by the governing
073 * content rule.
074 *
075 * An entry is governed by (if present and active in the subschema) the
076 * DIT content rule which applies to the structural object class of the
077 * entry (see Section 2.4.2). If no active rule is present for the
078 * entry's structural object class, the entry's content is governed by
079 * the structural object class (and possibly other aspects of user and
080 * system schema).
081 *
082 * DIT content rule descriptions are written according to the ABNF:
083 *
084 * DITContentRuleDescription = LPAREN WSP
085 * numericoid ; object identifier
086 * [ SP "NAME" SP qdescrs ] ; short names (descriptors)
087 * [ SP "DESC" SP qdstring ] ; description
088 * [ SP "OBSOLETE" ] ; not active
089 * [ SP "AUX" SP oids ] ; auxiliary object classes
090 * [ SP "MUST" SP oids ] ; attribute types
091 * [ SP "MAY" SP oids ] ; attribute types
092 * [ SP "NOT" SP oids ] ; attribute types
093 * extensions WSP RPAREN ; extensions
094 *
095 * where:
096 *
097 * [numericoid] is the object identifier of the structural object class
098 * associated with this DIT content rule;
099 * NAME [qdescrs] are short names (descriptors) identifying this DIT
100 * content rule;
101 * DESC [qdstring] is a short descriptive string;
102 * OBSOLETE indicates this DIT content rule use is not active;
103 * AUX specifies a list of auxiliary object classes which entries
104 * subject to this DIT content rule may belong to;
105 * MUST, MAY, and NOT specify lists of attribute types which are
106 * required, allowed, or precluded, respectively, from appearing in
107 * entries subject to this DIT content rule; and
108 * [extensions] describe extensions.
109 * </pre>
110 *
111 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC 2252 Section 5.4.3</a>
112 * @see <a
113 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
114 * [MODELS]</a>
115 * @see DescriptionUtils#getDescription(DITContentRule)
116 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
117 * @version $Rev: 896579 $
118 */
119 public class DITContentRule extends AbstractSchemaObject
120 {
121 /** The serialVersionUID */
122 public static final long serialVersionUID = 1L;
123
124 /** The list of Auxiliary ObjectClass OIDs entries may belong to */
125 private List<String> auxObjectClassOids;
126
127 /** The list of Auxiliary ObjectClass entries may belong to */
128 private List<ObjectClass> auxObjectClasses;
129
130 /** The list of allowed AttributeType OIDs */
131 private List<String> mayAttributeTypeOids;
132
133 /** The list of allowed AttributeTypes */
134 private List<AttributeType> mayAttributeTypes;
135
136 /** The list of required AttributeType OIDs */
137 private List<String> mustAttributeTypeOids;
138
139 /** The list of required AttributeTypes */
140 private List<AttributeType> mustAttributeTypes;
141
142 /** The list of precluded AttributeType OIDs */
143 private List<String> notAttributeTypeOids;
144
145 /** The list of precluded AttributeTypes */
146 private List<AttributeType> notAttributeTypes;
147
148
149 /**
150 * Creates a DITContentRule object using a unique OID.
151 *
152 * @param oid the OID for this DITContentRule
153 */
154 public DITContentRule( String oid )
155 {
156 super( SchemaObjectType.DIT_CONTENT_RULE, oid );
157
158 mayAttributeTypeOids = new ArrayList<String>();
159 mustAttributeTypeOids = new ArrayList<String>();
160 notAttributeTypeOids = new ArrayList<String>();
161 auxObjectClassOids = new ArrayList<String>();
162
163 mayAttributeTypes = new ArrayList<AttributeType>();
164 mustAttributeTypes = new ArrayList<AttributeType>();
165 notAttributeTypes = new ArrayList<AttributeType>();
166 auxObjectClasses = new ArrayList<ObjectClass>();
167 }
168
169
170 /**
171 * @return the auxObjectClassOids
172 */
173 public List<String> getAuxObjectClassOids()
174 {
175 return auxObjectClassOids;
176 }
177
178
179 /**
180 * Add an Auxiliary ObjectClass Oid
181 *
182 * @param oid The ObjectClass oid
183 */
184 public void addAuxObjectClassOidOids( String oid )
185 {
186 if ( !isReadOnly )
187 {
188 auxObjectClassOids.add( oid );
189 }
190 }
191
192
193 /**
194 * Add an Auxiliary ObjectClass
195 *
196 * @param oid The ObjectClass
197 */
198 public void addAuxObjectClasses( ObjectClass objectClass )
199 {
200 if ( !isReadOnly )
201 {
202 if ( !auxObjectClassOids.contains( objectClass.getOid() ) )
203 {
204 auxObjectClasses.add( objectClass );
205 auxObjectClassOids.add( objectClass.getOid() );
206 }
207 }
208 }
209
210
211 /**
212 * @param auxObjectClassOids the auxObjectClassOids to set
213 */
214 public void setAuxObjectClassOids( List<String> auxObjectClassOids )
215 {
216 if ( !isReadOnly )
217 {
218 this.auxObjectClassOids = auxObjectClassOids;
219 }
220 }
221
222
223 /**
224 * @param auxObjectClasses the auxObjectClasses to set
225 */
226 public void setAuxObjectClasses( List<ObjectClass> auxObjectClasses )
227 {
228 if ( !isReadOnly )
229 {
230 this.auxObjectClasses = auxObjectClasses;
231
232 // update the OIDS now
233 auxObjectClassOids.clear();
234
235 for ( ObjectClass oc : auxObjectClasses )
236 {
237 auxObjectClassOids.add( oc.getOid() );
238 }
239 }
240 }
241
242
243 /**
244 * @return the auxObjectClasses
245 */
246 public List<ObjectClass> getAuxObjectClasses()
247 {
248 return auxObjectClasses;
249 }
250
251
252 /**
253 * @return the mayAttributeTypeOids
254 */
255 public List<String> getMayAttributeTypeOids()
256 {
257 return mayAttributeTypeOids;
258 }
259
260
261 /**
262 * Add an allowed AttributeType
263 *
264 * @param oid The attributeType oid
265 */
266 public void addMayAttributeTypeOids( String oid )
267 {
268 if ( !isReadOnly )
269 {
270 mayAttributeTypeOids.add( oid );
271 }
272 }
273
274
275 /**
276 * Add an allowed AttributeType
277 *
278 * @param attributeType The attributeType
279 */
280 public void addMayAttributeTypes( AttributeType attributeType )
281 {
282 if ( !isReadOnly )
283 {
284 if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
285 {
286 mayAttributeTypes.add( attributeType );
287 mayAttributeTypeOids.add( attributeType.getOid() );
288 }
289 }
290 }
291
292
293 /**
294 * @param mayAttributeTypeOids the mayAttributeTypeOids to set
295 */
296 public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids )
297 {
298 if ( !isReadOnly )
299 {
300 this.mayAttributeTypeOids = mayAttributeTypeOids;
301 }
302 }
303
304
305 /**
306 * Sets the list of allowed AttributeTypes
307 *
308 * @param mayAttributeTypes the list of allowed AttributeTypes
309 */
310 public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes )
311 {
312 if ( !isReadOnly )
313 {
314 this.mayAttributeTypes = mayAttributeTypes;
315
316 // update the OIDS now
317 mayAttributeTypeOids.clear();
318
319 for ( AttributeType may : mayAttributeTypes )
320 {
321 mayAttributeTypeOids.add( may.getOid() );
322 }
323 }
324 }
325
326
327 /**
328 * @return the mayAttributeTypes
329 */
330 public List<AttributeType> getMayAttributeTypes()
331 {
332 return mayAttributeTypes;
333 }
334
335
336 /**
337 * @return the mustAttributeTypeOids
338 */
339 public List<String> getMustAttributeTypeOids()
340 {
341 return mustAttributeTypeOids;
342 }
343
344
345 /**
346 * Add a required AttributeType OID
347 *
348 * @param oid The attributeType OID
349 */
350 public void addMustAttributeTypeOids( String oid )
351 {
352 if ( !isReadOnly )
353 {
354 mustAttributeTypeOids.add( oid );
355 }
356 }
357
358
359 /**
360 * Add a required AttributeType
361 *
362 * @param attributeType The attributeType
363 */
364 public void addMustAttributeTypes( AttributeType attributeType )
365 {
366 if ( !isReadOnly )
367 {
368 if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
369 {
370 mustAttributeTypes.add( attributeType );
371 mustAttributeTypeOids.add( attributeType.getOid() );
372 }
373 }
374 }
375
376
377 /**
378 * @param mustAttributeTypeOids the mustAttributeTypeOids to set
379 */
380 public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids )
381 {
382 if ( !isReadOnly )
383 {
384 this.mustAttributeTypeOids = mustAttributeTypeOids;
385 }
386 }
387
388
389 /**
390 * Sets the list of required AttributeTypes
391 *
392 * @param mayAttributeTypes the list of required AttributeTypes
393 */
394 public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes )
395 {
396 if ( !isReadOnly )
397 {
398 this.mustAttributeTypes = mustAttributeTypes;
399
400 // update the OIDS now
401 mustAttributeTypeOids.clear();
402
403 for ( AttributeType may : mustAttributeTypes )
404 {
405 mustAttributeTypeOids.add( may.getOid() );
406 }
407 }
408 }
409
410
411 /**
412 * @return the mustAttributeTypes
413 */
414 public List<AttributeType> getMustAttributeTypes()
415 {
416 return mustAttributeTypes;
417 }
418
419
420 /**
421 * @return the notAttributeTypeOids
422 */
423 public List<String> getNotAttributeTypeOids()
424 {
425 return notAttributeTypeOids;
426 }
427
428
429 /**
430 * Add a precluded AttributeType
431 *
432 * @param oid The attributeType oid
433 */
434 public void addNotAttributeTypeOids( String oid )
435 {
436 if ( !isReadOnly )
437 {
438 notAttributeTypeOids.add( oid );
439 }
440 }
441
442
443 /**
444 * Add a precluded AttributeType
445 *
446 * @param attributeType The attributeType
447 */
448 public void addNotAttributeTypes( AttributeType attributeType )
449 {
450 if ( !isReadOnly )
451 {
452 if ( !notAttributeTypeOids.contains( attributeType.getOid() ) )
453 {
454 notAttributeTypes.add( attributeType );
455 notAttributeTypeOids.add( attributeType.getOid() );
456 }
457 }
458 }
459
460
461 /**
462 * @param notAttributeTypeOids the notAttributeTypeOids to set
463 */
464 public void setNotAttributeTypeOids( List<String> notAttributeTypeOids )
465 {
466 if ( !isReadOnly )
467 {
468 this.notAttributeTypeOids = notAttributeTypeOids;
469 }
470 }
471
472
473 /**
474 * Sets the list of precluded AttributeTypes
475 *
476 * @param mayAttributeTypes the list of precluded AttributeTypes
477 */
478 public void setNotAttributeTypes( List<AttributeType> notAttributeTypes )
479 {
480 if ( !isReadOnly )
481 {
482 this.notAttributeTypes = notAttributeTypes;
483
484 // update the OIDS now
485 notAttributeTypeOids.clear();
486
487 for ( AttributeType not : notAttributeTypes )
488 {
489 notAttributeTypeOids.add( not.getOid() );
490 }
491 }
492 }
493
494
495 /**
496 * @return the notAttributeTypes
497 */
498 public List<AttributeType> getNotAttributeTypes()
499 {
500 return notAttributeTypes;
501 }
502
503
504 /**
505 * Inject the DITContentRule into the registries, updating the references to
506 * other SchemaObject
507 *
508 * @param registries The Registries
509 * @exception If the addition failed
510 */
511 public void addToRegistries( Registries registries ) throws NamingException
512 {
513 if ( registries != null )
514 {
515 AttributeTypeRegistry atRegistry = registries.getAttributeTypeRegistry();
516 ObjectClassRegistry ocRegistry = registries.getObjectClassRegistry();
517
518 if ( mayAttributeTypeOids != null )
519 {
520 mayAttributeTypes = new ArrayList<AttributeType>( mayAttributeTypeOids.size() );
521
522 for ( String oid : mayAttributeTypeOids )
523 {
524 mayAttributeTypes.add( atRegistry.lookup( oid ) );
525 }
526 }
527
528 if ( mustAttributeTypeOids != null )
529 {
530 mustAttributeTypes = new ArrayList<AttributeType>( mustAttributeTypeOids.size() );
531
532 for ( String oid : mustAttributeTypeOids )
533 {
534 mustAttributeTypes.add( atRegistry.lookup( oid ) );
535 }
536 }
537
538 if ( notAttributeTypeOids != null )
539 {
540 notAttributeTypes = new ArrayList<AttributeType>( notAttributeTypeOids.size() );
541
542 for ( String oid : notAttributeTypeOids )
543 {
544 notAttributeTypes.add( atRegistry.lookup( oid ) );
545 }
546 }
547
548 if ( auxObjectClassOids != null )
549 {
550 auxObjectClasses = new ArrayList<ObjectClass>( auxObjectClassOids.size() );
551
552 for ( String oid : auxObjectClassOids )
553 {
554 auxObjectClasses.add( ocRegistry.lookup( oid ) );
555 }
556 }
557 }
558 }
559
560
561 /**
562 * @see Object#toString()
563 */
564 public String toString()
565 {
566 return objectType + " " + DescriptionUtils.getDescription( this );
567 }
568
569
570 /**
571 * Copy a DITContentRule
572 */
573 public DITContentRule copy()
574 {
575 DITContentRule copy = new DITContentRule( oid );
576
577 // Copy the SchemaObject common data
578 copy.copy( this );
579
580 // copy the AUX ObjectClasses OIDs
581 copy.auxObjectClassOids = new ArrayList<String>();
582
583 for ( String oid : auxObjectClassOids )
584 {
585 copy.auxObjectClassOids.add( oid );
586 }
587
588 // copy the AUX ObjectClasses ( will be empty )
589 copy.auxObjectClasses = new ArrayList<ObjectClass>();
590
591 // Clone the MAY AttributeTypes OIDs
592 copy.mayAttributeTypeOids = new ArrayList<String>();
593
594 for ( String oid : mayAttributeTypeOids )
595 {
596 copy.mayAttributeTypeOids.add( oid );
597 }
598
599 // Clone the MAY AttributeTypes ( will be empty )
600 copy.mayAttributeTypes = new ArrayList<AttributeType>();
601
602 // Clone the MUST AttributeTypes OIDs
603 copy.mustAttributeTypeOids = new ArrayList<String>();
604
605 for ( String oid : mustAttributeTypeOids )
606 {
607 copy.mustAttributeTypeOids.add( oid );
608 }
609
610 // Clone the MUST AttributeTypes ( will be empty )
611 copy.mustAttributeTypes = new ArrayList<AttributeType>();
612
613 // Clone the NOT AttributeTypes OIDs
614 copy.notAttributeTypeOids = new ArrayList<String>();
615
616 for ( String oid : notAttributeTypeOids )
617 {
618 copy.notAttributeTypeOids.add( oid );
619 }
620
621 // Clone the NOT AttributeTypes ( will be empty )
622 copy.notAttributeTypes = new ArrayList<AttributeType>();
623
624 return copy;
625 }
626
627
628 /**
629 * @see Object#equals(Object)
630 */
631 public boolean equals( Object o )
632 {
633 if ( !super.equals( o ) )
634 {
635 return false;
636 }
637
638 if ( !( o instanceof DITContentRule ) )
639 {
640 return false;
641 }
642
643 DITContentRule that = ( DITContentRule ) o;
644
645 // TODO : complete the check
646 return true;
647 }
648
649
650 /**
651 * {@inheritDoc}
652 */
653 public void clear()
654 {
655 // Clear the common elements
656 super.clear();
657
658 // Clear the references
659 auxObjectClasses.clear();
660 auxObjectClassOids.clear();
661 mayAttributeTypes.clear();
662 mayAttributeTypeOids.clear();
663 mustAttributeTypes.clear();
664 mustAttributeTypeOids.clear();
665 notAttributeTypes.clear();
666 notAttributeTypeOids.clear();
667 }
668 }