From f386801829fe0295a232ad8af4785ba60d2be044 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Tue, 30 Jan 2007 16:11:11 +0000
Subject: [PATCH] Add a new task that may be used to cause the server to load the contents of a new file into the schema without the need to restart.

---
 opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java                                | 1266 ++++++++++++++++++++---------------
 opendj-sdk/opends/src/server/org/opends/server/messages/TaskMessages.java                                   |   83 ++
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/AddSchemaFileTaskTestCase.java |  482 +++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java                               |   37 +
 opendj-sdk/opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java                                 |  238 ++++++
 opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java                                  |    6 
 opendj-sdk/opends/resource/schema/02-config.ldif                                                            |    6 
 7 files changed, 1,569 insertions(+), 549 deletions(-)

diff --git a/opendj-sdk/opends/resource/schema/02-config.ldif b/opendj-sdk/opends/resource/schema/02-config.ldif
index 4c3a840..5da40a7 100644
--- a/opendj-sdk/opends/resource/schema/02-config.ldif
+++ b/opendj-sdk/opends/resource/schema/02-config.ldif
@@ -1028,6 +1028,9 @@
 attributeTypes: ( 1.3.6.1.4.1.26027.1.1.301
   NAME 'ds-cfg-reject-unauthenticated-requests' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
   SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.302
+  NAME 'ds-task-schema-file-name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  X-ORIGIN 'OpenDS Directory Server' )
 objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
   NAME 'ds-cfg-access-control-handler' SUP top STRUCTURAL
   MUST ( cn $ ds-cfg-acl-handler-class $ ds-cfg-acl-handler-enabled )
@@ -1409,4 +1412,7 @@
   MAY ( ds-connectionhandler-connection $ ds-connectionhandler-listener $
   ds-connectionhandler-num-connections $ ds-connectionhandler-protocol )
   X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.80 NAME 'ds-task-add-schema-file'
+  SUP ds-task MUST ds-task-schema-file-name
+  X-ORIGIN 'OpenDS Directory Server' )
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index d8bfc1e..a486838 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -1693,5 +1693,42 @@
 
     return scheduledTaskParentDN;
   }
+
+
+
+  /**
+   * Retrieves the scheduled task for the entry with the provided DN.
+   *
+   * @param  taskEntryDN  The DN of the entry for the task to retrieve.
+   *
+   * @return  The requested task, or {@code null} if there is no task with the
+   *          specified entry DN.
+   */
+  public Task getScheduledTask(DN taskEntryDN)
+  {
+    assert debugEnter(CLASS_NAME, "getScheduledTask",
+                      String.valueOf(taskEntryDN));
+
+    return taskScheduler.getScheduledTask(taskEntryDN);
+  }
+
+
+
+  /**
+   * Retrieves the recurring task for the entry with the provided DN.
+   *
+   * @param  taskEntryDN  The DN of the entry for the recurring task to
+   *                      retrieve.
+   *
+   * @return  The requested recurring task, or {@code null} if there is no task
+   *          with the specified entry DN.
+   */
+  public RecurringTask getRecurringTask(DN taskEntryDN)
+  {
+    assert debugEnter(CLASS_NAME, "getScheduledTask",
+                      String.valueOf(taskEntryDN));
+
+    return taskScheduler.getRecurringTask(taskEntryDN);
+  }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java b/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
index 5890265..28656a5 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
@@ -3730,5 +3730,11 @@
 
 
 
+  /**
+   * The name of the attribute in the add schema file task definition that
+   * specifies the name of the schema file to be added.
+   */
+  public static final String ATTR_TASK_ADDSCHEMAFILE_FILENAME =
+       NAME_PREFIX_TASK + "schema-file-name";
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java b/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
index d20ce16..7aaca38 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -623,19 +623,20 @@
 
 
   /**
-   * Initializes all the attribute type and objectclass definitions by reading
-   * the server schema files.  These files will be located in a single directory
-   * and will be processed in alphabetic order.  However, to make the order
+   * Initializes all the attribute type, object class, name form, DIT content
+   * rule, DIT structure rule, and matching rule use definitions by reading the
+   * server schema files.  These files will be located in a single directory and
+   * will be processed in lexicographic order.  However, to make the order
    * easier to understand, they may be prefixed with a two digit number (with a
    * leading zero if necessary) so that they will be read in numeric order.
    * This should only be called at Directory Server startup.
    *
-   * @throws  ConfigException  If a configuration problem causes the attribute
-   *                           type or objectclass initialization to fail.
+   * @throws  ConfigException  If a configuration problem causes the schema
+   *                           element initialization to fail.
    *
    * @throws  InitializationException  If a problem occurs while initializing
-   *                                   the attribute types/objectclasses that is
-   *                                   not related to the server configuration.
+   *                                   the schema elements that is not related
+   *                                   to the server configuration.
    */
   public void initializeSchemaFromFiles()
          throws ConfigException, InitializationException
@@ -673,7 +674,7 @@
       {
         if (f.isFile())
         {
-          fileList.add(f.getAbsolutePath());
+          fileList.add(f.getName());
         }
 
         long modificationTime = f.lastModified();
@@ -732,685 +733,858 @@
     // from that entry and parse them to initialize the server schema.
     for (String schemaFile : fileNames)
     {
-      // Create an LDIF reader to use when reading the files.
-      LDIFReader reader;
-      try
-      {
-        reader = new LDIFReader(new LDIFImportConfig(schemaFile));
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+      loadSchemaFile(schema, schemaFile, false);
+    }
+  }
 
-        int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_OPEN_FILE;
-        String message = getMessage(msgID, schemaFile, schemaDirPath,
-                                    stackTraceToSingleLineString(e));
+
+
+  /**
+   * Loads the contents of the specified schema file into the provided schema.
+   *
+   * @param  schema      The schema in which the contents of the schema file are
+   *                     to be loaded.
+   * @param  schemaFile  The name of the schema file to be loaded into the
+   *                     provided schema.
+   *
+   * @throws  ConfigException  If a configuration problem causes the schema
+   *                           element initialization to fail.
+   *
+   * @throws  InitializationException  If a problem occurs while initializing
+   *                                   the schema elements that is not related
+   *                                   to the server configuration.
+   */
+  public static void loadSchemaFile(Schema schema, String schemaFile)
+         throws ConfigException, InitializationException
+  {
+    assert debugEnter(CLASS_NAME, "loadSchemaFile", String.valueOf(schema),
+                      String.valueOf(schemaFile));
+
+    loadSchemaFile(schema, schemaFile, true);
+  }
+
+
+
+  /**
+   * Loads the contents of the specified schema file into the provided schema.
+   *
+   * @param  schema       The schema in which the contents of the schema file
+   *                      are to be loaded.
+   * @param  schemaFile   The name of the schema file to be loaded into the
+   *                      provided schema.
+   * @param  failOnError  If {@code true}, indicates that this method should
+   *                      throw an exception if certain kinds of errors occur.
+   *                      If {@code false}, indicates that this method should
+   *                      log an error message and return without an exception.
+   *                      This should only be {@code false} when called from
+   *                      {@code initializeSchemaFromFiles}.
+   *
+   * @throws  ConfigException  If a configuration problem causes the schema
+   *                           element initialization to fail.
+   *
+   * @throws  InitializationException  If a problem occurs while initializing
+   *                                   the schema elements that is not related
+   *                                   to the server configuration.
+   */
+  private static void loadSchemaFile(Schema schema, String schemaFile,
+                                     boolean failOnError)
+         throws ConfigException, InitializationException
+  {
+    assert debugEnter(CLASS_NAME, "loadSchemaFile", String.valueOf(schema),
+                      String.valueOf(schemaFile), String.valueOf(failOnError));
+
+
+    // Create an LDIF reader to use when reading the files.
+    String schemaDirPath = getSchemaDirectoryPath();
+    LDIFReader reader;
+    try
+    {
+      File f = new File(schemaDirPath, schemaFile);
+      reader = new LDIFReader(new LDIFImportConfig(f.getAbsolutePath()));
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+      int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_OPEN_FILE;
+      String message = getMessage(msgID, schemaFile, schemaDirPath,
+                                  stackTraceToSingleLineString(e));
+
+      if (failOnError)
+      {
+        throw new ConfigException(msgID, message);
+      }
+      else
+      {
         logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
                  message, msgID);
-        continue;
+        return;
       }
+    }
 
 
-      // Read the LDIF entry from the file and close the file.
-      Entry entry;
-      try
+    // Read the LDIF entry from the file and close the file.
+    Entry entry;
+    try
+    {
+      entry = reader.readEntry(false);
+
+      if (entry == null)
       {
-        entry = reader.readEntry(false);
-
-        if (entry == null)
-        {
-          // The file was empty -- skip it.
-          continue;
-        }
+        // The file was empty -- skip it.
+        return;
       }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-        int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_READ_LDIF_ENTRY;
-        String message = getMessage(msgID, schemaFile, schemaDirPath,
-                                    stackTraceToSingleLineString(e));
+      int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_READ_LDIF_ENTRY;
+      String message = getMessage(msgID, schemaFile, schemaDirPath,
+                                  stackTraceToSingleLineString(e));
+
+      if (failOnError)
+      {
+        throw new InitializationException(msgID, message, e);
+      }
+      else
+      {
         logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
                  message, msgID);
-        continue;
+        return;
       }
+    }
 
