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 org.apache.directory.api.i18n.I18n;
24  
25  
26  /**
27   * An attributeType specification. attributeType specifications describe the
28   * nature of attributes within the directory. The attributeType specification's
29   * properties are accessible through this interface.
30   * <p>
31   * According to ldapbis [MODELS]:
32   * </p>
33   *
34   * <pre>
35   *  4.1.2. Attribute Types
36   *
37   *    Attribute Type definitions are written according to the ABNF:
38   *
39   *      AttributeTypeDescription = LPAREN WSP
40   *          numericoid                   ; object identifier
41   *          [ SP &quot;NAME&quot; SP qdescrs ]     ; short names (descriptors)
42   *          [ SP &quot;DESC&quot; SP qdstring ]    ; description
43   *          [ SP &quot;OBSOLETE&quot; ]            ; not active
44   *          [ SP &quot;SUP&quot; SP oid ]          ; supertype
45   *          [ SP &quot;EQUALITY&quot; SP oid ]     ; equality matching rule
46   *          [ SP &quot;ORDERING&quot; SP oid ]     ; ordering matching rule
47   *          [ SP &quot;SUBSTR&quot; SP oid ]       ; substrings matching rule
48   *          [ SP &quot;SYNTAX&quot; SP noidlen ]   ; value syntax
49   *          [ SP &quot;SINGLE-VALUE&quot; ]        ; single-value
50   *          [ SP &quot;COLLECTIVE&quot; ]          ; collective
51   *          [ SP &quot;NO-USER-MODIFICATION&quot; ]; not user modifiable
52   *          [ SP &quot;USAGE&quot; SP usage ]      ; usage
53   *          extensions WSP RPAREN        ; extensions
54   *
55   *      usage = &quot;userApplications&quot;     / ; user
56   *              &quot;directoryOperation&quot;   / ; directory operational
57   *              &quot;distributedOperation&quot; / ; DSA-shared operational
58   *              &quot;dSAOperation&quot;           ; DSA-specific operational
59   *
60   *    where:
61   *      [numericoid] is object identifier assigned to this attribute type;
62   *      NAME [qdescrs] are short names (descriptors) identifying this
63   *          attribute type;
64   *      DESC [qdstring] is a short descriptive string;
65   *      OBSOLETE indicates this attribute type is not active;
66   *      SUP oid specifies the direct supertype of this type;
67   *      EQUALITY, ORDERING, SUBSTRING provide the oid of the equality,
68   *          ordering, and substrings matching rules, respectively;
69   *      SYNTAX identifies value syntax by object identifier and may suggest
70   *          a minimum upper bound;
71   *      COLLECTIVE indicates this attribute type is collective [X.501];
72   *      NO-USER-MODIFICATION indicates this attribute type is not user
73   *          modifiable;
74   *      USAGE indicates the application of this attribute type; and
75   *      [extensions] describe extensions.
76   *
77   *    Each attribute type description must contain at least one of the SUP
78   *    or SYNTAX fields.
79   *
80   *    Usage of userApplications, the default, indicates that attributes of
81   *    this type represent user information.  That is, they are user
82   *    attributes.
83   *
84   *    COLLECTIVE requires usage userApplications.  Use of collective
85   *    attribute types in LDAP is not discussed in this technical
86   *    specification.
87   *
88   *    A usage of directoryOperation, distributedOperation, or dSAOperation
89   *    indicates that attributes of this type represent operational and/or
90   *    administrative information.  That is, they are operational attributes.
91   *
92   *    directoryOperation usage indicates that the attribute of this type is
93   *    a directory operational attribute.  distributedOperation usage
94   *    indicates that the attribute of this DSA-shared usage operational
95   *    attribute.  dSAOperation usage indicates that the attribute of this
96   *    type is a DSA-specific operational attribute.
97   *
98   *    NO-USER-MODIFICATION requires an operational usage.
99   *
100  *    Note that the [AttributeTypeDescription] does not list the matching
101  *    rules which can be used with that attribute type in an extensibleMatch
102  *    search filter.  This is done using the 'matchingRuleUse' attribute
103  *    described in Section 4.1.4.
104  *
105  *    This document refines the schema description of X.501 by requiring
106  *    that the SYNTAX field in an [AttributeTypeDescription] be a string
107  *    representation of an object identifier for the LDAP string syntax
108  *    definition with an optional indication of the suggested minimum bound
109  *    of a value of this attribute.
110  *
111  *    A suggested minimum upper bound on the number of characters in a value
112  *    with a string-based syntax, or the number of bytes in a value for all
113  *    other syntaxes, may be indicated by appending this bound count inside
114  *    of curly braces following the syntax's OBJECT IDENTIFIER in an
115  *
116  *    Attribute Type Description.  This bound is not part of the syntax name
117  *    itself.  For instance, &quot;1.3.6.4.1.1466.0{64}&quot; suggests that server
118  *    implementations should allow a string to be 64 characters long,
119  *    although they may allow longer strings.  Note that a single character
120  *    of the Directory String syntax may be encoded in more than one octet
121  *    since UTF-8 is a variable-length encoding.
122  * </pre>
123  *
124  * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC 2252 Section 4.2</a>
125  * @see <a
126  *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">
127  *      ldapbis [MODELS]</a>
128  * @see DescriptionUtils#getDescription(MutableAttributeType)
129  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
130  */
131 public class MutableAttributeType extends AttributeType
132 {
133     /** The mandatory serialVersionUID */
134     public static final long serialVersionUID = 1L;
135 
136 
137     /**
138      * Creates a AttributeType object using a unique OID.
139      *
140      * @param oid the OID for this AttributeType
141      */
142     public MutableAttributeType( String oid )
143     {
144         super( oid );
145     }
146 
147 
148     /**
149      * Tells if this AttributeType is Single Valued or not
150      *
151      * @param singleValued True if the AttributeType is single-valued
152      */
153     public void setSingleValued( boolean singleValued )
154     {
155         if ( locked )
156         {
157             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
158         }
159 
160         if ( !isReadOnly )
161         {
162             this.isSingleValued = singleValued;
163         }
164     }
165 
166 
167     /**
168      * Tells if this AttributeType can be modified by a user or not
169      *
170      * @param userModifiable The flag to set
171      */
172     public void setUserModifiable( boolean userModifiable )
173     {
174         if ( locked )
175         {
176             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
177         }
178 
179         if ( !isReadOnly )
180         {
181             this.canUserModify = userModifiable;
182         }
183     }
184 
185 
186     /**
187      * Updates the collective flag
188      *
189      * @param collective The new value to set
190      */
191     public void updateCollective( boolean collective )
192     {
193         if ( locked )
194         {
195             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
196         }
197 
198         this.isCollective = collective;
199     }
200 
201 
202     /**
203      * Sets the collective flag
204      *
205      * @param collective The new value to set
206      */
207     public void setCollective( boolean collective )
208     {
209         if ( locked )
210         {
211             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
212         }
213 
214         if ( !isReadOnly )
215         {
216             this.isCollective = collective;
217         }
218     }
219 
220 
221     /**
222      * Sets the AttributeType usage, one of :
223      * <ul>
224      *   <li>USER_APPLICATIONS</li>
225      *   <li>DIRECTORY_OPERATION</li>
226      *   <li>DISTRIBUTED_OPERATION</li>
227      *   <li>DSA_OPERATION</li>
228      * </ul>
229      * 
230      * @see UsageEnum
231      * @param usage The AttributeType usage
232      */
233     public void setUsage( UsageEnum usage )
234     {
235         if ( locked )
236         {
237             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
238         }
239 
240         if ( !isReadOnly )
241         {
242             this.usage = usage;
243         }
244     }
245 
246 
247     /**
248      * Updates the AttributeType usage, one of :
249      * <ul>
250      *   <li>USER_APPLICATIONS</li>
251      *   <li>DIRECTORY_OPERATION</li>
252      *   <li>DISTRIBUTED_OPERATION</li>
253      *   <li>DSA_OPERATION</li>
254      * </ul>
255      * 
256      * @see UsageEnum
257      * @param newUsage The AttributeType usage
258      */
259     public void updateUsage( UsageEnum newUsage )
260     {
261         if ( locked )
262         {
263             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
264         }
265 
266         this.usage = newUsage;
267     }
268 
269 
270     /**
271      * Sets the length limit of this AttributeType based on its associated
272      * syntax.
273      *
274      * @param length the new length to set
275      */
276     public void setSyntaxLength( long length )
277     {
278         if ( locked )
279         {
280             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
281         }
282 
283         if ( !isReadOnly )
284         {
285             this.syntaxLength = length;
286         }
287     }
288 
289 
290     /**
291      * Sets the superior AttributeType OID of this AttributeType
292      *
293      * @param superiorOid The superior AttributeType OID of this AttributeType
294      */
295     public void setSuperiorOid( String superiorOid )
296     {
297         if ( locked )
298         {
299             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
300         }
301 
302         if ( !isReadOnly )
303         {
304             this.superiorOid = superiorOid;
305         }
306     }
307 
308 
309     /**
310      * Sets the superior for this AttributeType
311      *
312      * @param superior The superior for this AttributeType
313      */
314     public void setSuperior( MutableAttributeType superior )
315     {
316         if ( locked )
317         {
318             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
319         }
320 
321         if ( !isReadOnly )
322         {
323             this.superior = superior;
324             this.superiorOid = superior.getOid();
325         }
326     }
327 
328 
329     /**
330      * Sets the superior oid for this AttributeType
331      *
332      * @param newSuperiorOid The superior oid for this AttributeType
333      */
334     public void setSuperior( String newSuperiorOid )
335     {
336         if ( locked )
337         {
338             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
339         }
340 
341         if ( !isReadOnly )
342         {
343             this.superiorOid = newSuperiorOid;
344         }
345     }
346 
347 
348     /**
349      * Update the associated Superior AttributeType, even if the SchemaObject is readOnly
350      *
351      * @param newSuperior The superior for this AttributeType
352      */
353     public void updateSuperior( MutableAttributeType newSuperior )
354     {
355         if ( locked )
356         {
357             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
358         }
359 
360         this.superior = newSuperior;
361         this.superiorOid = newSuperior.getOid();
362     }
363 
364 
365     /**
366      * Sets the Syntax OID for this AttributeType
367      *
368      * @param syntaxOid The syntax OID for this AttributeType
369      */
370     public void setSyntaxOid( String syntaxOid )
371     {
372         if ( locked )
373         {
374             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
375         }
376 
377         if ( !isReadOnly )
378         {
379             this.syntaxOid = syntaxOid;
380         }
381     }
382 
383 
384     /**
385      * Sets the Syntax for this AttributeType
386      *
387      * @param syntax The Syntax for this AttributeType
388      */
389     public void setSyntax( LdapSyntax syntax )
390     {
391         if ( locked )
392         {
393             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
394         }
395 
396         if ( !isReadOnly )
397         {
398             this.syntax = syntax;
399             this.syntaxOid = syntax.getOid();
400         }
401     }
402 
403 
404     /**
405      * Update the associated Syntax, even if the SchemaObject is readOnly
406      *
407      * @param newSyntax The Syntax for this AttributeType
408      */
409     public void updateSyntax( LdapSyntax newSyntax )
410     {
411         if ( locked )
412         {
413             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
414         }
415 
416         this.syntax = newSyntax;
417         this.syntaxOid = newSyntax.getOid();
418     }
419 
420 
421     /**
422      * Sets the Equality OID for this AttributeType
423      *
424      * @param equalityOid The Equality OID for this AttributeType
425      */
426     public void setEqualityOid( String equalityOid )
427     {
428         if ( locked )
429         {
430             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
431         }
432 
433         if ( !isReadOnly )
434         {
435             this.equalityOid = equalityOid;
436         }
437     }
438 
439 
440     /**
441      * Sets the Equality MR for this AttributeType
442      *
443      * @param equality The Equality MR for this AttributeType
444      */
445     public void setEquality( MatchingRule equality )
446     {
447         if ( locked )
448         {
449             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
450         }
451 
452         if ( !isReadOnly )
453         {
454             this.equality = equality;
455             this.equalityOid = equality.getOid();
456         }
457     }
458 
459 
460     /**
461      * Update the associated Equality MatchingRule, even if the SchemaObject is readOnly
462      *
463      * @param newEquality The Equality MR for this AttributeType
464      */
465     public void updateEquality( MatchingRule newEquality )
466     {
467         if ( locked )
468         {
469             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
470         }
471 
472         this.equality = newEquality;
473         this.equalityOid = newEquality.getOid();
474     }
475 
476 
477     /**
478      * Sets the Ordering OID for this AttributeType
479      *
480      * @param orderingOid The Ordering OID for this AttributeType
481      */
482     public void setOrderingOid( String orderingOid )
483     {
484         if ( locked )
485         {
486             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
487         }
488 
489         if ( !isReadOnly )
490         {
491             this.orderingOid = orderingOid;
492         }
493     }
494 
495 
496     /**
497      * Sets the Ordering MR for this AttributeType
498      *
499      * @param ordering The Ordering MR for this AttributeType
500      */
501     public void setOrdering( MatchingRule ordering )
502     {
503         if ( locked )
504         {
505             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
506         }
507 
508         if ( !isReadOnly )
509         {
510             this.ordering = ordering;
511             this.orderingOid = ordering.getOid();
512         }
513     }
514 
515 
516     /**
517      * Update the associated Ordering MatchingRule, even if the SchemaObject is readOnly
518      *
519      * @param newOrdering The Ordering MR for this AttributeType
520      */
521     public void updateOrdering( MatchingRule newOrdering )
522     {
523         if ( locked )
524         {
525             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
526         }
527 
528         this.ordering = newOrdering;
529         this.orderingOid = newOrdering.getOid();
530     }
531 
532 
533     /**
534      * Sets the Substr OID for this AttributeType
535      *
536      * @param substrOid The Substr OID for this AttributeType
537      */
538     public void setSubstringOid( String substrOid )
539     {
540         if ( locked )
541         {
542             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
543         }
544 
545         if ( !isReadOnly )
546         {
547             this.substringOid = substrOid;
548         }
549     }
550 
551 
552     /**
553      * Sets the Substr MR for this AttributeType
554      *
555      * @param substring The Substr MR for this AttributeType
556      */
557     public void setSubstring( MatchingRule substring )
558     {
559         if ( locked )
560         {
561             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
562         }
563 
564         if ( !isReadOnly )
565         {
566             this.substring = substring;
567             this.substringOid = substring.getOid();
568         }
569     }
570 
571 
572     /**
573      * Update the associated Substring MatchingRule, even if the SchemaObject is readOnly
574      *
575      * @param newSubstring The Substr MR for this AttributeType
576      */
577     public void updateSubstring( MatchingRule newSubstring )
578     {
579         if ( locked )
580         {
581             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
582         }
583 
584         this.substring = newSubstring;
585         this.substringOid = newSubstring.getOid();
586     }
587 
588 
589     /**
590      * {@inheritDoc}
591      */
592     public void clear()
593     {
594         // Clear the common elements
595         super.clear();
596 
597         // Clear the references
598         equality = null;
599         ordering = null;
600         substring = null;
601         superior = null;
602         syntax = null;
603     }
604 }