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 *    https://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 */
020package org.apache.directory.api.ldap.model.schema.registries.helper;
021
022import java.util.HashSet;
023import java.util.Set;
024
025import org.apache.directory.api.i18n.I18n;
026import org.apache.directory.api.ldap.model.exception.LdapException;
027import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
028import org.apache.directory.api.ldap.model.exception.LdapSchemaExceptionCodes;
029import org.apache.directory.api.ldap.model.schema.AttributeType;
030import org.apache.directory.api.ldap.model.schema.LdapSyntax;
031import org.apache.directory.api.ldap.model.schema.MatchingRule;
032import org.apache.directory.api.ldap.model.schema.SchemaErrorHandler;
033import org.apache.directory.api.ldap.model.schema.UsageEnum;
034import org.apache.directory.api.ldap.model.schema.registries.AttributeTypeRegistry;
035import org.apache.directory.api.ldap.model.schema.registries.Registries;
036import org.slf4j.Logger;
037import org.slf4j.LoggerFactory;
038
039/**
040 * An helper class used to store all the methods associated with an AttributeType
041 * in relation with the Registries and SchemaManager.
042 * 
043 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
044 */
045public final class AttributeTypeHelper
046{
047    /** A logger for this class */
048    private static final Logger LOG = LoggerFactory.getLogger( AttributeTypeHelper.class );
049
050    private AttributeTypeHelper()
051    {
052    }
053
054    /**
055     * Inject the AttributeType into the Registries, updating the references to
056     * other SchemaObject
057     *
058     * If one of the referenced SchemaObject does not exist (SUP, EQUALITY, ORDERING, SUBSTR, SYNTAX),
059     * an exception is thrown.
060     * 
061     * @param attributeType The AttributeType to add to the Registries
062     * @param errorHandler Error handler
063     * @param registries The Registries
064     * @throws LdapException If the AttributeType is not valid
065     */
066    public static void addToRegistries( AttributeType attributeType, SchemaErrorHandler errorHandler, Registries registries ) throws LdapException
067    {
068        if ( registries != null )
069        {
070            try
071            {
072                attributeType.unlock();
073                AttributeTypeRegistry attributeTypeRegistry = registries.getAttributeTypeRegistry();
074    
075                // The superior
076                if ( !buildSuperior( attributeType, errorHandler, registries ) )
077                {
078                    // We have had errors, let's stop here as we need a correct superior to continue
079                    return;
080                }
081    
082                // The Syntax
083                buildSyntax( attributeType, errorHandler, registries );
084    
085                // The EQUALITY matching rule
086                buildEquality( attributeType, errorHandler, registries );
087    
088                // The ORDERING matching rule
089                buildOrdering( attributeType, errorHandler, registries );
090    
091                // The SUBSTR matching rule
092                buildSubstring( attributeType, errorHandler, registries );
093    
094                // Check the USAGE
095                checkUsage( attributeType, errorHandler );
096    
097                // Check the COLLECTIVE element
098                checkCollective( attributeType, errorHandler );
099    
100                // Inject the attributeType into the oid/normalizer map
101                attributeTypeRegistry.addMappingFor( attributeType );
102    
103                // Register this AttributeType into the Descendant map
104                attributeTypeRegistry.registerDescendants( attributeType, attributeType.getSuperior() );
105    
106                /**
107                 * Add the AT references (using and usedBy) :
108                 * AT -> MR (for EQUALITY, ORDERING and SUBSTR)
109                 * AT -> S
110                 * AT -> AT
111                 */
112                if ( attributeType.getEquality() != null )
113                {
114                    registries.addReference( attributeType, attributeType.getEquality() );
115                }
116    
117                if ( attributeType.getOrdering() != null )
118                {
119                    registries.addReference( attributeType, attributeType.getOrdering() );
120                }
121    
122                if ( attributeType.getSubstring() != null )
123                {
124                    registries.addReference( attributeType, attributeType.getSubstring() );
125                }
126    
127                if ( attributeType.getSyntax() != null )
128                {
129                    registries.addReference( attributeType, attributeType.getSyntax() );
130                }
131    
132                if ( attributeType.getSuperior() != null )
133                {
134                    registries.addReference( attributeType, attributeType.getSuperior() );
135                }
136            }
137            finally
138            {
139                attributeType.lock();
140            }
141        }
142    }
143
144
145    /**
146     * Build the Superior AttributeType reference for an AttributeType
147     * 
148     * @param attributeType The AttributeType to process
149     * @param errorHandler The error handler
150     * @param registries The Registries instance
151     * @return <tt>true</tt> if the AttributeType superiors hierarchy is correct, or if we don't have any superior
152     */
153    private static boolean buildSuperior( AttributeType attributeType, SchemaErrorHandler errorHandler, 
154            Registries registries )
155    {
156        AttributeType currentSuperior;
157        AttributeTypeRegistry attributeTypeRegistry = registries.getAttributeTypeRegistry();
158        
159        String superiorOid = attributeType.getSuperiorOid();
160
161        if ( superiorOid != null )
162        {
163            // This AT has a superior
164            try
165            {
166                currentSuperior = ( AttributeType ) attributeTypeRegistry.lookup( superiorOid );
167            }
168            catch ( Exception e )
169            {
170                // Not allowed.
171                String msg = I18n.err( I18n.ERR_13752_CANNOT_FIND_SUPERIOR, superiorOid, attributeType.getName() );
172
173                LdapSchemaException ldapSchemaException = new LdapSchemaException(
174                    LdapSchemaExceptionCodes.AT_NONEXISTENT_SUPERIOR, msg, e );
175                ldapSchemaException.setSourceObject( attributeType );
176                ldapSchemaException.setRelatedId( superiorOid );
177                errorHandler.handle( LOG, msg, ldapSchemaException );
178
179                // Get out now
180                return false;
181            }
182
183            if ( currentSuperior != null )
184            {
185                // a special case : if the superior is collective, this is an error
186                if ( currentSuperior.isCollective() )
187                {
188                    String msg = I18n.err( I18n.ERR_13776_CANNOT_SUBTYPE_COLLECTIVE,
189                        currentSuperior, attributeType.getName() );
190
191                    LdapSchemaException ldapSchemaException = new LdapSchemaException(
192                        LdapSchemaExceptionCodes.AT_CANNOT_SUBTYPE_COLLECTIVE_AT, msg );
193                    ldapSchemaException.setSourceObject( attributeType );
194                    errorHandler.handle( LOG, msg, ldapSchemaException );
195                    
196                    return false;
197                }
198
199                attributeType.setSuperior( currentSuperior );
200
201                // Recursively update the superior if not already done. We don't recurse
202                // if the superior's superior is not null, as it means it has already been
203                // handled.
204                if ( currentSuperior.getSuperior() == null )
205                {
206                    registries.buildReference( currentSuperior );
207                }
208
209                // Update the descendant MAP
210                try
211                {
212                    attributeTypeRegistry.registerDescendants( attributeType, currentSuperior );
213                }
214                catch ( LdapException ne )
215                {
216                    errorHandler.handle( LOG, ne.getMessage(), ne );
217                    
218                    return false;
219                }
220
221                // Check for cycles now
222                Set<String> superiors = new HashSet<>();
223                superiors.add( attributeType.getOid() );
224                AttributeType tmp = currentSuperior;
225                boolean isOk = true;
226
227                while ( tmp != null )
228                {
229                    if ( superiors.contains( tmp.getOid() ) )
230                    {
231                        // There is a cycle : bad bad bad !
232                        // Not allowed.
233                        String msg = I18n.err( I18n.ERR_13753_CYCLE_DETECTED, attributeType.getName() );
234
235                        LdapSchemaException ldapSchemaException = new LdapSchemaException(
236                            LdapSchemaExceptionCodes.AT_CYCLE_TYPE_HIERARCHY, msg );
237                        ldapSchemaException.setSourceObject( attributeType );
238                        errorHandler.handle( LOG, msg, ldapSchemaException );
239
240                        isOk = false;
241
242                        break;
243                    }
244                    else
245                    {
246                        superiors.add( tmp.getOid() );
247                        tmp = tmp.getSuperior();
248                    }
249                }
250
251                superiors.clear();
252
253                return isOk;
254            }
255            else
256            {
257                // Not allowed.
258                String msg = I18n.err( I18n.ERR_13752_CANNOT_FIND_SUPERIOR, superiorOid, attributeType.getName() );
259
260                LdapSchemaException ldapSchemaException = new LdapSchemaException(
261                    LdapSchemaExceptionCodes.AT_NONEXISTENT_SUPERIOR, msg );
262                ldapSchemaException.setSourceObject( attributeType );
263                ldapSchemaException.setRelatedId( superiorOid );
264                errorHandler.handle( LOG, msg, ldapSchemaException );
265
266                // Get out now
267                return false;
268            }
269        }
270        else
271        {
272            // No superior, just return
273            return true;
274        }
275    }
276
277
278    /**
279     * Build the SYNTAX reference for an AttributeType
280     * 
281     * @param attributeType The AttributeType to process
282     * @param errorHandler The error handler
283     * @param registries The Registries instance
284     */
285    private static void buildSyntax( AttributeType attributeType, SchemaErrorHandler errorHandler, 
286            Registries registries )
287    {
288        String syntaxOid = attributeType.getSyntaxOid();
289        
290        if ( syntaxOid != null )
291        {
292            LdapSyntax currentSyntax = null;
293
294            try
295            {
296                currentSyntax = registries.getLdapSyntaxRegistry().lookup( syntaxOid );
297            }
298            catch ( LdapException ne )
299            {
300                // Not allowed.
301                String msg = I18n.err( I18n.ERR_13754_CANNOT_FIND_SYNTAX, syntaxOid, attributeType.getName() );
302
303                LdapSchemaException ldapSchemaException = new LdapSchemaException(
304                    LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg, ne );
305                ldapSchemaException.setSourceObject( attributeType );
306                ldapSchemaException.setRelatedId( syntaxOid );
307                errorHandler.handle( LOG, msg, ldapSchemaException );
308                
309                return;
310            }
311
312            if ( currentSyntax != null )
313            {
314                // Update the Syntax reference
315                attributeType.setSyntax( currentSyntax );
316            }
317            else
318            {
319                // Not allowed.
320                String msg = I18n.err( I18n.ERR_13754_CANNOT_FIND_SYNTAX, syntaxOid, attributeType.getName() );
321
322                LdapSchemaException ldapSchemaException = new LdapSchemaException(
323                    LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg );
324                ldapSchemaException.setSourceObject( attributeType );
325                ldapSchemaException.setRelatedId( syntaxOid );
326                errorHandler.handle( LOG, msg, ldapSchemaException );
327            }
328        }
329        else
330        {
331            // We inherit from the superior's syntax, if any
332            if ( attributeType.getSuperior() != null )
333            {
334                if ( attributeType.getSuperior().getSyntax() != null )
335                {
336                    attributeType.setSyntax( attributeType.getSuperior().getSyntax() );
337                }
338                else
339                {
340                    String msg = I18n.err( I18n.ERR_13754_CANNOT_FIND_SYNTAX, syntaxOid, attributeType.getName() );
341
342                    LdapSchemaException ldapSchemaException = new LdapSchemaException(
343                        LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg );
344                    ldapSchemaException.setSourceObject( attributeType );
345                    ldapSchemaException.setRelatedId( syntaxOid );
346                    errorHandler.handle( LOG, msg, ldapSchemaException );
347                }
348            }
349            else
350            {
351                // Not allowed.
352                String msg = I18n.err( I18n.ERR_13755_AT_MUST_HAVE_A_SYNTAX_OID, attributeType.getName() );
353
354                LdapSchemaException ldapSchemaException = new LdapSchemaException(
355                    LdapSchemaExceptionCodes.AT_SYNTAX_OR_SUPERIOR_REQUIRED, msg );
356                ldapSchemaException.setSourceObject( attributeType );
357                errorHandler.handle( LOG, msg, ldapSchemaException );
358            }
359        }
360    }
361    
362    
363    /**
364     * Build the EQUALITY MR reference for an AttributeType
365     * 
366     * @param attributeType The AttributeType to process
367     * @param errorHandler The error handler
368     * @param registries The Registries instance
369     */
370    private static void buildEquality( AttributeType attributeType, SchemaErrorHandler errorHandler, 
371            Registries registries )
372    {
373        String equalityOid = attributeType.getEqualityOid();
374        
375        // The equality MR. It can be null
376        if ( equalityOid != null )
377        {
378            MatchingRule currentEquality = null;
379
380            try
381            {
382                currentEquality = registries.getMatchingRuleRegistry().lookup( equalityOid );
383            }
384            catch ( LdapException ne )
385            {
386                // Not allowed.
387                String msg = I18n.err( I18n.ERR_13756_CANNOT_FIND_EQUALITY_MR_OBJECT, equalityOid, attributeType.getName() );
388
389                LdapSchemaException ldapSchemaException = new LdapSchemaException(
390                    LdapSchemaExceptionCodes.AT_NONEXISTENT_EQUALITY_MATCHING_RULE, msg, ne );
391                ldapSchemaException.setSourceObject( attributeType );
392                ldapSchemaException.setRelatedId( equalityOid );
393                errorHandler.handle( LOG, msg, ldapSchemaException );
394                
395                return;
396            }
397
398            if ( currentEquality != null )
399            {
400                attributeType.setEquality( currentEquality );
401                
402                // Restore the old equality OID to preserve the user's provided value
403                attributeType.setEqualityOid( equalityOid );
404            }
405            else
406            {
407                // Not allowed.
408                String msg = I18n.err( I18n.ERR_13757_CANNOT_FIND_EQUALITY_MR_INSTANCE, equalityOid, attributeType.getName() );
409
410                LdapSchemaException ldapSchemaException = new LdapSchemaException(
411                    LdapSchemaExceptionCodes.AT_NONEXISTENT_EQUALITY_MATCHING_RULE, msg );
412                ldapSchemaException.setSourceObject( attributeType );
413                ldapSchemaException.setRelatedId( equalityOid );
414                errorHandler.handle( LOG, msg, ldapSchemaException );
415            }
416        }
417        else
418        {
419            AttributeType superior = attributeType.getSuperior();
420            
421            // If the AT has a superior, take its Equality MR if any
422            if ( ( superior != null ) && ( superior.getEquality() != null ) )
423            {
424                attributeType.setEquality( superior.getEquality() );
425            }
426        }
427    }
428
429
430    /**
431     * Build the SUBSTR MR reference for an AttributeType
432     * 
433     * @param attributeType The AttributeType to process
434     * @param errorHandler The error handler
435     * @param registries The Registries instance
436     */
437    private static void buildSubstring( AttributeType attributeType, SchemaErrorHandler errorHandler,
438            Registries registries )
439    {
440        String substringOid = attributeType.getSubstringOid();
441        
442        // The Substring MR. It can be null
443        if ( substringOid != null )
444        {
445            MatchingRule currentSubstring = null;
446
447            try
448            {
449                currentSubstring = registries.getMatchingRuleRegistry().lookup( substringOid );
450            }
451            catch ( LdapException ne )
452            {
453                // Not allowed.
454                String msg = I18n.err( I18n.ERR_13760_CANNOT_FIND_SUBSTR_MR_OBJECT, substringOid, attributeType.getName() );
455
456                LdapSchemaException ldapSchemaException = new LdapSchemaException(
457                    LdapSchemaExceptionCodes.AT_NONEXISTENT_SUBSTRING_MATCHING_RULE, msg, ne );
458                ldapSchemaException.setSourceObject( attributeType );
459                ldapSchemaException.setRelatedId( substringOid );
460                errorHandler.handle( LOG, msg, ldapSchemaException );
461                
462                return;
463            }
464
465            if ( currentSubstring != null )
466            {
467                attributeType.setSubstring( currentSubstring );
468            }
469            else
470            {
471                // Not allowed.
472                String msg = I18n.err( I18n.ERR_13761_CANNOT_FIND_SUBSTR_MR_INSTANCE, substringOid, attributeType.getName() );
473
474                LdapSchemaException ldapSchemaException = new LdapSchemaException(
475                    LdapSchemaExceptionCodes.AT_NONEXISTENT_SUBSTRING_MATCHING_RULE, msg );
476                ldapSchemaException.setSourceObject( attributeType );
477                ldapSchemaException.setRelatedId( substringOid );
478                errorHandler.handle( LOG, msg, ldapSchemaException );
479            }
480        }
481        else
482        {
483            AttributeType superior = attributeType.getSuperior();
484            
485            // If the AT has a superior, take its Substring MR if any
486            if ( ( superior != null ) && ( superior.getSubstring() != null ) )
487            {
488                attributeType.setSubstring( superior.getSubstring() );
489            }
490        }
491    }
492    
493    
494    /**
495     * Build the ORDERING MR reference for an AttributeType
496     * 
497     * @param attributeType The AttributeType to process
498     * @param errorHandler The error handler
499     * @param registries The Registries instance
500     */
501    private static void buildOrdering( AttributeType attributeType, SchemaErrorHandler errorHandler, 
502            Registries registries )
503    {
504        String orderingOid = attributeType.getOrderingOid();
505        
506        if ( orderingOid != null )
507        {
508            MatchingRule currentOrdering = null;
509
510            try
511            {
512                currentOrdering = registries.getMatchingRuleRegistry().lookup( orderingOid );
513            }
514            catch ( LdapException ne )
515            {
516                // Not allowed.
517                String msg = I18n.err( I18n.ERR_13758_CANNOT_FIND_ORDERING_MR_OBJECT, orderingOid, attributeType.getName() );
518
519                LdapSchemaException ldapSchemaException = new LdapSchemaException(
520                    LdapSchemaExceptionCodes.AT_NONEXISTENT_ORDERING_MATCHING_RULE, msg, ne );
521                ldapSchemaException.setSourceObject( attributeType );
522                ldapSchemaException.setRelatedId( orderingOid );
523                errorHandler.handle( LOG, msg, ldapSchemaException );
524                
525                return;
526            }
527
528            if ( currentOrdering != null )
529            {
530                attributeType.setOrdering( currentOrdering );
531            }
532            else
533            {
534                // Not allowed.
535                String msg = I18n.err( I18n.ERR_13759_CANNOT_FIND_ORDERING_MR_INSTANCE, orderingOid, attributeType.getName() );
536
537                LdapSchemaException ldapSchemaException = new LdapSchemaException(
538                    LdapSchemaExceptionCodes.AT_NONEXISTENT_ORDERING_MATCHING_RULE, msg );
539                ldapSchemaException.setSourceObject( attributeType );
540                ldapSchemaException.setRelatedId( orderingOid );
541                errorHandler.handle( LOG, msg, ldapSchemaException );
542            }
543        }
544        else
545        {
546            AttributeType superior = attributeType.getSuperior();
547            
548            // If the AT has a superior, take its Ordering MR if any
549            if ( ( superior != null ) && ( superior.getOrdering() != null ) )
550            {
551                attributeType.setOrdering( superior.getOrdering() );
552            }
553        }
554    }
555
556    
557    /**
558     * Check the constraints for the Usage field.
559     * 
560     * @param attributeType The AttributeType to check
561     * @param errorHandler The error handler
562     */
563    private static void checkUsage( AttributeType attributeType, SchemaErrorHandler errorHandler )
564    {
565        AttributeType superior = attributeType.getSuperior();
566        
567        // Check that the AT usage is the same that its superior
568        if ( ( superior != null ) && ( attributeType.getUsage() != superior.getUsage() ) )
569        {
570            // This is an error
571            String msg = I18n.err( I18n.ERR_13762_AT_MUST_HAVE_SUPERIOR_USAGE, attributeType.getName() );
572
573            LdapSchemaException ldapSchemaException = new LdapSchemaException(
574                LdapSchemaExceptionCodes.AT_MUST_HAVE_SAME_USAGE_THAN_SUPERIOR, msg );
575            ldapSchemaException.setSourceObject( attributeType );
576            errorHandler.handle( LOG, msg, ldapSchemaException );
577            
578            return;
579        }
580
581        // Now, check that the AttributeType's USAGE does not conflict
582        if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
583        {
584            // Cannot have a not user modifiable AT which is not an operational AT
585            String msg = I18n.err( I18n.ERR_13763_AT_MUST_BE_USER_MODIFIABLE, attributeType.getName() );
586
587            LdapSchemaException ldapSchemaException = new LdapSchemaException(
588                LdapSchemaExceptionCodes.AT_USER_APPLICATIONS_USAGE_MUST_BE_USER_MODIFIABLE, msg );
589            ldapSchemaException.setSourceObject( attributeType );
590            errorHandler.handle( LOG, msg, ldapSchemaException );
591        }
592    }
593
594
595    /**
596     * Check the constraints for the Collective field.
597     * 
598     * @param attributeType The AttributeType to check
599     * @param errorHandler The error handler
600     */
601    private static void checkCollective( AttributeType attributeType, SchemaErrorHandler errorHandler )
602    {
603        AttributeType superior = attributeType.getSuperior();
604
605        if ( ( superior != null ) && superior.isCollective() )
606        {
607            // An AttributeType will be collective if its superior is collective
608            attributeType.setCollective( true );
609        }
610
611        if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
612        {
613            // An AttributeType which is collective must be a USER attributeType
614            String msg = I18n.err( I18n.ERR_13764_AT_COLLECTIVE_SHOULD_BE_USER_APP, attributeType.getName() );
615
616            LdapSchemaException ldapSchemaException = new LdapSchemaException(
617                LdapSchemaExceptionCodes.AT_COLLECTIVE_MUST_HAVE_USER_APPLICATIONS_USAGE, msg );
618            ldapSchemaException.setSourceObject( attributeType );
619            errorHandler.handle( LOG, msg, ldapSchemaException );
620        }
621
622        if ( attributeType.isCollective() && attributeType.isSingleValued() )
623        {
624            // A collective attribute must be multi-valued
625            String msg = I18n.err( I18n.ERR_13777_COLLECTIVE_NOT_MULTI_VALUED, attributeType.getName() );
626
627            LdapSchemaException ldapSchemaException = new LdapSchemaException(
628                LdapSchemaExceptionCodes.AT_COLLECTIVE_CANNOT_BE_SINGLE_VALUED, msg );
629            ldapSchemaException.setSourceObject( attributeType );
630            errorHandler.handle( LOG, msg, ldapSchemaException );
631        }
632    }
633    
634    
635    /**
636     * Remove the AttributeType from the registries, updating the references to
637     * other SchemaObject.
638     *
639     * If one of the referenced SchemaObject does not exist (SUP, EQUALITY, ORDERING, SUBSTR, SYNTAX),
640     * an exception is thrown.
641     * 
642     * @param attributeType The AttributeType to remove from the Registries
643     * @param errorHandler Error handler
644     * @param registries The Registries
645     * @throws LdapException If the AttributeType is not valid
646     */
647    public static void removeFromRegistries( AttributeType attributeType, SchemaErrorHandler errorHandler, Registries registries ) throws LdapException
648    {
649        if ( registries != null )
650        {
651            AttributeTypeRegistry attributeTypeRegistry = registries.getAttributeTypeRegistry();
652
653            // Remove the attributeType from the oid/normalizer map
654            attributeTypeRegistry.removeMappingFor( attributeType );
655
656            // Unregister this AttributeType into the Descendant map
657            attributeTypeRegistry.unregisterDescendants( attributeType, attributeType.getSuperior() );
658
659            /**
660             * Remove the AT references (using and usedBy) :
661             * AT -> MR (for EQUALITY, ORDERING and SUBSTR)
662             * AT -> S
663             * AT -> AT
664             */
665            if ( attributeType.getEquality() != null )
666            {
667                registries.delReference( attributeType, attributeType.getEquality() );
668            }
669
670            if ( attributeType.getOrdering() != null )
671            {
672                registries.delReference( attributeType, attributeType.getOrdering() );
673            }
674
675            if ( attributeType.getSubstring() != null )
676            {
677                registries.delReference( attributeType, attributeType.getSubstring() );
678            }
679
680            if ( attributeType.getSyntax() != null )
681            {
682                registries.delReference( attributeType, attributeType.getSyntax() );
683            }
684
685            if ( attributeType.getSuperior() != null )
686            {
687                registries.delReference( attributeType, attributeType.getSuperior() );
688            }
689        }
690    }
691}