-      try
-      {
-        reader.close();
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-      }
+    try
+    {
+      reader.close();
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+    }
 
 
-      // Get the attributeTypes attribute from the entry.
-      AttributeTypeSyntax attrTypeSyntax;
-      try
+    // Get the attributeTypes attribute from the entry.
+    AttributeTypeSyntax attrTypeSyntax;
+    try
+    {
+      attrTypeSyntax = (AttributeTypeSyntax)
+                       schema.getSyntax(SYNTAX_ATTRIBUTE_TYPE_OID);
+      if (attrTypeSyntax == null)
       {
-        attrTypeSyntax = (AttributeTypeSyntax)
-                         schema.getSyntax(SYNTAX_ATTRIBUTE_TYPE_OID);
-        if (attrTypeSyntax == null)
-        {
-          attrTypeSyntax = new AttributeTypeSyntax();
-          attrTypeSyntax.initializeSyntax(null);
-        }
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
         attrTypeSyntax = new AttributeTypeSyntax();
         attrTypeSyntax.initializeSyntax(null);
       }
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-      AttributeType attributeAttrType =
-           schema.getAttributeType(ATTR_ATTRIBUTE_TYPES_LC);
-      if (attributeAttrType == null)
+      attrTypeSyntax = new AttributeTypeSyntax();
+      attrTypeSyntax.initializeSyntax(null);
+    }
+
+    AttributeType attributeAttrType =
+         schema.getAttributeType(ATTR_ATTRIBUTE_TYPES_LC);
+    if (attributeAttrType == null)
+    {
+      attributeAttrType =
+           DirectoryServer.getDefaultAttributeType(ATTR_ATTRIBUTE_TYPES,
+                                                   attrTypeSyntax);
+    }
+
+    List<Attribute> attrList = entry.getAttribute(attributeAttrType);
+
+
+    // Get the objectClasses attribute from the entry.
+    ObjectClassSyntax ocSyntax;
+    try
+    {
+      ocSyntax = (ObjectClassSyntax) schema.getSyntax(SYNTAX_OBJECTCLASS_OID);
+      if (ocSyntax == null)
       {
-        attributeAttrType =
-             DirectoryServer.getDefaultAttributeType(ATTR_ATTRIBUTE_TYPES,
-                                                     attrTypeSyntax);
-      }
-
-      List<Attribute> attrList = entry.getAttribute(attributeAttrType);
-
-
-      // Get the objectClasses attribute from the entry.
-      ObjectClassSyntax ocSyntax;
-      try
-      {
-        ocSyntax = (ObjectClassSyntax) schema.getSyntax(SYNTAX_OBJECTCLASS_OID);
-        if (ocSyntax == null)
-        {
-          ocSyntax = new ObjectClassSyntax();
-          ocSyntax.initializeSyntax(null);
-        }
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
         ocSyntax = new ObjectClassSyntax();
         ocSyntax.initializeSyntax(null);
       }
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-      AttributeType objectclassAttrType =
-           schema.getAttributeType(ATTR_OBJECTCLASSES_LC);
-      if (objectclassAttrType == null)
+      ocSyntax = new ObjectClassSyntax();
+      ocSyntax.initializeSyntax(null);
+    }
+
+    AttributeType objectclassAttrType =
+         schema.getAttributeType(ATTR_OBJECTCLASSES_LC);
+    if (objectclassAttrType == null)
+    {
+      objectclassAttrType =
+           DirectoryServer.getDefaultAttributeType(ATTR_OBJECTCLASSES,
+                                                   ocSyntax);
+    }
+
+    List<Attribute> ocList = entry.getAttribute(objectclassAttrType);
+
+
+    // Get the name forms attribute from the entry.
+    NameFormSyntax nfSyntax;
+    try
+    {
+      nfSyntax = (NameFormSyntax) schema.getSyntax(SYNTAX_NAME_FORM_OID);
+      if (nfSyntax == null)
       {
-        objectclassAttrType =
-             DirectoryServer.getDefaultAttributeType(ATTR_OBJECTCLASSES,
-                                                     ocSyntax);
-      }
-
-      List<Attribute> ocList = entry.getAttribute(objectclassAttrType);
-
-
-      // Get the name forms attribute from the entry.
-      NameFormSyntax nfSyntax;
-      try
-      {
-        nfSyntax = (NameFormSyntax) schema.getSyntax(SYNTAX_NAME_FORM_OID);
-        if (nfSyntax == null)
-        {
-          nfSyntax = new NameFormSyntax();
-          nfSyntax.initializeSyntax(null);
-        }
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
         nfSyntax = new NameFormSyntax();
         nfSyntax.initializeSyntax(null);
       }
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-      AttributeType nameFormAttrType =
-           schema.getAttributeType(ATTR_NAME_FORMS_LC);
-      if (nameFormAttrType == null)
+      nfSyntax = new NameFormSyntax();
+      nfSyntax.initializeSyntax(null);
+    }
+
+    AttributeType nameFormAttrType =
+         schema.getAttributeType(ATTR_NAME_FORMS_LC);
+    if (nameFormAttrType == null)
+    {
+      nameFormAttrType =
+           DirectoryServer.getDefaultAttributeType(ATTR_NAME_FORMS, nfSyntax);
+    }
+
+    List<Attribute> nfList = entry.getAttribute(nameFormAttrType);
+
+
+    // Get the DIT content rules attribute from the entry.
+    DITContentRuleSyntax dcrSyntax;
+    try
+    {
+      dcrSyntax = (DITContentRuleSyntax)
+                  schema.getSyntax(SYNTAX_DIT_CONTENT_RULE_OID);
+      if (dcrSyntax == null)
       {
-        nameFormAttrType =
-             DirectoryServer.getDefaultAttributeType(ATTR_NAME_FORMS, nfSyntax);
-      }
-
-      List<Attribute> nfList = entry.getAttribute(nameFormAttrType);
-
-
-      // Get the DIT content rules attribute from the entry.
-      DITContentRuleSyntax dcrSyntax;
-      try
-      {
-        dcrSyntax = (DITContentRuleSyntax)
-                    schema.getSyntax(SYNTAX_DIT_CONTENT_RULE_OID);
-        if (dcrSyntax == null)
-        {
-          dcrSyntax = new DITContentRuleSyntax();
-          dcrSyntax.initializeSyntax(null);
-        }
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
         dcrSyntax = new DITContentRuleSyntax();
         dcrSyntax.initializeSyntax(null);
       }
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-      AttributeType dcrAttrType =
-           schema.getAttributeType(ATTR_DIT_CONTENT_RULES_LC);
-      if (dcrAttrType == null)
+      dcrSyntax = new DITContentRuleSyntax();
+      dcrSyntax.initializeSyntax(null);
+    }
+
+    AttributeType dcrAttrType =
+         schema.getAttributeType(ATTR_DIT_CONTENT_RULES_LC);
+    if (dcrAttrType == null)
+    {
+      dcrAttrType =
+           DirectoryServer.getDefaultAttributeType(ATTR_DIT_CONTENT_RULES,
+                                                   dcrSyntax);
+    }
+
+    List<Attribute> dcrList = entry.getAttribute(dcrAttrType);
+
+
+    // Get the DIT structure rules attribute from the entry.
+    DITStructureRuleSyntax dsrSyntax;
+    try
+    {
+      dsrSyntax = (DITStructureRuleSyntax)
+                  schema.getSyntax(SYNTAX_DIT_STRUCTURE_RULE_OID);
+      if (dsrSyntax == null)
       {
-        dcrAttrType =
-             DirectoryServer.getDefaultAttributeType(ATTR_DIT_CONTENT_RULES,
-                                                     dcrSyntax);
-      }
-
-      List<Attribute> dcrList = entry.getAttribute(dcrAttrType);
-
-
-      // Get the DIT structure rules attribute from the entry.
-      DITStructureRuleSyntax dsrSyntax;
-      try
-      {
-        dsrSyntax = (DITStructureRuleSyntax)
-                    schema.getSyntax(SYNTAX_DIT_STRUCTURE_RULE_OID);
-        if (dsrSyntax == null)
-        {
-          dsrSyntax = new DITStructureRuleSyntax();
-          dsrSyntax.initializeSyntax(null);
-        }
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
         dsrSyntax = new DITStructureRuleSyntax();
         dsrSyntax.initializeSyntax(null);
       }
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-      AttributeType dsrAttrType =
-           schema.getAttributeType(ATTR_DIT_STRUCTURE_RULES_LC);
-      if (dsrAttrType == null)
+      dsrSyntax = new DITStructureRuleSyntax();
+      dsrSyntax.initializeSyntax(null);
+    }
+
+    AttributeType dsrAttrType =
+         schema.getAttributeType(ATTR_DIT_STRUCTURE_RULES_LC);
+    if (dsrAttrType == null)
+    {
+      dsrAttrType =
+           DirectoryServer.getDefaultAttributeType(ATTR_DIT_STRUCTURE_RULES,
+                                                   dsrSyntax);
+    }
+
+    List<Attribute> dsrList = entry.getAttribute(dsrAttrType);
+
+
+    // Get the matching rule uses attribute from the entry.
+    MatchingRuleUseSyntax mruSyntax;
+    try
+    {
+      mruSyntax = (MatchingRuleUseSyntax)
+                  schema.getSyntax(SYNTAX_MATCHING_RULE_USE_OID);
+      if (mruSyntax == null)
       {
-        dsrAttrType =
-             DirectoryServer.getDefaultAttributeType(ATTR_DIT_STRUCTURE_RULES,
-                                                     dsrSyntax);
-      }
-
-      List<Attribute> dsrList = entry.getAttribute(dsrAttrType);
-
-
-      // Get the matching rule uses attribute from the entry.
-      MatchingRuleUseSyntax mruSyntax;
-      try
-      {
-        mruSyntax = (MatchingRuleUseSyntax)
-                    schema.getSyntax(SYNTAX_MATCHING_RULE_USE_OID);
-        if (mruSyntax == null)
-        {
-          mruSyntax = new MatchingRuleUseSyntax();
-          mruSyntax.initializeSyntax(null);
-        }
-      }
-      catch (Exception e)
-      {
-        assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
         mruSyntax = new MatchingRuleUseSyntax();
         mruSyntax.initializeSyntax(null);
       }
+    }
+    catch (Exception e)
+    {
+      assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
 
-      AttributeType mruAttrType =
-           schema.getAttributeType(ATTR_MATCHING_RULE_USE_LC);
-      if (mruAttrType == null)
+      mruSyntax = new MatchingRuleUseSyntax();
+      mruSyntax.initializeSyntax(null);
+    }
+
+    AttributeType mruAttrType =
+         schema.getAttributeType(ATTR_MATCHING_RULE_USE_LC);
+    if (mruAttrType == null)
+    {
+      mruAttrType =
+           DirectoryServer.getDefaultAttributeType(ATTR_MATCHING_RULE_USE,
+                                                   mruSyntax);
+    }
+
+    List<Attribute> mruList = entry.getAttribute(mruAttrType);
+
+
+    // Parse the attribute type definitions if there are any.
+    if (attrList != null)
+    {
+      for (Attribute a : attrList)
       {
-        mruAttrType =
-             DirectoryServer.getDefaultAttributeType(ATTR_MATCHING_RULE_USE,
-                                                     mruSyntax);
-      }
-
-      List<Attribute> mruList = entry.getAttribute(mruAttrType);
-
-
-      // Parse the attribute type definitions if there are any.
-      if (attrList != null)
-      {
-        for (Attribute a : attrList)
+        for (AttributeValue v : a.getValues())
         {
-          for (AttributeValue v : a.getValues())
+          // Parse the attribute type.
+          AttributeType attrType;
+          try
           {
-            // Parse the attribute type.
-            AttributeType attrType;
-            try
-            {
-              attrType = attrTypeSyntax.decodeAttributeType(v.getValue(),
-                                                            schema, false);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
+            attrType = attrTypeSyntax.decodeAttributeType(v.getValue(),
+                                                          schema, false);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
 
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_ATTR_TYPE;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_ATTR_TYPE;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, de);
+            }
+            else
+            {
               logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                        message, msgID);
               continue;
             }
+          }
+          catch (Exception e)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_ATTR_TYPE;
+            String message = getMessage(msgID, schemaFile,
+                                        v.getStringValue() + ":  " +
+                                             stackTraceToSingleLineString(e));
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, e);
+            }
+            else
+            {
+              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                       message, msgID);
+              continue;
+            }
+          }
+
+          // Register it with the schema.  We will allow duplicates, with the
+          // later definition overriding any earlier definition, but we want
+          // to trap them and log a warning.
+          try
+          {
+            schema.registerAttributeType(attrType, failOnError);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_ATTR_TYPE;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                     message, msgID);
+
+            try
+            {
+              schema.registerAttributeType(attrType, true);
+            }
             catch (Exception e)
             {
+              // This should never happen.
               assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_ATTR_TYPE;
-              String message = getMessage(msgID, schemaFile,
-                                          v.getStringValue() + ":  " +
-                                               stackTraceToSingleLineString(e));
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-              continue;
-            }
-
-            // Register it with the schema.  We will allow duplicates, with the
-            // later definition overriding any earlier definition, but we want
-            // to trap them and log a warning.
-            try
-            {
-              schema.registerAttributeType(attrType, false);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_ATTR_TYPE;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              try
-              {
-                schema.registerAttributeType(attrType, true);
-              }
-              catch (Exception e)
-              {
-                // This should never happen.
-                assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                      e);
-              }
             }
           }
         }
       }
