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}