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  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
129  */
130 public class MutableAttributeType extends AttributeType
131 {
132     /** The mandatory serialVersionUID */
133     public static final long serialVersionUID = 1L;
134 
135 
136     /**
137      * Creates a AttributeType object using a unique OID.
138      *
139      * @param oid the OID for this AttributeType
140      */
141     public MutableAttributeType( String oid )
142     {
143         super( oid );
144     }
145 
146 
147     /**
148      * Tells if this AttributeType is Single Valued or not
149      *
150      * @param singleValued True if the AttributeType is single-valued
151      */
152     public void setSingleValued( boolean singleValued )
153     {
154         if ( locked )
155         {
156             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
157         }
158 
159         if ( !isReadOnly )
160         {
161             this.isSingleValued = singleValued;
162         }
163     }
164 
165 
166     /**
167      * Tells if this AttributeType can be modified by a user or not
168      *
169      * @param userModifiable The flag to set
170      */
171     public void setUserModifiable( boolean userModifiable )
172     {
173         if ( locked )
174         {
175             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
176         }
177 
178         if ( !isReadOnly )
179         {
180             this.canUserModify = userModifiable;
181         }
182     }
183 
184 
185     /**
186      * Updates the collective flag
187      *
188      * @param collective The new value to set
189      */
190     public void updateCollective( boolean collective )
191     {
192         if ( locked )
193         {
194             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
195         }
196 
197         this.isCollective = collective;
198     }
199 
200 
201     /**
202      * Sets the collective flag
203      *
204      * @param collective The new value to set
205      */
206     public void setCollective( boolean collective )
207     {
208         if ( locked )
209         {
210             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
211         }
212 
213         if ( !isReadOnly )
214         {
215             this.isCollective = collective;
216         }
217     }
218 
219 
220     /**
221      * Sets the AttributeType usage, one of :
222      * <ul>
223      *   <li>USER_APPLICATIONS</li>
224      *   <li>DIRECTORY_OPERATION</li>
225      *   <li>DISTRIBUTED_OPERATION</li>
226      *   <li>DSA_OPERATION</li>
227      * </ul>
228      * 
229      * @see UsageEnum
230      * @param usage The AttributeType usage
231      */
232     public void setUsage( UsageEnum usage )
233     {
234         if ( locked )
235         {
236             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
237         }
238 
239         if ( !isReadOnly )
240         {
241             this.usage = usage;
242         }
243     }
244 
245 
246     /**
247      * Updates the AttributeType usage, one of :
248      * <ul>
249      *   <li>USER_APPLICATIONS</li>
250      *   <li>DIRECTORY_OPERATION</li>
251      *   <li>DISTRIBUTED_OPERATION</li>
252      *   <li>DSA_OPERATION</li>
253      * </ul>
254      * 
255      * @see UsageEnum
256      * @param newUsage The AttributeType usage
257      */
258     public void updateUsage( UsageEnum newUsage )
259     {
260         if ( locked )
261         {
262             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
263         }
264 
265         this.usage = newUsage;
266     }
267 
268 
269     /**
270      * Sets the length limit of this AttributeType based on its associated
271      * syntax.
272      *
273      * @param length the new length to set
274      */
275     public void setSyntaxLength( long length )
276     {
277         if ( locked )
278         {
279             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
280         }
281 
282         if ( !isReadOnly )
283         {
284             this.syntaxLength = length;
285         }
286     }
287 
288 
289     /**
290      * Sets the superior AttributeType OID of this AttributeType
291      *
292      * @param superiorOid The superior AttributeType OID of this AttributeType
293      */
294     public void setSuperiorOid( String superiorOid )
295     {
296         if ( locked )
297         {
298             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
299         }
300 
301         if ( !isReadOnly )
302         {
303             this.superiorOid = superiorOid;
304         }
305     }
306 
307 
308     /**
309      * Sets the superior for this AttributeType
310      *
311      * @param superior The superior for this AttributeType
312      */
313     public void setSuperior( MutableAttributeType superior )
314     {
315         if ( locked )
316         {
317             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
318         }
319 
320         if ( !isReadOnly )
321         {
322             this.superior = superior;
323             this.superiorOid = superior.getOid();
324         }
325     }
326 
327 
328     /**
329      * Sets the superior oid for this AttributeType
330      *
331      * @param newSuperiorOid The superior oid for this AttributeType
332      */
333     public void setSuperior( String newSuperiorOid )
334     {
335         if ( locked )
336         {
337             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
338         }
339 
340         if ( !isReadOnly )
341         {
342             this.superiorOid = newSuperiorOid;
343         }
344     }
345 
346 
347     /**
348      * Update the associated Superior AttributeType, even if the SchemaObject is readOnly
349      *
350      * @param newSuperior The superior for this AttributeType
351      */
352     public void updateSuperior( MutableAttributeType newSuperior )
353     {
354         if ( locked )
355         {
356             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
357         }
358 
359         this.superior = newSuperior;
360         this.superiorOid = newSuperior.getOid();
361     }
362 
363 
364     /**
365      * Sets the Syntax OID for this AttributeType
366      *
367      * @param syntaxOid The syntax OID for this AttributeType
368      */
369     public void setSyntaxOid( String syntaxOid )
370     {
371         if ( locked )
372         {
373             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
374         }
375 
376         if ( !isReadOnly )
377         {
378             this.syntaxOid = syntaxOid;
379         }
380     }
381 
382 
383     /**
384      * Sets the Syntax for this AttributeType
385      *
386      * @param syntax The Syntax for this AttributeType
387      */
388     public void setSyntax( LdapSyntax syntax )
389     {
390         if ( locked )
391         {
392             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
393         }
394 
395         if ( !isReadOnly )
396         {
397             this.syntax = syntax;
398             this.syntaxOid = syntax.getOid();
399         }
400     }
401 
402 
403     /**
404      * Update the associated Syntax, even if the SchemaObject is readOnly
405      *
406      * @param newSyntax The Syntax for this AttributeType
407      */
408     public void updateSyntax( LdapSyntax newSyntax )
409     {
410         if ( locked )
411         {
412             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
413         }
414 
415         this.syntax = newSyntax;
416         this.syntaxOid = newSyntax.getOid();
417     }
418 
419 
420     /**
421      * Sets the Equality OID for this AttributeType
422      *
423      * @param equalityOid The Equality OID for this AttributeType
424      */
425     public void setEqualityOid( String equalityOid )
426     {
427         if ( locked )
428         {
429             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
430         }
431 
432         if ( !isReadOnly )
433         {
434             this.equalityOid = equalityOid;
435         }
436     }
437 
438 
439     /**
440      * Sets the Equality MR for this AttributeType
441      *
442      * @param equality The Equality MR for this AttributeType
443      */
444     public void setEquality( MatchingRule equality )
445     {
446         if ( locked )
447         {
448             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
449         }
450 
451         if ( !isReadOnly )
452         {
453             this.equality = equality;
454             this.equalityOid = equality.getOid();
455         }
456     }
457 
458 
459     /**
460      * Update the associated Equality MatchingRule, even if the SchemaObject is readOnly
461      *
462      * @param newEquality The Equality MR for this AttributeType
463      */
464     public void updateEquality( MatchingRule newEquality )
465     {
466         if ( locked )
467         {
468             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
469         }
470 
471         this.equality = newEquality;
472         this.equalityOid = newEquality.getOid();
473     }
474 
475 
476     /**
477      * Sets the Ordering OID for this AttributeType
478      *
479      * @param orderingOid The Ordering OID for this AttributeType
480      */
481     public void setOrderingOid( String orderingOid )
482     {
483         if ( locked )
484         {
485             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
486         }
487 
488         if ( !isReadOnly )
489         {
490             this.orderingOid = orderingOid;
491         }
492     }
493 
494 
495     /**
496      * Sets the Ordering MR for this AttributeType
497      *
498      * @param ordering The Ordering MR for this AttributeType
499      */
500     public void setOrdering( MatchingRule ordering )
501     {
502         if ( locked )
503         {
504             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
505         }
506 
507         if ( !isReadOnly )
508         {
509             this.ordering = ordering;
510             this.orderingOid = ordering.getOid();
511         }
512     }
513 
514 
515     /**
516      * Update the associated Ordering MatchingRule, even if the SchemaObject is readOnly
517      *
518      * @param newOrdering The Ordering MR for this AttributeType
519      */
520     public void updateOrdering( MatchingRule newOrdering )
521     {
522         if ( locked )
523         {
524             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
525         }
526 
527         this.ordering = newOrdering;
528         this.orderingOid = newOrdering.getOid();
529     }
530 
531 
532     /**
533      * Sets the Substr OID for this AttributeType
534      *
535      * @param substrOid The Substr OID for this AttributeType
536      */
537     public void setSubstringOid( String substrOid )
538     {
539         if ( locked )
540         {
541             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
542         }
543 
544         if ( !isReadOnly )
545         {
546             this.substringOid = substrOid;
547         }
548     }
549 
550 
551     /**
552      * Sets the Substr MR for this AttributeType
553      *
554      * @param substring The Substr MR for this AttributeType
555      */
556     public void setSubstring( MatchingRule substring )
557     {
558         if ( locked )
559         {
560             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
561         }
562 
563         if ( !isReadOnly )
564         {
565             this.substring = substring;
566             this.substringOid = substring.getOid();
567         }
568     }
569 
570 
571     /**
572      * Update the associated Substring MatchingRule, even if the SchemaObject is readOnly
573      *
574      * @param newSubstring The Substr MR for this AttributeType
575      */
576     public void updateSubstring( MatchingRule newSubstring )
577     {
578         if ( locked )
579         {
580             throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
581         }
582 
583         this.substring = newSubstring;
584         this.substringOid = newSubstring.getOid();
585     }
586 
587 
588     /**
589      * {@inheritDoc}
590      */
591     @Override
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 }