+    }
 
 
-      // Parse the objectclass definitions if there are any.
-      if (ocList != null)
+    // Parse the objectclass definitions if there are any.
+    if (ocList != null)
+    {
+      for (Attribute a : ocList)
       {
-        for (Attribute a : ocList)
+        for (AttributeValue v : a.getValues())
         {
-          for (AttributeValue v : a.getValues())
+          // Parse the objectclass.
+          ObjectClass oc;
+          try
           {
-            // Parse the objectclass.
-            ObjectClass oc;
-            try
-            {
-              oc = ocSyntax.decodeObjectClass(v.getValue(), schema, false);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
+            oc = ocSyntax.decodeObjectClass(v.getValue(), schema, false);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
 
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_OC;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_OC;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, de);
+            }
+            else
+            {
               logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                        message, msgID);
               continue;
             }
+          }
+          catch (Exception e)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_OC;
+            String message = getMessage(msgID, schemaFile,
+                                        v.getStringValue() + ":  " +
+                                             stackTraceToSingleLineString(e));
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, e);
+            }
+            else
+            {
+              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                       message, msgID);
+              continue;
+            }
+          }
+
+          // Register it with the schema.  We will allow duplicates, with the
+          // later definition overriding any earlier definition, but we want
+          // to trap them and log a warning.
+          try
+          {
+            schema.registerObjectClass(oc, failOnError);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_OC;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                     message, msgID);
+
+            try
+            {
+              schema.registerObjectClass(oc, true);
+            }
             catch (Exception e)
             {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_OC;
-              String message = getMessage(msgID, schemaFile,
-                                          v.getStringValue() + ":  " +
-                                               stackTraceToSingleLineString(e));
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-              continue;
-            }
-
-            // Register it with the schema.  We will allow duplicates, with the
-            // later definition overriding any earlier definition, but we want
-            // to trap them and log a warning.
-            try
-            {
-              schema.registerObjectClass(oc, false);
-            }
-            catch (DirectoryException de)
-            {
+              // This should never happen.
               assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_OC;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              try
-              {
-                schema.registerObjectClass(oc, true);
-              }
-              catch (Exception e)
-              {
-                // This should never happen.
-                assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                      e);
-              }
+                                    e);
             }
           }
         }
       }
