001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.core; 028 import org.opends.messages.Message; 029 030 031 032 import java.io.File; 033 import java.util.ArrayList; 034 import java.util.Arrays; 035 import java.util.LinkedList; 036 import java.util.List; 037 038 import org.opends.server.api.ConfigHandler; 039 import org.opends.server.config.ConfigException; 040 import org.opends.server.schema.AttributeTypeSyntax; 041 import org.opends.server.schema.DITContentRuleSyntax; 042 import org.opends.server.schema.DITStructureRuleSyntax; 043 import org.opends.server.schema.MatchingRuleUseSyntax; 044 import org.opends.server.schema.NameFormSyntax; 045 import org.opends.server.schema.ObjectClassSyntax; 046 import org.opends.server.types.Attribute; 047 import org.opends.server.types.AttributeType; 048 import org.opends.server.types.AttributeValue; 049 import org.opends.server.types.DirectoryException; 050 import org.opends.server.types.DITContentRule; 051 import org.opends.server.types.DITStructureRule; 052 import org.opends.server.types.Entry; 053 import org.opends.server.types.InitializationException; 054 import org.opends.server.types.LDIFImportConfig; 055 import org.opends.server.types.MatchingRuleUse; 056 import org.opends.server.types.Modification; 057 import org.opends.server.types.ModificationType; 058 import org.opends.server.types.NameForm; 059 import org.opends.server.types.ObjectClass; 060 import org.opends.server.types.Schema; 061 import org.opends.server.util.LDIFReader; 062 063 import static org.opends.server.config.ConfigConstants.*; 064 import org.opends.server.types.DebugLogLevel; 065 import static org.opends.server.loggers.debug.DebugLogger.*; 066 import static org.opends.server.loggers.ErrorLogger.*; 067 import org.opends.server.loggers.debug.DebugTracer; 068 import static org.opends.messages.ConfigMessages.*; 069 import static org.opends.server.schema.SchemaConstants.*; 070 import static org.opends.server.util.ServerConstants.*; 071 import static org.opends.server.util.StaticUtils.*; 072 073 074 075 /** 076 * This class defines a utility that will be used to manage the interaction with 077 * the Directory Server schema. It will be used to initially load all of the 078 * matching rules and attribute syntaxes that have been defined in the 079 * configuration, and will then read the actual schema definitions. At present, 080 * only attribute types and objectclasses are supported in the schema config 081 * files. Other components like DIT content rules, DIT structure rules, name 082 * forms, and matching rule use definitions will be ignored. 083 */ 084 public class SchemaConfigManager 085 { 086 /** 087 * The tracer object for the debug logger. 088 */ 089 private static final DebugTracer TRACER = getTracer(); 090 091 // The schema that has been parsed from the server configuration. 092 private Schema schema; 093 094 // The configuration handler for the Directory Server. 095 private ConfigHandler configHandler; 096 097 098 099 /** 100 * Creates a new instance of this schema config manager. 101 */ 102 public SchemaConfigManager() 103 { 104 configHandler = DirectoryServer.getConfigHandler(); 105 106 schema = new Schema(); 107 } 108 109 110 111 /** 112 * Retrieves the path to the directory containing the server schema files. 113 * 114 * @return The path to the directory containing the server schema files. 115 */ 116 public static String getSchemaDirectoryPath() 117 { 118 File schemaDir = 119 DirectoryServer.getEnvironmentConfig().getSchemaDirectory(); 120 if (schemaDir != null) { 121 return schemaDir.getAbsolutePath(); 122 } else { 123 return null; 124 } 125 } 126 127 128 129 /** 130 * Retrieves a reference to the schema information that has been read from the 131 * server configuration. Note that this information will not be complete 132 * until the <CODE>initializeMatchingRules</CODE>, 133 * <CODE>initializeAttributeSyntaxes</CODE>, and 134 * <CODE>initializeAttributeTypesAndObjectClasses</CODE> methods have been 135 * called. 136 * 137 * @return A reference to the schema information that has been read from the 138 * server configuration. 139 */ 140 public Schema getSchema() 141 { 142 return schema; 143 } 144 145 146 147 /** 148 * Initializes all the matching rules defined in the Directory Server 149 * configuration. This should only be called at Directory Server startup. 150 * 151 * @throws ConfigException If a configuration problem causes the matching 152 * rule initialization process to fail. 153 * 154 * @throws InitializationException If a problem occurs while initializing 155 * the matching rules that is not related to 156 * the server configuration. 157 */ 158 public void initializeMatchingRules() 159 throws ConfigException, InitializationException 160 { 161 MatchingRuleConfigManager matchingRuleConfigManager = 162 new MatchingRuleConfigManager(); 163 matchingRuleConfigManager.initializeMatchingRules(); 164 } 165 166 167 168 /** 169 * Initializes all the attribute syntaxes defined in the Directory Server 170 * configuration. This should only be called at Directory Server startup. 171 * 172 * @throws ConfigException If a configuration problem causes the syntax 173 * initialization process to fail. 174 * 175 * @throws InitializationException If a problem occurs while initializing 176 * the syntaxes that is not related to the 177 * server configuration. 178 */ 179 public void initializeAttributeSyntaxes() 180 throws ConfigException, InitializationException 181 { 182 AttributeSyntaxConfigManager syntaxConfigManager = 183 new AttributeSyntaxConfigManager(); 184 syntaxConfigManager.initializeAttributeSyntaxes(); 185 } 186 187 188 189 /** 190 * Initializes all the attribute type, object class, name form, DIT content 191 * rule, DIT structure rule, and matching rule use definitions by reading the 192 * server schema files. These files will be located in a single directory and 193 * will be processed in lexicographic order. However, to make the order 194 * easier to understand, they may be prefixed with a two digit number (with a 195 * leading zero if necessary) so that they will be read in numeric order. 196 * This should only be called at Directory Server startup. 197 * 198 * @throws ConfigException If a configuration problem causes the schema 199 * element initialization to fail. 200 * 201 * @throws InitializationException If a problem occurs while initializing 202 * the schema elements that is not related 203 * to the server configuration. 204 */ 205 public void initializeSchemaFromFiles() 206 throws ConfigException, InitializationException 207 { 208 // Construct the path to the directory that should contain the schema files 209 // and make sure that it exists and is a directory. Get a list of the files 210 // in that directory sorted in alphabetic order. 211 String schemaDirPath = getSchemaDirectoryPath(); 212 File schemaDir = new File(schemaDirPath); 213 long oldestModificationTime = -1L; 214 long youngestModificationTime = -1L; 215 String[] fileNames; 216 217 try 218 { 219 if (schemaDirPath == null || ! schemaDir.exists()) 220 { 221 Message message = ERR_CONFIG_SCHEMA_NO_SCHEMA_DIR.get(schemaDirPath); 222 throw new InitializationException(message); 223 } 224 else if (! schemaDir.isDirectory()) 225 { 226 Message message = 227 ERR_CONFIG_SCHEMA_DIR_NOT_DIRECTORY.get(schemaDirPath); 228 throw new InitializationException(message); 229 } 230 231 File[] schemaDirFiles = schemaDir.listFiles(); 232 ArrayList<String> fileList = new ArrayList<String>(schemaDirFiles.length); 233 for (File f : schemaDirFiles) 234 { 235 if (f.isFile()) 236 { 237 fileList.add(f.getName()); 238 } 239 240 long modificationTime = f.lastModified(); 241 if ((oldestModificationTime <= 0L) || 242 (modificationTime < oldestModificationTime)) 243 { 244 oldestModificationTime = modificationTime; 245 } 246 247 if ((youngestModificationTime <= 0) || 248 (modificationTime > youngestModificationTime)) 249 { 250 youngestModificationTime = modificationTime; 251 } 252 } 253 254 fileNames = new String[fileList.size()]; 255 fileList.toArray(fileNames); 256 Arrays.sort(fileNames); 257 } 258 catch (InitializationException ie) 259 { 260 if (debugEnabled()) 261 { 262 TRACER.debugCaught(DebugLogLevel.ERROR, ie); 263 } 264 265 throw ie; 266 } 267 catch (Exception e) 268 { 269 if (debugEnabled()) 270 { 271 TRACER.debugCaught(DebugLogLevel.ERROR, e); 272 } 273 274 Message message = ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES.get( 275 schemaDirPath, getExceptionMessage(e)); 276 throw new InitializationException(message, e); 277 } 278 279 280 // If the oldest and youngest modification timestamps didn't get set for 281 // some reason, then set them to the current time. 282 if (oldestModificationTime <= 0) 283 { 284 oldestModificationTime = System.currentTimeMillis(); 285 } 286 287 if (youngestModificationTime <= 0) 288 { 289 youngestModificationTime = oldestModificationTime; 290 } 291 292 schema.setOldestModificationTime(oldestModificationTime); 293 schema.setYoungestModificationTime(youngestModificationTime); 294 295 296 // Iterate through the schema files and read them as an LDIF file containing 297 // a single entry. Then get the attributeTypes and objectClasses attributes 298 // from that entry and parse them to initialize the server schema. 299 for (String schemaFile : fileNames) 300 { 301 loadSchemaFile(schema, schemaFile, false); 302 } 303 } 304 305 306 307 /** 308 * Loads the contents of the specified schema file into the provided schema. 309 * 310 * @param schema The schema in which the contents of the schema file are 311 * to be loaded. 312 * @param schemaFile The name of the schema file to be loaded into the 313 * provided schema. 314 * 315 * @return A list of the modifications that could be performed in order to 316 * obtain the contents of the file. 317 * 318 * @throws ConfigException If a configuration problem causes the schema 319 * element initialization to fail. 320 * 321 * @throws InitializationException If a problem occurs while initializing 322 * the schema elements that is not related 323 * to the server configuration. 324 */ 325 public static List<Modification> loadSchemaFile(Schema schema, 326 String schemaFile) 327 throws ConfigException, InitializationException 328 { 329 return loadSchemaFile(schema, schemaFile, true); 330 } 331 332 333 334 /** 335 * Loads the contents of the specified schema file into the provided schema. 336 * 337 * @param schema The schema in which the contents of the schema file 338 * are to be loaded. 339 * @param schemaFile The name of the schema file to be loaded into the 340 * provided schema. 341 * @param failOnError If {@code true}, indicates that this method should 342 * throw an exception if certain kinds of errors occur. 343 * If {@code false}, indicates that this method should 344 * log an error message and return without an exception. 345 * This should only be {@code false} when called from 346 * {@code initializeSchemaFromFiles}. 347 * 348 * @return A list of the modifications that could be performed in order to 349 * obtain the contents of the file, or {@code null} if a problem 350 * occurred and {@code failOnError} is {@code false}. 351 * 352 * @throws ConfigException If a configuration problem causes the schema 353 * element initialization to fail. 354 * 355 * @throws InitializationException If a problem occurs while initializing 356 * the schema elements that is not related 357 * to the server configuration. 358 */ 359 private static List<Modification> loadSchemaFile(Schema schema, 360 String schemaFile, 361 boolean failOnError) 362 throws ConfigException, InitializationException 363 { 364 // Create an LDIF reader to use when reading the files. 365 String schemaDirPath = getSchemaDirectoryPath(); 366 LDIFReader reader; 367 try 368 { 369 File f = new File(schemaDirPath, schemaFile); 370 reader = new LDIFReader(new LDIFImportConfig(f.getAbsolutePath())); 371 } 372 catch (Exception e) 373 { 374 if (debugEnabled()) 375 { 376 TRACER.debugCaught(DebugLogLevel.ERROR, e); 377 } 378 379 Message message = WARN_CONFIG_SCHEMA_CANNOT_OPEN_FILE.get( 380 schemaFile, schemaDirPath, getExceptionMessage(e)); 381 382 if (failOnError) 383 { 384 throw new ConfigException(message); 385 } 386 else 387 { 388 logError(message); 389 return null; 390 } 391 } 392 393 394 // Read the LDIF entry from the file and close the file. 395 Entry entry; 396 try 397 { 398 entry = reader.readEntry(false); 399 400 if (entry == null) 401 { 402 // The file was empty -- skip it. 403 reader.close(); 404 return new LinkedList<Modification>(); 405 } 406 } 407 catch (Exception e) 408 { 409 if (debugEnabled()) 410 { 411 TRACER.debugCaught(DebugLogLevel.ERROR, e); 412 } 413 414 Message message = WARN_CONFIG_SCHEMA_CANNOT_READ_LDIF_ENTRY.get( 415 schemaFile, schemaDirPath, getExceptionMessage(e)); 416 417 if (failOnError) 418 { 419 throw new InitializationException(message, e); 420 } 421 else 422 { 423 logError(message); 424 return null; 425 } 426 } 427 428 // If there are any more entries in the file, then print a warning message. 429 try 430 { 431 Entry e = reader.readEntry(false); 432 if (e != null) 433 { 434 Message message = WARN_CONFIG_SCHEMA_MULTIPLE_ENTRIES_IN_FILE.get( 435 schemaFile, schemaDirPath); 436 logError(message); 437 } 438 } 439 catch (Exception e) 440 { 441 if (debugEnabled()) 442 { 443 TRACER.debugCaught(DebugLogLevel.ERROR, e); 444 } 445 446 Message message = WARN_CONFIG_SCHEMA_UNPARSEABLE_EXTRA_DATA_IN_FILE.get( 447 schemaFile, schemaDirPath, getExceptionMessage(e)); 448 logError(message); 449 } 450 451 try 452 { 453 reader.close(); 454 } 455 catch (Exception e) 456 { 457 if (debugEnabled()) 458 { 459 TRACER.debugCaught(DebugLogLevel.ERROR, e); 460 } 461 } 462 463 464 // Get the attributeTypes attribute from the entry. 465 LinkedList<Modification> mods = new LinkedList<Modification>(); 466 AttributeTypeSyntax attrTypeSyntax; 467 try 468 { 469 attrTypeSyntax = (AttributeTypeSyntax) 470 schema.getSyntax(SYNTAX_ATTRIBUTE_TYPE_OID); 471 if (attrTypeSyntax == null) 472 { 473 attrTypeSyntax = new AttributeTypeSyntax(); 474 attrTypeSyntax.initializeSyntax(null); 475 } 476 } 477 catch (Exception e) 478 { 479 if (debugEnabled()) 480 { 481 TRACER.debugCaught(DebugLogLevel.ERROR, e); 482 } 483 484 attrTypeSyntax = new AttributeTypeSyntax(); 485 attrTypeSyntax.initializeSyntax(null); 486 } 487 488 AttributeType attributeAttrType = 489 schema.getAttributeType(ATTR_ATTRIBUTE_TYPES_LC); 490 if (attributeAttrType == null) 491 { 492 attributeAttrType = 493 DirectoryServer.getDefaultAttributeType(ATTR_ATTRIBUTE_TYPES, 494 attrTypeSyntax); 495 } 496 497 List<Attribute> attrList = entry.getAttribute(attributeAttrType); 498 if ((attrList != null) && (! attrList.isEmpty())) 499 { 500 for (Attribute a : attrList) 501 { 502 mods.add(new Modification(ModificationType.ADD, a.duplicate())); 503 } 504 } 505 506 507 // Get the objectClasses attribute from the entry. 508 ObjectClassSyntax ocSyntax; 509 try 510 { 511 ocSyntax = (ObjectClassSyntax) schema.getSyntax(SYNTAX_OBJECTCLASS_OID); 512 if (ocSyntax == null) 513 { 514 ocSyntax = new ObjectClassSyntax(); 515 ocSyntax.initializeSyntax(null); 516 } 517 } 518 catch (Exception e) 519 { 520 if (debugEnabled()) 521 { 522 TRACER.debugCaught(DebugLogLevel.ERROR, e); 523 } 524 525 ocSyntax = new ObjectClassSyntax(); 526 ocSyntax.initializeSyntax(null); 527 } 528 529 AttributeType objectclassAttrType = 530 schema.getAttributeType(ATTR_OBJECTCLASSES_LC); 531 if (objectclassAttrType == null) 532 { 533 objectclassAttrType = 534 DirectoryServer.getDefaultAttributeType(ATTR_OBJECTCLASSES, 535 ocSyntax); 536 } 537 538 List<Attribute> ocList = entry.getAttribute(objectclassAttrType); 539 if ((ocList != null) && (! ocList.isEmpty())) 540 { 541 for (Attribute a : ocList) 542 { 543 mods.add(new Modification(ModificationType.ADD, a.duplicate())); 544 } 545 } 546 547 548 // Get the name forms attribute from the entry. 549 NameFormSyntax nfSyntax; 550 try 551 { 552 nfSyntax = (NameFormSyntax) schema.getSyntax(SYNTAX_NAME_FORM_OID); 553 if (nfSyntax == null) 554 { 555 nfSyntax = new NameFormSyntax(); 556 nfSyntax.initializeSyntax(null); 557 } 558 } 559 catch (Exception e) 560 { 561 if (debugEnabled()) 562 { 563 TRACER.debugCaught(DebugLogLevel.ERROR, e); 564 } 565 566 nfSyntax = new NameFormSyntax(); 567 nfSyntax.initializeSyntax(null); 568 } 569 570 AttributeType nameFormAttrType = 571 schema.getAttributeType(ATTR_NAME_FORMS_LC); 572 if (nameFormAttrType == null) 573 { 574 nameFormAttrType = 575 DirectoryServer.getDefaultAttributeType(ATTR_NAME_FORMS, nfSyntax); 576 } 577 578 List<Attribute> nfList = entry.getAttribute(nameFormAttrType); 579 if ((nfList != null) && (! nfList.isEmpty())) 580 { 581 for (Attribute a : nfList) 582 { 583 mods.add(new Modification(ModificationType.ADD, a.duplicate())); 584 } 585 } 586 587 588 // Get the DIT content rules attribute from the entry. 589 DITContentRuleSyntax dcrSyntax; 590 try 591 { 592 dcrSyntax = (DITContentRuleSyntax) 593 schema.getSyntax(SYNTAX_DIT_CONTENT_RULE_OID); 594 if (dcrSyntax == null) 595 { 596 dcrSyntax = new DITContentRuleSyntax(); 597 dcrSyntax.initializeSyntax(null); 598 } 599 } 600 catch (Exception e) 601 { 602 if (debugEnabled()) 603 { 604 TRACER.debugCaught(DebugLogLevel.ERROR, e); 605 } 606 607 dcrSyntax = new DITContentRuleSyntax(); 608 dcrSyntax.initializeSyntax(null); 609 } 610 611 AttributeType dcrAttrType = 612 schema.getAttributeType(ATTR_DIT_CONTENT_RULES_LC); 613 if (dcrAttrType == null) 614 { 615 dcrAttrType = 616 DirectoryServer.getDefaultAttributeType(ATTR_DIT_CONTENT_RULES, 617 dcrSyntax); 618 } 619 620 List<Attribute> dcrList = entry.getAttribute(dcrAttrType); 621 if ((dcrList != null) && (! dcrList.isEmpty())) 622 { 623 for (Attribute a : dcrList) 624 { 625 mods.add(new Modification(ModificationType.ADD, a.duplicate())); 626 } 627 } 628 629 630 // Get the DIT structure rules attribute from the entry. 631 DITStructureRuleSyntax dsrSyntax; 632 try 633 { 634 dsrSyntax = (DITStructureRuleSyntax) 635 schema.getSyntax(SYNTAX_DIT_STRUCTURE_RULE_OID); 636 if (dsrSyntax == null) 637 { 638 dsrSyntax = new DITStructureRuleSyntax(); 639 dsrSyntax.initializeSyntax(null); 640 } 641 } 642 catch (Exception e) 643 { 644 if (debugEnabled()) 645 { 646 TRACER.debugCaught(DebugLogLevel.ERROR, e); 647 } 648 649 dsrSyntax = new DITStructureRuleSyntax(); 650 dsrSyntax.initializeSyntax(null); 651 } 652 653 AttributeType dsrAttrType = 654 schema.getAttributeType(ATTR_DIT_STRUCTURE_RULES_LC); 655 if (dsrAttrType == null) 656 { 657 dsrAttrType = 658 DirectoryServer.getDefaultAttributeType(ATTR_DIT_STRUCTURE_RULES, 659 dsrSyntax); 660 } 661 662 List<Attribute> dsrList = entry.getAttribute(dsrAttrType); 663 if ((dsrList != null) && (! dsrList.isEmpty())) 664 { 665 for (Attribute a : dsrList) 666 { 667 mods.add(new Modification(ModificationType.ADD, a.duplicate())); 668 } 669 } 670 671 672 // Get the matching rule uses attribute from the entry. 673 MatchingRuleUseSyntax mruSyntax; 674 try 675 { 676 mruSyntax = (MatchingRuleUseSyntax) 677 schema.getSyntax(SYNTAX_MATCHING_RULE_USE_OID); 678 if (mruSyntax == null) 679 { 680 mruSyntax = new MatchingRuleUseSyntax(); 681 mruSyntax.initializeSyntax(null); 682 } 683 } 684 catch (Exception e) 685 { 686 if (debugEnabled()) 687 { 688 TRACER.debugCaught(DebugLogLevel.ERROR, e); 689 } 690 691 mruSyntax = new MatchingRuleUseSyntax(); 692 mruSyntax.initializeSyntax(null); 693 } 694 695 AttributeType mruAttrType = 696 schema.getAttributeType(ATTR_MATCHING_RULE_USE_LC); 697 if (mruAttrType == null) 698 { 699 mruAttrType = 700 DirectoryServer.getDefaultAttributeType(ATTR_MATCHING_RULE_USE, 701 mruSyntax); 702 } 703 704 List<Attribute> mruList = entry.getAttribute(mruAttrType); 705 if ((mruList != null) && (! mruList.isEmpty())) 706 { 707 for (Attribute a : mruList) 708 { 709 mods.add(new Modification(ModificationType.ADD, a.duplicate())); 710 } 711 } 712 713 // Loop on all the attribute of the schema entry to 714 // find the extra attribute that shoule be loaded in the Schema. 715 for (Attribute attribute : entry.getAttributes()) 716 { 717 if (!isSchemaAttribute(attribute)) 718 { 719 schema.addExtraAttribute(attribute.getName(), attribute); 720 } 721 } 722 723 // Parse the attribute type definitions if there are any. 724 if (attrList != null) 725 { 726 for (Attribute a : attrList) 727 { 728 for (AttributeValue v : a.getValues()) 729 { 730 // Parse the attribute type. 731 AttributeType attrType; 732 try 733 { 734 attrType = AttributeTypeSyntax.decodeAttributeType(v.getValue(), 735 schema, false); 736 attrType.setExtraProperty(SCHEMA_PROPERTY_FILENAME, (String) null); 737 attrType.setSchemaFile(schemaFile); 738 } 739 catch (DirectoryException de) 740 { 741 if (debugEnabled()) 742 { 743 TRACER.debugCaught(DebugLogLevel.ERROR, de); 744 } 745 746 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_ATTR_TYPE.get( 747 schemaFile, de.getMessageObject()); 748 749 if (failOnError) 750 { 751 throw new ConfigException(message, de); 752 } 753 else 754 { 755 logError(message); 756 continue; 757 } 758 } 759 catch (Exception e) 760 { 761 if (debugEnabled()) 762 { 763 TRACER.debugCaught(DebugLogLevel.ERROR, e); 764 } 765 766 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_ATTR_TYPE.get( 767 schemaFile, v.getStringValue() + ": " + 768 getExceptionMessage(e)); 769 if (failOnError) 770 { 771 throw new ConfigException(message, e); 772 } 773 else 774 { 775 logError(message); 776 continue; 777 } 778 } 779 780 // Register it with the schema. We will allow duplicates, with the 781 // later definition overriding any earlier definition, but we want 782 // to trap them and log a warning. 783 try 784 { 785 schema.registerAttributeType(attrType, failOnError); 786 } 787 catch (DirectoryException de) 788 { 789 if (debugEnabled()) 790 { 791 TRACER.debugCaught(DebugLogLevel.ERROR, de); 792 } 793 794 Message message = WARN_CONFIG_SCHEMA_CONFLICTING_ATTR_TYPE.get( 795 schemaFile, de.getMessageObject()); 796 logError(message); 797 798 try 799 { 800 schema.registerAttributeType(attrType, true); 801 } 802 catch (Exception e) 803 { 804 // This should never happen. 805 if (debugEnabled()) 806 { 807 TRACER.debugCaught(DebugLogLevel.ERROR, e); 808 } 809 } 810 } 811 } 812 } 813 } 814 815 816 // Parse the objectclass definitions if there are any. 817 if (ocList != null) 818 { 819 for (Attribute a : ocList) 820 { 821 for (AttributeValue v : a.getValues()) 822 { 823 // Parse the objectclass. 824 ObjectClass oc; 825 try 826 { 827 oc = 828 ObjectClassSyntax.decodeObjectClass(v.getValue(), schema, false); 829 oc.setExtraProperty(SCHEMA_PROPERTY_FILENAME, (String) null); 830 oc.setSchemaFile(schemaFile); 831 } 832 catch (DirectoryException de) 833 { 834 if (debugEnabled()) 835 { 836 TRACER.debugCaught(DebugLogLevel.ERROR, de); 837 } 838 839 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_OC.get( 840 schemaFile, 841 de.getMessageObject()); 842 843 if (failOnError) 844 { 845 throw new ConfigException(message, de); 846 } 847 else 848 { 849 logError(message); 850 continue; 851 } 852 } 853 catch (Exception e) 854 { 855 if (debugEnabled()) 856 { 857 TRACER.debugCaught(DebugLogLevel.ERROR, e); 858 } 859 860 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_OC.get( 861 schemaFile, 862 v.getStringValue() + ": " + getExceptionMessage(e)); 863 864 if (failOnError) 865 { 866 throw new ConfigException(message, e); 867 } 868 else 869 { 870 logError(message); 871 continue; 872 } 873 } 874 875 // Register it with the schema. We will allow duplicates, with the 876 // later definition overriding any earlier definition, but we want 877 // to trap them and log a warning. 878 try 879 { 880 schema.registerObjectClass(oc, failOnError); 881 } 882 catch (DirectoryException de) 883 { 884 if (debugEnabled()) 885 { 886 TRACER.debugCaught(DebugLogLevel.ERROR, de); 887 } 888 889 Message message = WARN_CONFIG_SCHEMA_CONFLICTING_OC.get( 890 schemaFile, de.getMessageObject()); 891 logError(message); 892 893 try 894 { 895 schema.registerObjectClass(oc, true); 896 } 897 catch (Exception e) 898 { 899 // This should never happen. 900 if (debugEnabled()) 901 { 902 TRACER.debugCaught(DebugLogLevel.ERROR, e); 903 } 904 } 905 } 906 } 907 } 908 } 909 910 911 // Parse the name form definitions if there are any. 912 if (nfList != null) 913 { 914 for (Attribute a : nfList) 915 { 916 for (AttributeValue v : a.getValues()) 917 { 918 // Parse the name form. 919 NameForm nf; 920 try 921 { 922 nf = NameFormSyntax.decodeNameForm(v.getValue(), schema, false); 923 nf.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME); 924 nf.setSchemaFile(schemaFile); 925 } 926 catch (DirectoryException de) 927 { 928 if (debugEnabled()) 929 { 930 TRACER.debugCaught(DebugLogLevel.ERROR, de); 931 } 932 933 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_NAME_FORM.get( 934 schemaFile, de.getMessageObject()); 935 if (failOnError) 936 { 937 throw new ConfigException(message, de); 938 } 939 else 940 { 941 logError(message); 942 continue; 943 } 944 } 945 catch (Exception e) 946 { 947 if (debugEnabled()) 948 { 949 TRACER.debugCaught(DebugLogLevel.ERROR, e); 950 } 951 952 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_NAME_FORM.get( 953 schemaFile, v.getStringValue() + ": " + 954 getExceptionMessage(e)); 955 956 if (failOnError) 957 { 958 throw new ConfigException(message, e); 959 } 960 else 961 { 962 logError(message); 963 continue; 964 } 965 } 966 967 // Register it with the schema. We will allow duplicates, with the 968 // later definition overriding any earlier definition, but we want 969 // to trap them and log a warning. 970 try 971 { 972 schema.registerNameForm(nf, failOnError); 973 } 974 catch (DirectoryException de) 975 { 976 if (debugEnabled()) 977 { 978 TRACER.debugCaught(DebugLogLevel.ERROR, de); 979 } 980 981 Message message = WARN_CONFIG_SCHEMA_CONFLICTING_NAME_FORM.get( 982 schemaFile, de.getMessageObject()); 983 logError(message); 984 985 try 986 { 987 schema.registerNameForm(nf, true); 988 } 989 catch (Exception e) 990 { 991 // This should never happen. 992 if (debugEnabled()) 993 { 994 TRACER.debugCaught(DebugLogLevel.ERROR, e); 995 } 996 } 997 } 998 } 999 } 1000 } 1001 1002 1003 // Parse the DIT content rule definitions if there are any. 1004 if (dcrList != null) 1005 { 1006 for (Attribute a : dcrList) 1007 { 1008 for (AttributeValue v : a.getValues()) 1009 { 1010 // Parse the DIT content rule. 1011 DITContentRule dcr; 1012 try 1013 { 1014 dcr = DITContentRuleSyntax.decodeDITContentRule( 1015 v.getValue(), schema, false); 1016 dcr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME); 1017 dcr.setSchemaFile(schemaFile); 1018 } 1019 catch (DirectoryException de) 1020 { 1021 if (debugEnabled()) 1022 { 1023 TRACER.debugCaught(DebugLogLevel.ERROR, de); 1024 } 1025 1026 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_DCR.get( 1027 schemaFile, de.getMessageObject()); 1028 1029 if (failOnError) 1030 { 1031 throw new ConfigException(message, de); 1032 } 1033 else 1034 { 1035 logError(message); 1036 continue; 1037 } 1038 } 1039 catch (Exception e) 1040 { 1041 if (debugEnabled()) 1042 { 1043 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1044 } 1045 1046 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_DCR.get( 1047 schemaFile,v.getStringValue() + ": " + 1048 getExceptionMessage(e)); 1049 1050 if (failOnError) 1051 { 1052 throw new ConfigException(message, e); 1053 } 1054 else 1055 { 1056 logError(message); 1057 continue; 1058 } 1059 } 1060 1061 // Register it with the schema. We will allow duplicates, with the 1062 // later definition overriding any earlier definition, but we want 1063 // to trap them and log a warning. 1064 try 1065 { 1066 schema.registerDITContentRule(dcr, failOnError); 1067 } 1068 catch (DirectoryException de) 1069 { 1070 if (debugEnabled()) 1071 { 1072 TRACER.debugCaught(DebugLogLevel.ERROR, de); 1073 } 1074 1075 Message message = WARN_CONFIG_SCHEMA_CONFLICTING_DCR.get( 1076 schemaFile, de.getMessageObject()); 1077 logError(message); 1078 1079 try 1080 { 1081 schema.registerDITContentRule(dcr, true); 1082 } 1083 catch (Exception e) 1084 { 1085 // This should never happen. 1086 if (debugEnabled()) 1087 { 1088 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1089 } 1090 } 1091 } 1092 } 1093 } 1094 } 1095 1096 1097 // Parse the DIT structure rule definitions if there are any. 1098 if (dsrList != null) 1099 { 1100 for (Attribute a : dsrList) 1101 { 1102 for (AttributeValue v : a.getValues()) 1103 { 1104 // Parse the DIT content rule. 1105 DITStructureRule dsr; 1106 try 1107 { 1108 dsr = DITStructureRuleSyntax.decodeDITStructureRule( 1109 v.getValue(), schema, false); 1110 dsr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME); 1111 dsr.setSchemaFile(schemaFile); 1112 } 1113 catch (DirectoryException de) 1114 { 1115 if (debugEnabled()) 1116 { 1117 TRACER.debugCaught(DebugLogLevel.ERROR, de); 1118 } 1119 1120 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_DSR.get( 1121 schemaFile, de.getMessageObject()); 1122 1123 if (failOnError) 1124 { 1125 throw new ConfigException(message, de); 1126 } 1127 else 1128 { 1129 logError(message); 1130 continue; 1131 } 1132 } 1133 catch (Exception e) 1134 { 1135 if (debugEnabled()) 1136 { 1137 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1138 } 1139 1140 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_DSR.get( 1141 schemaFile, v.getStringValue() + ": " + 1142 getExceptionMessage(e)); 1143 1144 if (failOnError) 1145 { 1146 throw new ConfigException(message, e); 1147 } 1148 else 1149 { 1150 logError(message); 1151 continue; 1152 } 1153 } 1154 1155 // Register it with the schema. We will allow duplicates, with the 1156 // later definition overriding any earlier definition, but we want 1157 // to trap them and log a warning. 1158 try 1159 { 1160 schema.registerDITStructureRule(dsr, failOnError); 1161 } 1162 catch (DirectoryException de) 1163 { 1164 if (debugEnabled()) 1165 { 1166 TRACER.debugCaught(DebugLogLevel.ERROR, de); 1167 } 1168 1169 Message message = WARN_CONFIG_SCHEMA_CONFLICTING_DSR.get( 1170 schemaFile, de.getMessageObject()); 1171 logError(message); 1172 1173 try 1174 { 1175 schema.registerDITStructureRule(dsr, true); 1176 } 1177 catch (Exception e) 1178 { 1179 // This should never happen. 1180 if (debugEnabled()) 1181 { 1182 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1183 } 1184 } 1185 } 1186 } 1187 } 1188 } 1189 1190 1191 // Parse the matching rule use definitions if there are any. 1192 if (mruList != null) 1193 { 1194 for (Attribute a : mruList) 1195 { 1196 for (AttributeValue v : a.getValues()) 1197 { 1198 // Parse the matching rule use definition. 1199 MatchingRuleUse mru; 1200 try 1201 { 1202 mru = MatchingRuleUseSyntax.decodeMatchingRuleUse( 1203 v.getValue(), schema, false); 1204 mru.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME); 1205 mru.setSchemaFile(schemaFile); 1206 } 1207 catch (DirectoryException de) 1208 { 1209 if (debugEnabled()) 1210 { 1211 TRACER.debugCaught(DebugLogLevel.ERROR, de); 1212 } 1213 1214 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_MRU.get( 1215 schemaFile, de.getMessageObject()); 1216 1217 if (failOnError) 1218 { 1219 throw new ConfigException(message, de); 1220 } 1221 else 1222 { 1223 logError(message); 1224 continue; 1225 } 1226 } 1227 catch (Exception e) 1228 { 1229 if (debugEnabled()) 1230 { 1231 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1232 } 1233 1234 Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_MRU.get( 1235 schemaFile, 1236 v.getStringValue() + ": " + 1237 getExceptionMessage(e)); 1238 1239 if (failOnError) 1240 { 1241 throw new ConfigException(message, e); 1242 } 1243 else 1244 { 1245 logError(message); 1246 continue; 1247 } 1248 } 1249 1250 // Register it with the schema. We will allow duplicates, with the 1251 // later definition overriding any earlier definition, but we want 1252 // to trap them and log a warning. 1253 try 1254 { 1255 schema.registerMatchingRuleUse(mru, failOnError); 1256 } 1257 catch (DirectoryException de) 1258 { 1259 if (debugEnabled()) 1260 { 1261 TRACER.debugCaught(DebugLogLevel.ERROR, de); 1262 } 1263 1264 Message message = WARN_CONFIG_SCHEMA_CONFLICTING_MRU.get( 1265 schemaFile, de.getMessageObject()); 1266 logError(message); 1267 1268 try 1269 { 1270 schema.registerMatchingRuleUse(mru, true); 1271 } 1272 catch (Exception e) 1273 { 1274 // This should never happen. 1275 if (debugEnabled()) 1276 { 1277 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1278 } 1279 } 1280 } 1281 } 1282 } 1283 } 1284 1285 1286 return mods; 1287 } 1288 1289 1290 1291 /** 1292 * This method checks if a given attribute is an attribute that 1293 * is used by the definition of the schema. 1294 * 1295 * @param attribute The attribute to be checked. 1296 * @return true if the attribute is part of the schema definition, 1297 * false if the attribute is not part of the schema 1298 * definition. 1299 */ 1300 private static boolean isSchemaAttribute(Attribute attribute) 1301 { 1302 String attributeOid = attribute.getAttributeType().getOID(); 1303 if (attributeOid.equals("2.5.21.1") || 1304 attributeOid.equals("2.5.21.2") || 1305 attributeOid.equals("2.5.21.4") || 1306 attributeOid.equals("2.5.21.5") || 1307 attributeOid.equals("2.5.21.6") || 1308 attributeOid.equals("2.5.21.7") || 1309 attributeOid.equals("2.5.21.8") || 1310 attributeOid.equals("2.5.4.3") || 1311 attributeOid.equals("attributetypes-oid") || 1312 attributeOid.equals("objectclasses-oid") || 1313 attributeOid.equals("matchingRules-oid") || 1314 attributeOid.equals("matchingRuleUse-oid") || 1315 attributeOid.equals("NameFormDescription-oid") || 1316 attributeOid.equals("dITContentRules-oid") || 1317 attributeOid.equals("dITStructureRules") 1318 ) 1319 { 1320 return true; 1321 } 1322 else 1323 { 1324 return false; 1325 } 1326 } 1327 } 1328