+    }
 
 
-      // Parse the name form definitions if there are any.
-      if (nfList != null)
+    // Parse the name form definitions if there are any.
+    if (nfList != null)
+    {
+      for (Attribute a : nfList)
       {
-        for (Attribute a : nfList)
+        for (AttributeValue v : a.getValues())
         {
-          for (AttributeValue v : a.getValues())
+          // Parse the name form.
+          NameForm nf;
+          try
           {
-            // Parse the name form.
-            NameForm nf;
-            try
-            {
-              nf = nfSyntax.decodeNameForm(v.getValue(), schema, false);
-              nf.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
-              nf.setSchemaFile(schemaFile);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
+            nf = nfSyntax.decodeNameForm(v.getValue(), schema, false);
+            nf.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
+            nf.setSchemaFile(schemaFile);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
 
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_NAME_FORM;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_NAME_FORM;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, de);
+            }
+            else
+            {
               logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                        message, msgID);
               continue;
             }
+          }
+          catch (Exception e)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_NAME_FORM;
+            String message = getMessage(msgID, schemaFile,
+                                        v.getStringValue() + ":  " +
+                                             stackTraceToSingleLineString(e));
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, e);
+            }
+            else
+            {
+              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                       message, msgID);
+              continue;
+            }
+          }
+
+          // Register it with the schema.  We will allow duplicates, with the
+          // later definition overriding any earlier definition, but we want
+          // to trap them and log a warning.
+          try
+          {
+            schema.registerNameForm(nf, failOnError);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_NAME_FORM;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                     message, msgID);
+
+            try
+            {
+              schema.registerNameForm(nf, true);
+            }
             catch (Exception e)
             {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_NAME_FORM;
-              String message = getMessage(msgID, schemaFile,
-                                          v.getStringValue() + ":  " +
-                                               stackTraceToSingleLineString(e));
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-              continue;
-            }
-
-            // Register it with the schema.  We will allow duplicates, with the
-            // later definition overriding any earlier definition, but we want
-            // to trap them and log a warning.
-            try
-            {
-              schema.registerNameForm(nf, false);
-            }
-            catch (DirectoryException de)
-            {
+              // This should never happen.
               assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_NAME_FORM;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              try
-              {
-                schema.registerNameForm(nf, true);
-              }
-              catch (Exception e)
-              {
-                // This should never happen.
-                assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                      e);
-              }
+                                    e);
             }
           }
         }
       }
+    }
 
 
-      // Parse the DIT content rule definitions if there are any.
-      if (dcrList != null)
+    // Parse the DIT content rule definitions if there are any.
+    if (dcrList != null)
+    {
+      for (Attribute a : dcrList)
       {
-        for (Attribute a : dcrList)
+        for (AttributeValue v : a.getValues())
         {
-          for (AttributeValue v : a.getValues())
+          // Parse the DIT content rule.
+          DITContentRule dcr;
+          try
           {
-            // Parse the DIT content rule.
-            DITContentRule dcr;
-            try
-            {
-              dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema, false);
-              dcr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
-              dcr.setSchemaFile(schemaFile);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
+            dcr = dcrSyntax.decodeDITContentRule(v.getValue(), schema, false);
+            dcr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
+            dcr.setSchemaFile(schemaFile);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
 
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DCR;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DCR;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, de);
+            }
+            else
+            {
               logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                        message, msgID);
               continue;
             }
+          }
+          catch (Exception e)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DCR;
+            String message = getMessage(msgID, schemaFile,
+                                        v.getStringValue() + ":  " +
+                                             stackTraceToSingleLineString(e));
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, e);
+            }
+            else
+            {
+              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                       message, msgID);
+              continue;
+            }
+          }
+
+          // Register it with the schema.  We will allow duplicates, with the
+          // later definition overriding any earlier definition, but we want
+          // to trap them and log a warning.
+          try
+          {
+            schema.registerDITContentRule(dcr, failOnError);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_DCR;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                     message, msgID);
+
+            try
+            {
+              schema.registerDITContentRule(dcr, true);
+            }
             catch (Exception e)
             {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DCR;
-              String message = getMessage(msgID, schemaFile,
-                                          v.getStringValue() + ":  " +
-                                               stackTraceToSingleLineString(e));
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-              continue;
-            }
-
-            // Register it with the schema.  We will allow duplicates, with the
-            // later definition overriding any earlier definition, but we want
-            // to trap them and log a warning.
-            try
-            {
-              schema.registerDITContentRule(dcr, false);
-            }
-            catch (DirectoryException de)
-            {
+              // This should never happen.
               assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_DCR;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              try
-              {
-                schema.registerDITContentRule(dcr, true);
-              }
-              catch (Exception e)
-              {
-                // This should never happen.
-                assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                      e);
-              }
+                                    e);
             }
           }
         }
       }
+    }
 
 
-      // Parse the DIT structure rule definitions if there are any.
-      if (dsrList != null)
+    // Parse the DIT structure rule definitions if there are any.
+    if (dsrList != null)
+    {
+      for (Attribute a : dsrList)
       {
-        for (Attribute a : dsrList)
+        for (AttributeValue v : a.getValues())
         {
-          for (AttributeValue v : a.getValues())
+          // Parse the DIT content rule.
+          DITStructureRule dsr;
+          try
           {
-            // Parse the DIT content rule.
-            DITStructureRule dsr;
-            try
-            {
-              dsr = dsrSyntax.decodeDITStructureRule(v.getValue(), schema,
-                                                     false);
-              dsr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
-              dsr.setSchemaFile(schemaFile);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
+            dsr = dsrSyntax.decodeDITStructureRule(v.getValue(), schema,
+                                                   false);
+            dsr.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
+            dsr.setSchemaFile(schemaFile);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
 
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DSR;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DSR;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, de);
+            }
+            else
+            {
               logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                        message, msgID);
               continue;
             }
+          }
+          catch (Exception e)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DSR;
+            String message = getMessage(msgID, schemaFile,
+                                        v.getStringValue() + ":  " +
+                                             stackTraceToSingleLineString(e));
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, e);
+            }
+            else
+            {
+              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                       message, msgID);
+              continue;
+            }
+          }
+
+          // Register it with the schema.  We will allow duplicates, with the
+          // later definition overriding any earlier definition, but we want
+          // to trap them and log a warning.
+          try
+          {
+            schema.registerDITStructureRule(dsr, failOnError);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_DSR;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                     message, msgID);
+
+            try
+            {
+              schema.registerDITStructureRule(dsr, true);
+            }
             catch (Exception e)
             {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_DSR;
-              String message = getMessage(msgID, schemaFile,
-                                          v.getStringValue() + ":  " +
-                                               stackTraceToSingleLineString(e));
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-              continue;
-            }
-
-            // Register it with the schema.  We will allow duplicates, with the
-            // later definition overriding any earlier definition, but we want
-            // to trap them and log a warning.
-            try
-            {
-              schema.registerDITStructureRule(dsr, false);
-            }
-            catch (DirectoryException de)
-            {
+              // This should never happen.
               assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_DSR;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              try
-              {
-                schema.registerDITStructureRule(dsr, true);
-              }
-              catch (Exception e)
-              {
-                // This should never happen.
-                assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                      e);
-              }
+                                    e);
             }
           }
         }
       }
+    }
 
 
-      // Parse the matching rule use definitions if there are any.
-      if (mruList != null)
+    // Parse the matching rule use definitions if there are any.
+    if (mruList != null)
+    {
+      for (Attribute a : mruList)
       {
-        for (Attribute a : mruList)
+        for (AttributeValue v : a.getValues())
         {
-          for (AttributeValue v : a.getValues())
+          // Parse the matching rule use definition.
+          MatchingRuleUse mru;
+          try
           {
-            // Parse the matching rule use definition.
-            MatchingRuleUse mru;
-            try
-            {
-              mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema,
-                                                    false);
-              mru.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
-              mru.setSchemaFile(schemaFile);
-            }
-            catch (DirectoryException de)
-            {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
+            mru = mruSyntax.decodeMatchingRuleUse(v.getValue(), schema,
+                                                  false);
+            mru.getExtraProperties().remove(SCHEMA_PROPERTY_FILENAME);
+            mru.setSchemaFile(schemaFile);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
 
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_MRU;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_MRU;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, de);
+            }
+            else
+            {
               logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                        message, msgID);
               continue;
             }
+          }
+          catch (Exception e)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_MRU;
+            String message = getMessage(msgID, schemaFile,
+                                        v.getStringValue() + ":  " +
+                                             stackTraceToSingleLineString(e));
+
+            if (failOnError)
+            {
+              throw new ConfigException(msgID, message, e);
+            }
+            else
+            {
+              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                       message, msgID);
+              continue;
+            }
+          }
+
+          // Register it with the schema.  We will allow duplicates, with the
+          // later definition overriding any earlier definition, but we want
+          // to trap them and log a warning.
+          try
+          {
+            schema.registerMatchingRuleUse(mru, failOnError);
+          }
+          catch (DirectoryException de)
+          {
+            assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
+                                  de);
+
+            int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_MRU;
+            String message = getMessage(msgID, schemaFile,
+                                        de.getErrorMessage());
+            logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
+                     message, msgID);
+
+            try
+            {
+              schema.registerMatchingRuleUse(mru, true);
+            }
             catch (Exception e)
             {
-              assert debugException(CLASS_NAME, "initializeSchemaFromFiles", e);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CANNOT_PARSE_MRU;
-              String message = getMessage(msgID, schemaFile,
-                                          v.getStringValue() + ":  " +
-                                               stackTraceToSingleLineString(e));
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-              continue;
-            }
-
-            // Register it with the schema.  We will allow duplicates, with the
-            // later definition overriding any earlier definition, but we want
-            // to trap them and log a warning.
-            try
-            {
-              schema.registerMatchingRuleUse(mru, false);
-            }
-            catch (DirectoryException de)
-            {
+              // This should never happen.
               assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                    de);
-
-              int    msgID   = MSGID_CONFIG_SCHEMA_CONFLICTING_MRU;
-              String message = getMessage(msgID, schemaFile,
-                                          de.getErrorMessage());
-              logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
-                       message, msgID);
-
-              try
-              {
-                schema.registerMatchingRuleUse(mru, true);
-              }
-              catch (Exception e)
-              {
-                // This should never happen.
-                assert debugException(CLASS_NAME, "initializeSchemaFromFiles",
-                                      e);
-              }
+                                    e);
             }
           }
         }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/TaskMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/TaskMessages.java
index 80bf1d4..5a7ed00 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/TaskMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/TaskMessages.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
  */
 package org.opends.server.messages;
 
@@ -62,7 +62,7 @@
    * own shutdown message.
    */
   public static final int MSGID_TASK_SHUTDOWN_DEFAULT_MESSAGE =
-       CATEGORY_MASK_EXTENSIONS | SEVERITY_MASK_INFORMATIONAL | 3;
+       CATEGORY_MASK_TASK | SEVERITY_MASK_INFORMATIONAL | 3;
 
 
 
@@ -72,7 +72,62 @@
    * shutdown message.
    */
   public static final int MSGID_TASK_SHUTDOWN_CUSTOM_MESSAGE =
-       CATEGORY_MASK_EXTENSIONS | SEVERITY_MASK_INFORMATIONAL | 4;
+       CATEGORY_MASK_TASK | SEVERITY_MASK_INFORMATIONAL | 4;
+
+
+
+  /**
+   * The message ID for the shutdown message that will be used if no schema file
+   * names were provided.  This takes two arguments, which are the name of the
+   * attribute and the DN of the entry in which the file names should have been
+   * given.
+   */
+  public static final int MSGID_TASK_ADDSCHEMAFILE_NO_FILENAME =
+       CATEGORY_MASK_TASK | SEVERITY_MASK_SEVERE_ERROR | 5;
+
+
+
+  /**
+   * The message ID for the shutdown message that will be used if a specified
+   * schema file does not exist in the schema directory.  This takes two
+   * arguments, which are the name of the schema file and the path to the schema
+   * directory.
+   */
+  public static final int MSGID_TASK_ADDSCHEMAFILE_NO_SUCH_FILE =
+       CATEGORY_MASK_TASK | SEVERITY_MASK_SEVERE_ERROR | 6;
+
+
+
+  /**
+   * The message ID for the shutdown message that will be used if an error
+   * occurs while attempting to check for the existence of a schema file in the
+   * schema directory.  This takes three arguments, which are the name of the
+   * file, the path to the schema directory, and a string representation of the
+   * exception that was caught.
+   */
+  public static final int MSGID_TASK_ADDSCHEMAFILE_ERROR_CHECKING_FOR_FILE =
+       CATEGORY_MASK_TASK | SEVERITY_MASK_SEVERE_ERROR | 7;
+
+
+
+  /**
+   * The message ID for the shutdown message that will be used if an error
+   * occurs while trying to read and load the contents of a schema file into the
+   * server schema.  This takes two arguments, which are the name of the schema
+   * file and a message explaining the problem that occurred.
+   */
+  public static final int MSGID_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE =
+       CATEGORY_MASK_TASK | SEVERITY_MASK_SEVERE_ERROR | 8;
+
+
+
+  /**
+   * The message ID for the shutdown message that will be used if the server is
+   * unable to obtain a write lock on the server schema.  This takes a single
+   * argument, which is the DN of the schema entry.
+   */
+  public static final int MSGID_TASK_ADDSCHEMAFILE_CANNOT_LOCK_SCHEMA =
+       CATEGORY_MASK_TASK | SEVERITY_MASK_SEVERE_ERROR | 9;
 
 
 
@@ -94,5 +149,27 @@
     registerMessage(MSGID_TASK_SHUTDOWN_CUSTOM_MESSAGE,
                     "The Directory Server shutdown process has been " +
                     "initiated by task %s:  %s");
+
+
+    registerMessage(MSGID_TASK_ADDSCHEMAFILE_NO_FILENAME,
+                    "Unable to add one or more files to the server schema " +
+                    "because no schema file names were provided in " +
+                    "attribute %s of task entry %s.");
+    registerMessage(MSGID_TASK_ADDSCHEMAFILE_NO_SUCH_FILE,
+                    "Unable to add one or more files to the server schema " +
+                    "because the specified schema file %s does not exist in " +
+                    "schema directory %s.");
+    registerMessage(MSGID_TASK_ADDSCHEMAFILE_ERROR_CHECKING_FOR_FILE,
+                    "Unable to add one or more files to the server schema " +
+                    "because an error occurred while attempting to determine " +
+                    "whether file %s exists in schema directory %s:  %s.");
+    registerMessage(MSGID_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE,
+                    "An error occurred while attempting to load the contents " +
+                    "of schema file %s into the server schema:  %s.");
+    registerMessage(MSGID_TASK_ADDSCHEMAFILE_CANNOT_LOCK_SCHEMA,
+                    "Unable to add one or more files to the server schema " +
+                    "because the server was unable to obtain a write lock on " +
+                    "the schema entry %s after multiple attempts.");
   }
 }
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java b/opendj-sdk/opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java
new file mode 100644
index 0000000..4e6eba6
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/tasks/AddSchemaFileTask.java
@@ -0,0 +1,238 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.tasks;
+
+
+
+import java.io.File;
+import java.util.TreeSet;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+
+import org.opends.server.backends.task.Task;
+import org.opends.server.backends.task.TaskState;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.SchemaConfigManager;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ErrorLogCategory;
+import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.LockManager;
+import org.opends.server.types.ResultCode;
+import org.opends.server.types.Schema;
+
+import static org.opends.server.config.ConfigConstants.*;
+import static org.opends.server.loggers.Debug.*;
+import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.TaskMessages.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This class provides an implementation of a Directory Server task that can be
+ * used to add the contents of a new schema file into the server schema.
+ */
+public class AddSchemaFileTask
+       extends Task
+{
+  /**
+   * The fully-qualified name of this class for debugging purposes.
+   */
+  private static final String CLASS_NAME =
+       "org.opends.server.tasks.AddSchemaFileTask";
+
+
+
+  // The list of files to be added to the server schema.
+  TreeSet<String> filesToAdd;
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void initializeTask()
+         throws DirectoryException
+  {
+    assert debugEnter(CLASS_NAME, "initializeTask");
+
+    // Get the attribute that specifies which schema file(s) to add.
+    Entry taskEntry = getTaskEntry();
+    AttributeType attrType = DirectoryServer.getAttributeType(
+                                  ATTR_TASK_ADDSCHEMAFILE_FILENAME, true);
+    List<Attribute> attrList = taskEntry.getAttribute(attrType);
+    if ((attrList == null) || attrList.isEmpty())
+    {
+      int    msgID   = MSGID_TASK_ADDSCHEMAFILE_NO_FILENAME;
+      String message = getMessage(msgID, ATTR_TASK_ADDSCHEMAFILE_FILENAME,
+                                  String.valueOf(taskEntry.getDN()));
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message,
+                                   msgID);
+    }
+
+
+    // Get the name(s) of the schema files to add and make sure they exist in
+    // the schema directory.
+    String schemaDirectory = SchemaConfigManager.getSchemaDirectoryPath();
+    filesToAdd = new TreeSet<String>();
+    for (Attribute a : attrList)
+    {
+      for (AttributeValue v  : a.getValues())
+      {
+        String filename = v.getStringValue();
+        filesToAdd.add(filename);
+
+        try
+        {
+          File schemaFile = new File(schemaDirectory, filename);
+          if ((! schemaFile.exists()) ||
+              (! schemaFile.getParent().equals(schemaDirectory)))
+          {
+            int    msgID   = MSGID_TASK_ADDSCHEMAFILE_NO_SUCH_FILE;
+            String message = getMessage(msgID, filename, schemaDirectory);
+            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                         message, msgID);
+          }
+        }
+        catch (Exception e)
+        {
+          int    msgID   = MSGID_TASK_ADDSCHEMAFILE_ERROR_CHECKING_FOR_FILE;
+          String message = getMessage(msgID, filename, schemaDirectory,
+                                      stackTraceToSingleLineString(e));
+          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+                                       message, msgID, e);
+        }
+      }
+    }
+
+
+    // Create a new dummy schema and make sure that we can add the contents of
+    // all the schema files into it.  Even though this duplicates work we'll
+    // have to do later, it will be good to do it now as well so we can reject
+    // the entry immediately which will fail the attempt by the client to add it
+    // to the server, rather than having to check its status after the fact.
+    Schema schema = DirectoryServer.getSchema().duplicate();
+    for (String schemaFile : filesToAdd)
+    {
+      try
+      {
+        SchemaConfigManager.loadSchemaFile(schema, schemaFile);
+      }
+      catch (ConfigException ce)
+      {
+        int    msgID   = MSGID_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE;
+        String message = getMessage(msgID, String.valueOf(schemaFile),
+                                    ce.getMessage());
+        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+                                     message, msgID, ce);
+      }
+      catch (InitializationException ie)
+      {
+        int    msgID   = MSGID_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE;
+        String message = getMessage(msgID, String.valueOf(schemaFile),
+                                    ie.getMessage());
+        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+                                     message, msgID, ie);
+      }
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  protected TaskState runTask()
+  {
+    assert debugEnter(CLASS_NAME, "runTask");
+
+
+    // Obtain a write lock on the server schema so that we can be sure nothing
+    // else tries to write to it at the same time.
+    DN schemaDN = DirectoryServer.getSchemaDN();
+    Lock schemaLock = LockManager.lockWrite(schemaDN);
+    for (int i=0; ((schemaLock == null) && (i < 3)); i++)
+    {
+      schemaLock = LockManager.lockWrite(schemaDN);
+    }
+
+    if (schemaLock == null)
+    {
+      int    msgID   = MSGID_TASK_ADDSCHEMAFILE_CANNOT_LOCK_SCHEMA;
+      String message = getMessage(msgID, String.valueOf(schemaDN));
+      logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR, message,
+               msgID);
+      return TaskState.STOPPED_BY_ERROR;
+    }
+
+    try
+    {
+      Schema schema = DirectoryServer.getSchema().duplicate();
+      for (String schemaFile : filesToAdd)
+      {
+        try
+        {
+          SchemaConfigManager.loadSchemaFile(schema, schemaFile);
+        }
+        catch (ConfigException ce)
+        {
+          int    msgID   = MSGID_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE;
+          String message = getMessage(msgID, String.valueOf(schemaFile),
+                                      ce.getMessage());
+          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
+                   message, msgID);
+          return TaskState.STOPPED_BY_ERROR;
+        }
+        catch (InitializationException ie)
+        {
+          int    msgID   = MSGID_TASK_ADDSCHEMAFILE_ERROR_LOADING_SCHEMA_FILE;
+          String message = getMessage(msgID, String.valueOf(schemaFile),
+                                      ie.getMessage());
+          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
+                   message, msgID);
+          return TaskState.STOPPED_BY_ERROR;
+        }
+      }
+
+      DirectoryServer.setSchema(schema);
+      return TaskState.COMPLETED_SUCCESSFULLY;
+    }
+    finally
+    {
+      LockManager.unlock(schemaDN, schemaLock);
+    }
+  }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/AddSchemaFileTaskTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/AddSchemaFileTaskTestCase.java
new file mode 100644
index 0000000..e68ca5a
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/AddSchemaFileTaskTestCase.java
@@ -0,0 +1,482 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.tasks;
+
+
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeClass;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.backends.SchemaTestMatchingRule;
+import org.opends.server.backends.task.Task;
+import org.opends.server.backends.task.TaskBackend;
+import org.opends.server.backends.task.TaskState;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.SchemaConfigManager;
+import org.opends.server.tools.LDAPModify;
+import org.opends.server.types.DN;
+
+import static org.testng.Assert.*;
+
+
+
+/**
+ * Tests invocation of the import and export tasks, but does not aim to
+ * thoroughly test the underlying backend implementations.
+ */
+public class AddSchemaFileTaskTestCase
+       extends TasksTestCase
+{
+  /**
+   * Make sure that the Directory Server is running.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @BeforeClass()
+  public void startServer()
+         throws Exception
+  {
+    TestCaseUtils.startServer();
+  }
+
+
+
+  /**
+   * Attempts to add a new file to the server schema where the file exists and
+   * has valid contents.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddValidSchemaFile()
+         throws Exception
+  {
+    SchemaTestMatchingRule matchingRule =
+         new SchemaTestMatchingRule("testAddValidSchemaFileMatch",
+                                    "1.3.6.1.4.1.26027.1.999.23");
+    DirectoryServer.registerMatchingRule(matchingRule, false);
+
+
+    String schemaDirectory = SchemaConfigManager.getSchemaDirectoryPath();
+
+    String[] fileLines =
+    {
+      "dn: cn=schema",
+      "objectClass: top",
+      "objectClass: ldapSubentry",
+      "objectClass: subschema",
+      "attributeTypes: ( testaddvalidschemafileat-oid " +
+           "NAME 'testAddValidSchemaFileAT' )",
+      "objectClasses: ( testaddvalidschemafileoc-oid " +
+           "NAME 'testAddValidSchemaFileOC' STRUCTURAL " +
+           "MUST testAddValidSchemaFileAT )",
+      "nameForms: ( testaddvalidschemafilenf-oid " +
+           "NAME 'testAddValidSchemaFileNF' OC testAddValidSchemaFileOC " +
+           "MUST testAddValidSchemaFileAT )",
+      "dITContentRules: ( testaddvalidschemafileoc-oid " +
+           "NAME 'testAddValidSchemaFileDCR' MAY description )",
+      "dITStructureRules: ( 999016 NAME 'testAddValidSchemaFileDSR' " +
+           "FORM testAddValidSchemaFileNF )",
+      "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.23 " +
+           "NAME 'testAddValidSchemaFileMRU' APPLIES testAddValidSchemaFileAT )"
+    };
+
+    File validFile = new File(schemaDirectory, "05-single-valid.ldif");
+    BufferedWriter writer = new BufferedWriter(new FileWriter(validFile));
+    for (String line : fileLines)
+    {
+      writer.write(line);
+      writer.newLine();
+    }
+    writer.close();
+
+    String taskDNStr =
+         "ds-task-id=add-single-valid-file,cn=Scheduled Tasks,cn=Tasks";
+    String path = TestCaseUtils.createTempFile(
+         "dn: " + taskDNStr,
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: ds-task",
+         "objectClass: ds-task-add-schema-file",
+         "ds-task-id: add-single-valid-file",
+         "ds-task-class-name: org.opends.server.tasks.AddSchemaFileTask",
+         "ds-task-schema-file-name: 05-single-valid.ldif");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Task task = getCompletedTask(DN.decode(taskDNStr));
+    assertEquals(task.getTaskState(), TaskState.COMPLETED_SUCCESSFULLY);
+  }
+
+
+
+  /**
+   * Attempts to add multiple new files to the server schema where the files
+   * exist and have valid contents.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddMultipleValidSchemaFiles()
+         throws Exception
+  {
+    String schemaDirectory = SchemaConfigManager.getSchemaDirectoryPath();
+
+
+    SchemaTestMatchingRule matchingRule1 =
+         new SchemaTestMatchingRule("testAddMultipleValidSchemaFiles1Match",
+                                    "1.3.6.1.4.1.26027.1.999.24");
+    DirectoryServer.registerMatchingRule(matchingRule1, false);
+
+    String[] fileLines1 =
+    {
+      "dn: cn=schema",
+      "objectClass: top",
+      "objectClass: ldapSubentry",
+      "objectClass: subschema",
+      "attributeTypes: ( testaddmultiplevalidschemafiles1at-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles1AT' )",
+      "objectClasses: ( testaddmultiplevalidschemafiles1oc-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles1OC' STRUCTURAL " +
+           "MUST testAddMultipleValidSchemaFiles1AT )",
+      "nameForms: ( testaddmultiplevalidschemafiles1nf-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles1NF' " +
+           "OC testAddMultipleValidSchemaFiles1OC " +
+           "MUST testAddMultipleValidSchemaFiles1AT )",
+      "dITContentRules: ( testaddmultiplevalidschemafiles1oc-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles1DCR' MAY description )",
+      "dITStructureRules: ( 999017 " +
+           "NAME 'testAddMultipleValidSchemaFiles1DSR' " +
+           "FORM testAddMultipleValidSchemaFiles1NF )",
+      "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.24 " +
+           "NAME 'testAddMultipleValidSchemaFiles1MRU' " +
+           "APPLIES testAddMultipleValidSchemaFiles1AT )"
+    };
+
+    File validFile1 = new File(schemaDirectory, "05-multiple-valid-1.ldif");
+    BufferedWriter writer1 = new BufferedWriter(new FileWriter(validFile1));
+    for (String line : fileLines1)
+    {
+      writer1.write(line);
+      writer1.newLine();
+    }
+    writer1.close();
+
+
+    SchemaTestMatchingRule matchingRule2 =
+         new SchemaTestMatchingRule("testAddMultipleValidSchemaFiles2Match",
+                                    "1.3.6.1.4.1.26027.1.999.25");
+    DirectoryServer.registerMatchingRule(matchingRule2, false);
+
+    String[] fileLines2 =
+    {
+      "dn: cn=schema",
+      "objectClass: top",
+      "objectClass: ldapSubentry",
+      "objectClass: subschema",
+      "attributeTypes: ( testaddmultiplevalidschemafiles2at-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles2AT' )",
+      "objectClasses: ( testaddmultiplevalidschemafiles2oc-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles2OC' STRUCTURAL " +
+           "MUST testAddMultipleValidSchemaFiles2AT )",
+      "nameForms: ( testaddmultiplevalidschemafiles2nf-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles2NF' " +
+           "OC testAddMultipleValidSchemaFiles2OC " +
+           "MUST testAddMultipleValidSchemaFiles2AT )",
+      "dITContentRules: ( testaddmultiplevalidschemafiles2oc-oid " +
+           "NAME 'testAddMultipleValidSchemaFiles2DCR' MAY description )",
+      "dITStructureRules: ( 999018 " +
+           "NAME 'testAddMultipleValidSchemaFiles2DSR' " +
+           "FORM testAddMultipleValidSchemaFiles2NF )",
+      "matchingRuleUse: ( 1.3.6.1.4.1.26027.1.999.25 " +
+           "NAME 'testAddMultipleValidSchemaFiles2MRU' " +
+           "APPLIES testAddMultipleValidSchemaFiles2AT )"
+    };
+
+    File validFile2 = new File(schemaDirectory, "05-multiple-valid-2.ldif");
+    BufferedWriter writer2 = new BufferedWriter(new FileWriter(validFile2));
+    for (String line : fileLines2)
+    {
+      writer2.write(line);
+      writer2.newLine();
+    }
+    writer2.close();
+
+
+    String taskDNStr =
+         "ds-task-id=add-multiple-valid-files,cn=Scheduled Tasks,cn=Tasks";
+    String path = TestCaseUtils.createTempFile(
+         "dn: " + taskDNStr,
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: ds-task",
+         "objectClass: ds-task-add-schema-file",
+         "ds-task-id: add-multiple-valid-files",
+         "ds-task-class-name: org.opends.server.tasks.AddSchemaFileTask",
+         "ds-task-schema-file-name: 05-multiple-valid-1.ldif",
+         "ds-task-schema-file-name: 05-multiple-valid-2.ldif");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Task task = getCompletedTask(DN.decode(taskDNStr));
+    assertEquals(task.getTaskState(), TaskState.COMPLETED_SUCCESSFULLY);
+  }
+
+
+
+  /**
+   * Attempts to add a new file to the server schema in which the task entry
+   * does not specify the name of the file to add.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddMissingSchemaFileNames()
+         throws Exception
+  {
+    String taskDNStr =
+         "ds-task-id=add-missing-file-names,cn=Scheduled Tasks,cn=Tasks";
+    String path = TestCaseUtils.createTempFile(
+         "dn: " + taskDNStr,
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: ds-task",
+         "ds-task-id: add-missing-file-names",
+         "ds-task-class-name: org.opends.server.tasks.AddSchemaFileTask");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Attempts to add a new file to the server schema in which the file does not
+   * exist.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddMissingSchemaFile()
+         throws Exception
+  {
+    String taskDNStr =
+         "ds-task-id=add-missing-file,cn=Scheduled Tasks,cn=Tasks";
+    String path = TestCaseUtils.createTempFile(
+         "dn: " + taskDNStr,
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: ds-task",
+         "objectClass: ds-task-add-schema-file",
+         "ds-task-id: add-missing-file",
+         "ds-task-class-name: org.opends.server.tasks.AddSchemaFileTask",
+         "ds-task-schema-file-name: 05-missing.ldif");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+  }
+
+
+
+  /**
+   * Attempts to add a new file to the server schema in which the file exists
+   * and is empty.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddEmptySchemaFile()
+         throws Exception
+  {
+    String schemaDirectory = SchemaConfigManager.getSchemaDirectoryPath();
+
+    File emptyFile = new File(schemaDirectory, "05-empty.ldif");
+    emptyFile.createNewFile();
+
+    String taskDNStr = "ds-task-id=add-empty-file,cn=Scheduled Tasks,cn=Tasks";
+    String path = TestCaseUtils.createTempFile(
+         "dn: " + taskDNStr,
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: ds-task",
+         "objectClass: ds-task-add-schema-file",
+         "ds-task-id: add-empty-file",
+         "ds-task-class-name: org.opends.server.tasks.AddSchemaFileTask",
+         "ds-task-schema-file-name: 05-empty.ldif");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+
+    Task task = getCompletedTask(DN.decode(taskDNStr));
+    assertEquals(task.getTaskState(), TaskState.COMPLETED_SUCCESSFULLY);
+  }
+
+
+
+  /**
+   * Attempts to add a new file to the server schema in which the file exists
+   * but does not contain a valid schema definition.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testAddInvalidSchemaFile()
+         throws Exception
+  {
+    String schemaDirectory = SchemaConfigManager.getSchemaDirectoryPath();
+
+    File invalidFile = new File(schemaDirectory, "05-invalid.ldif");
+    BufferedWriter writer = new BufferedWriter(new FileWriter(invalidFile));
+    writer.write("invalid");
+    writer.close();
+
+    String taskDNStr =
+         "ds-task-id=add-invalid-file,cn=Scheduled Tasks,cn=Tasks";
+    String path = TestCaseUtils.createTempFile(
+         "dn: " + taskDNStr,
+         "changetype: add",
+         "objectClass: top",
+         "objectClass: ds-task",
+         "objectClass: ds-task-add-schema-file",
+         "ds-task-id: add-invalid-file",
+         "ds-task-class-name: org.opends.server.tasks.AddSchemaFileTask",
+         "ds-task-schema-file-name: 05-invalid.ldif");
+
+    String[] args =
+    {
+      "-h", "127.0.0.1",
+      "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+      "-D", "cn=Directory Manager",
+      "-w", "password",
+      "-f", path
+    };
+
+    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
+    invalidFile.delete();
+  }
+
+
+
+  /**
+   * Retrieves the specified task from the server, waiting for it to finish all
+   * the running its going to do before returning.
+   *
+   * @param  taskEntryDN  The DN of the entry for the task to retrieve.
+   *
+   * @return  The requested task entry.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  private Task getCompletedTask(DN taskEntryDN)
+          throws Exception
+  {
+    TaskBackend taskBackend =
+         (TaskBackend) DirectoryServer.getBackend(DN.decode("cn=tasks"));
+    Task task = taskBackend.getScheduledTask(taskEntryDN);
+    if (task == null)
+    {
+      long stopWaitingTime = System.currentTimeMillis() + 10000L;
+      while ((task == null) && (System.currentTimeMillis() < stopWaitingTime))
+      {
+        Thread.sleep(10);
+        task = taskBackend.getScheduledTask(taskEntryDN);
+      }
+    }
+
+    if (task == null)
+    {
+      throw new AssertionError("There is no such task " +
+                               taskEntryDN.toString());
+    }
+
+    if (! TaskState.isDone(task.getTaskState()))
+    {
+      long stopWaitingTime = System.currentTimeMillis() + 20000L;
+      while ((! TaskState.isDone(task.getTaskState())) &&
+             (System.currentTimeMillis() < stopWaitingTime))
+      {
+        Thread.sleep(10);
+      }
+    }
+
+    if (! TaskState.isDone(task.getTaskState()))
+    {
+      throw new AssertionError("Task " + taskEntryDN.toString() +
+                               " did not complete in a timely manner.");
+    }
+
+    return task;
+  }
+}
+

--
Gitblit v1.10.0