From 8b3cd28204e15e0a98ce038b355f100cd7c44e3c Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <capponi.nicolas@gmail.com>
Date: Thu, 28 Jan 2016 08:28:20 +0000
Subject: [PATCH] OPENDJ-1632 (PR-201) Migrate AttributeType in one shot

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java |  404 +++++++++++++++++++++------------------------------------
 1 files changed, 149 insertions(+), 255 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
index 673f15d..6198e7e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/SchemaBackend.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2016 ForgeRock AS
  */
 package org.opends.server.backends;
 
@@ -68,10 +68,10 @@
 import org.forgerock.opendj.ldap.ModificationType;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.forgerock.opendj.ldap.schema.CoreSchema;
 import org.forgerock.opendj.ldap.schema.MatchingRule;
 import org.forgerock.opendj.ldap.schema.ObjectClassType;
-import org.forgerock.opendj.ldap.schema.SchemaBuilder;
 import org.forgerock.opendj.ldap.schema.Syntax;
 import org.opends.server.admin.server.ConfigurationChangeListener;
 import org.opends.server.admin.std.server.SchemaBackendCfg;
@@ -92,11 +92,10 @@
 import org.opends.server.schema.DITContentRuleSyntax;
 import org.opends.server.schema.DITStructureRuleSyntax;
 import org.opends.server.schema.GeneralizedTimeSyntax;
-import org.opends.server.schema.LDAPSyntaxDescriptionSyntax;
 import org.opends.server.schema.MatchingRuleUseSyntax;
 import org.opends.server.schema.NameFormSyntax;
 import org.opends.server.schema.ObjectClassSyntax;
-import org.opends.server.schema.SchemaUpdater;
+import org.opends.server.schema.SomeSchemaElement;
 import org.opends.server.types.*;
 import org.opends.server.util.BackupManager;
 import org.opends.server.util.DynamicConstants;
@@ -565,14 +564,14 @@
      * Add the schema definition attributes.
      */
     Schema schema = DirectoryServer.getSchema();
-    buildSchemaAttribute(schema.getAttributeTypes().values(), userAttrs,
+    buildSchemaAttribute(schema.getAttributeTypes(), userAttrs,
         operationalAttrs, attributeTypesType, includeSchemaFile,
         AttributeTypeSyntax.isStripSyntaxMinimumUpperBound(),
         ignoreShowAllOption);
     buildSchemaAttribute(schema.getObjectClasses().values(), userAttrs,
         operationalAttrs, objectClassesType, includeSchemaFile, false,
         ignoreShowAllOption);
-    buildSchemaAttribute(schema.getMatchingRules().values(), userAttrs,
+    buildSchemaAttribute(schema.getMatchingRules(), userAttrs,
         operationalAttrs, matchingRulesType, includeSchemaFile, false,
         ignoreShowAllOption);
 
@@ -584,7 +583,7 @@
      * updates to fail. This means that you'll always have to explicitly request
      * these attributes in order to be able to see them.
      */
-    buildSchemaAttribute(schema.getSyntaxes().values(), userAttrs,
+    buildSchemaAttribute(schema.getSyntaxes(), userAttrs,
         operationalAttrs, ldapSyntaxesType, includeSchemaFile, false, true);
     buildSchemaAttribute(schema.getNameFormsByNameOrOID().values(), userAttrs,
         operationalAttrs, nameFormsType, includeSchemaFile, false, true);
@@ -775,22 +774,8 @@
           {
             for (ByteString v : a)
             {
-              AttributeType type;
-              try
-              {
-                type = AttributeTypeSyntax.decodeAttributeType(v, newSchema, false);
-              }
-              catch (DirectoryException de)
-              {
-                logger.traceException(de);
-
-                LocalizableMessage message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_ATTRTYPE.get(
-                    v, de.getMessageObject());
-                throw new DirectoryException(
-                    ResultCode.INVALID_ATTRIBUTE_SYNTAX, message, de);
-              }
-
-              addAttributeType(type, newSchema, modifiedSchemaFiles);
+              AttributeType attributeType = newSchema.parseAttributeType(v.toString());
+              addAttributeType(attributeType, newSchema, modifiedSchemaFiles);
             }
           }
           else if (at.equals(objectClassesType))
@@ -907,10 +892,9 @@
           {
             for (ByteString v : a)
             {
-              LDAPSyntaxDescription lsd;
               try
               {
-                lsd = LDAPSyntaxDescriptionSyntax.decodeLDAPSyntax(v, serverContext, newSchema, false, false);
+                addLdapSyntaxDescription(v.toString(), newSchema, modifiedSchemaFiles);
               }
               catch (DirectoryException de)
               {
@@ -921,7 +905,6 @@
                 throw new DirectoryException(
                     ResultCode.INVALID_ATTRIBUTE_SYNTAX, message, de);
               }
-              addLdapSyntaxDescription(lsd, newSchema, modifiedSchemaFiles);
             }
           }
           else
@@ -948,23 +931,8 @@
           {
             for (ByteString v : a)
             {
-              AttributeType type;
-              try
-              {
-                type = AttributeTypeSyntax.decodeAttributeType(v, newSchema, false);
-              }
-              catch (DirectoryException de)
-              {
-                logger.traceException(de);
-
-                LocalizableMessage message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_ATTRTYPE.get(
-                    v, de.getMessageObject());
-                throw new DirectoryException(
-                    ResultCode.INVALID_ATTRIBUTE_SYNTAX, message, de);
-              }
-
-              removeAttributeType(type, newSchema, mods, pos,
-                  modifiedSchemaFiles);
+              AttributeType type = newSchema.parseAttributeType(v.toString());
+              removeAttributeType(type, newSchema, modifiedSchemaFiles);
             }
           }
           else if (at.equals(objectClassesType))
@@ -1082,10 +1050,9 @@
           {
             for (ByteString v : a)
             {
-              LDAPSyntaxDescription lsd;
               try
               {
-                lsd = LDAPSyntaxDescriptionSyntax.decodeLDAPSyntax(v, serverContext, newSchema, false, true);
+                removeLdapSyntaxDescription(v.toString(), newSchema, modifiedSchemaFiles);
               }
               catch (DirectoryException de)
               {
@@ -1097,7 +1064,6 @@
                 throw new DirectoryException(
                     ResultCode.INVALID_ATTRIBUTE_SYNTAX, message, de);
               }
-              removeLdapSyntaxDescription(lsd, newSchema, modifiedSchemaFiles);
             }
           }
           else
@@ -1234,24 +1200,20 @@
    *                              the provided attribute type to the server
    *                              schema.
    */
-  private void addAttributeType(AttributeType attributeType, Schema schema,
-                                Set<String> modifiedSchemaFiles)
+  private void addAttributeType(AttributeType attributeType, Schema schema, Set<String> modifiedSchemaFiles)
           throws DirectoryException
   {
-    // First, see if the specified attribute type already exists.  We'll check
-    // the OID and all of the names, which means that it's possible there could
-    // be more than one match (although if there is, then we'll refuse the
-    // operation).
-    AttributeType existingType =
-         schema.getAttributeType(attributeType.getOID());
-    for (String name : attributeType.getNormalizedNames())
+    // Check if there is only a single attribute type for each name
+    // This is not checked by the SDK schema.
+    AttributeType existingType = schema.getAttributeType(attributeType.getOID());
+    for (String name : attributeType.getNames())
     {
       AttributeType t = schema.getAttributeType(name);
-      if (t == null)
+      if (t.isPlaceHolder())
       {
         continue;
       }
-      else if (existingType == null)
+      if (existingType.isPlaceHolder())
       {
         existingType = t;
       }
@@ -1260,89 +1222,56 @@
         // NOTE:  We really do want to use "!=" instead of "! t.equals()"
         // because we want to check whether it's the same object instance, not
         // just a logical equivalent.
-        LocalizableMessage message = ERR_SCHEMA_MODIFY_MULTIPLE_CONFLICTS_FOR_ADD_ATTRTYPE.
-            get(attributeType.getNameOrOID(), existingType.getNameOrOID(),
-                t.getNameOrOID());
+        LocalizableMessage message = ERR_SCHEMA_MODIFY_MULTIPLE_CONFLICTS_FOR_ADD_ATTRTYPE.get(
+            attributeType.getNameOrOID(), existingType.getNameOrOID(), t.getNameOrOID());
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
       }
     }
 
-
-    // Make sure that the new attribute type doesn't reference an undefined
-    // or OBSOLETE superior attribute type.
+    // Make sure that the new attribute type doesn't reference an
+    // OBSOLETE superior attribute type.
     AttributeType superiorType = attributeType.getSuperiorType();
-    if (superiorType != null)
+    if (superiorType != null && superiorType.isObsolete())
     {
-      if (! schema.hasAttributeType(superiorType.getOID()))
-      {
-        LocalizableMessage message = ERR_SCHEMA_MODIFY_UNDEFINED_SUPERIOR_ATTRIBUTE_TYPE.
-            get(attributeType.getNameOrOID(), superiorType.getNameOrOID());
-        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
-      }
-      else if (superiorType.isObsolete())
-      {
-        LocalizableMessage message = ERR_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE.
-            get(attributeType.getNameOrOID(), superiorType.getNameOrOID());
-        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-      }
+      LocalizableMessage message = ERR_SCHEMA_MODIFY_OBSOLETE_SUPERIOR_ATTRIBUTE_TYPE.get(
+          attributeType.getNameOrOID(), superiorType.getNameOrOID());
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
     }
 
-
     // Make sure that none of the associated matching rules are marked OBSOLETE.
-    MatchingRule mr = attributeType.getEqualityMatchingRule();
-    if (mr != null && mr.isObsolete())
-    {
-      LocalizableMessage message = ERR_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR.get(
-          attributeType.getNameOrOID(), mr.getNameOrOID());
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-    }
-
-    mr = attributeType.getOrderingMatchingRule();
-    if (mr != null && mr.isObsolete())
-    {
-      LocalizableMessage message = ERR_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR.get(
-          attributeType.getNameOrOID(), mr.getNameOrOID());
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-    }
-
-    mr = attributeType.getSubstringMatchingRule();
-    if (mr != null && mr.isObsolete())
-    {
-      LocalizableMessage message = ERR_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR.get(
-          attributeType.getNameOrOID(), mr.getNameOrOID());
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-    }
-
-    mr = attributeType.getApproximateMatchingRule();
-    if (mr != null && mr.isObsolete())
-    {
-      LocalizableMessage message = ERR_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR.get(
-          attributeType.getNameOrOID(), mr.getNameOrOID());
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
-    }
-
+    throwIfObsoleteMatchingRule(attributeType, attributeType.getEqualityMatchingRule());
+    throwIfObsoleteMatchingRule(attributeType, attributeType.getOrderingMatchingRule());
+    throwIfObsoleteMatchingRule(attributeType, attributeType.getSubstringMatchingRule());
+    throwIfObsoleteMatchingRule(attributeType, attributeType.getApproximateMatchingRule());
 
     // If there is no existing type, then we're adding a new attribute.
     // Otherwise, we're replacing an existing one.
-    if (existingType == null)
+    if (existingType.isPlaceHolder())
     {
-      schema.registerAttributeType(attributeType, false);
-      addNewSchemaElement(modifiedSchemaFiles, attributeType);
+      String schemaFile = addNewSchemaElement(modifiedSchemaFiles, new SomeSchemaElement(attributeType));
+      schema.registerAttributeType(attributeType, schemaFile, false);
     }
     else
     {
       schema.deregisterAttributeType(existingType);
-      schema.registerAttributeType(attributeType, false);
-      schema.rebuildDependentElements(existingType);
-      replaceExistingSchemaElement(modifiedSchemaFiles, attributeType,
-          existingType);
+
+      String schemaFile = replaceExistingSchemaElement(
+          modifiedSchemaFiles, new SomeSchemaElement(attributeType), new SomeSchemaElement(existingType));
+      schema.registerAttributeType(attributeType, schemaFile, false);
+      schema.rebuildDependentElements(new SomeSchemaElement(existingType));
     }
   }
 
+  private void throwIfObsoleteMatchingRule(AttributeType attributeType, MatchingRule mr) throws DirectoryException
+  {
+    if (mr != null && mr.isObsolete())
+    {
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
+          ERR_SCHEMA_MODIFY_ATTRTYPE_OBSOLETE_MR.get(attributeType.getNameOrOID(), mr.getNameOrOID()));
+    }
+  }
 
-
-  private void addNewSchemaElement(Set<String> modifiedSchemaFiles,
-      SchemaFileElement elem)
+  private void addNewSchemaElement(Set<String> modifiedSchemaFiles, SchemaFileElement elem)
   {
     String schemaFile = getSchemaFile(elem);
     if (schemaFile == null || schemaFile.length() == 0)
@@ -1350,11 +1279,17 @@
       schemaFile = FILE_USER_SCHEMA_ELEMENTS;
       setSchemaFile(elem, schemaFile);
     }
-
     modifiedSchemaFiles.add(schemaFile);
   }
 
-
+  /** Update list of modified files and return the schema file to use for the added element (may be null). */
+  private String addNewSchemaElement(Set<String> modifiedSchemaFiles, SomeSchemaElement elem)
+  {
+    String schemaFile = elem.getSchemaFile();
+    String finalFile = schemaFile != null ? schemaFile : FILE_USER_SCHEMA_ELEMENTS;
+    modifiedSchemaFiles.add(finalFile);
+    return schemaFile == null ? finalFile : null;
+  }
 
   private <T extends SchemaFileElement> void replaceExistingSchemaElement(
       Set<String> modifiedSchemaFiles, T newElem, T existingElem)
@@ -1382,7 +1317,32 @@
     }
   }
 
-
+  /** Update list of modified files and return the schema file to use for the new element (may be null). */
+  private String replaceExistingSchemaElement(
+      Set<String> modifiedSchemaFiles, SomeSchemaElement newElem, SomeSchemaElement existingElem)
+  {
+    String newSchemaFile = newElem.getSchemaFile();
+    String oldSchemaFile = existingElem.getSchemaFile();
+    if (newSchemaFile == null)
+    {
+      if (oldSchemaFile == null)
+      {
+        oldSchemaFile = FILE_USER_SCHEMA_ELEMENTS;
+      }
+      modifiedSchemaFiles.add(oldSchemaFile);
+      return oldSchemaFile;
+    }
+    else if (oldSchemaFile == null || oldSchemaFile.equals(newSchemaFile))
+    {
+      modifiedSchemaFiles.add(newSchemaFile);
+    }
+    else
+    {
+      modifiedSchemaFiles.add(newSchemaFile);
+      modifiedSchemaFiles.add(oldSchemaFile);
+    }
+    return null;
+  }
 
   /**
    * Handles all processing required to remove the provided attribute type from
@@ -1411,67 +1371,22 @@
    *                              the provided attribute type from the server
    *                              schema.
    */
-  private void removeAttributeType(AttributeType attributeType, Schema schema,
-                                   ArrayList<Modification> modifications,
-                                   int currentPosition,
-                                   Set<String> modifiedSchemaFiles)
+  private void removeAttributeType(AttributeType attributeType, Schema schema, Set<String> modifiedSchemaFiles)
           throws DirectoryException
   {
     // See if the specified attribute type is actually defined in the server
     // schema.  If not, then fail.
     AttributeType removeType = schema.getAttributeType(attributeType.getOID());
-    if (removeType == null || !removeType.equals(attributeType))
+    if (removeType.isPlaceHolder() || !removeType.equals(attributeType))
     {
       LocalizableMessage message = ERR_SCHEMA_MODIFY_REMOVE_NO_SUCH_ATTRIBUTE_TYPE.get(
           attributeType.getNameOrOID());
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
     }
 
-
-    // See if there is another modification later to add the attribute type back
-    // into the schema.  If so, then it's a replace and we should ignore the
-    // remove because adding it back will handle the replace.
-    for (int i=currentPosition+1; i < modifications.size(); i++)
-    {
-      Modification m = modifications.get(i);
-      Attribute    a = m.getAttribute();
-
-      if (m.getModificationType() != ModificationType.ADD
-          || !a.getAttributeType().equals(attributeTypesType))
-      {
-        continue;
-      }
-
-      for (ByteString v : a)
-      {
-        AttributeType at;
-        try
-        {
-          at = AttributeTypeSyntax.decodeAttributeType(v, schema, true);
-        }
-        catch (DirectoryException de)
-        {
-          logger.traceException(de);
-
-          LocalizableMessage message = ERR_SCHEMA_MODIFY_CANNOT_DECODE_ATTRTYPE.get(
-              v, de.getMessageObject());
-          throw new DirectoryException(
-                         ResultCode.INVALID_ATTRIBUTE_SYNTAX, message, de);
-        }
-
-        if (attributeType.getOID().equals(at.getOID()))
-        {
-          // We found a match where the attribute type is added back later, so
-          // we don't need to do anything else here.
-          return;
-        }
-      }
-    }
-
-
     // Make sure that the attribute type isn't used as the superior type for
     // any other attributes.
-    for (AttributeType at : schema.getAttributeTypes().values())
+    for (AttributeType at : schema.getAttributeTypes())
     {
       AttributeType superiorType = at.getSuperiorType();
       if (superiorType != null && superiorType.equals(removeType))
@@ -1482,7 +1397,6 @@
       }
     }
 
-
     // Make sure that the attribute type isn't used as a required or optional
     // attribute type in any objectclass.
     for (ObjectClass oc : schema.getObjectClasses().values())
@@ -1496,7 +1410,6 @@
       }
     }
 
-
     // Make sure that the attribute type isn't used as a required or optional
     // attribute type in any name form.
     for (List<NameForm> mappedForms :
@@ -1515,7 +1428,6 @@
       }
     }
 
-
     // Make sure that the attribute type isn't used as a required, optional, or
     // prohibited attribute type in any DIT content rule.
     for (DITContentRule dcr : schema.getDITContentRules().values())
@@ -1530,7 +1442,6 @@
       }
     }
 
-
     // Make sure that the attribute type isn't referenced by any matching rule
     // use.
     for (MatchingRuleUse mru : schema.getMatchingRuleUses().values())
@@ -1543,11 +1454,10 @@
       }
     }
 
-
     // If we've gotten here, then it's OK to remove the attribute type from
     // the schema.
     schema.deregisterAttributeType(removeType);
-    String schemaFile = getSchemaFile(removeType);
+    String schemaFile = new SomeSchemaElement(removeType).getSchemaFile();
     if (schemaFile != null)
     {
       modifiedSchemaFiles.add(schemaFile);
@@ -1672,8 +1582,7 @@
       schema.deregisterObjectClass(existingClass);
       schema.registerObjectClass(objectClass, false);
       schema.rebuildDependentElements(existingClass);
-      replaceExistingSchemaElement(modifiedSchemaFiles, objectClass,
-          existingClass);
+      replaceExistingSchemaElement(modifiedSchemaFiles, objectClass, existingClass);
     }
   }
 
@@ -2691,80 +2600,76 @@
     }
   }
 
-
-
   /**
-   * Handles all processing required for adding the provided ldap syntax
-   * description to the given schema, replacing an existing ldap syntax
-   * description if necessary, and ensuring all other metadata is properly
-   * updated.
+   * Handles all processing required for adding the provided ldap syntax description to the given
+   * schema, replacing an existing ldap syntax description if necessary, and ensuring all other
+   * metadata is properly updated.
    *
-   * @param  ldapSyntaxDesc   The ldap syntax description to add or replace in
-   *                               the server schema.
-   * @param  schema               The schema to which the name form should be
-   *                              added.
-   * @param  modifiedSchemaFiles  The names of the schema files containing
-   *                              schema elements that have been updated as part
-   *                              of the schema modification.
-   *
-   * @throws  DirectoryException  If a problem occurs while attempting to add
-   *                              the provided ldap syntax description to the
-   *                              server schema.
+   * @param definition
+   *          The definition of the ldap syntax description to add or replace in the server schema.
+   * @param schema
+   *          The schema to which the LDAP syntax description should be added.
+   * @param modifiedSchemaFiles
+   *          The names of the schema files containing schema elements that have been updated as
+   *          part of the schema modification.
+   * @throws DirectoryException
+   *           If a problem occurs while attempting to add the provided ldap syntax description to
+   *           the server schema.
    */
-  private void addLdapSyntaxDescription(LDAPSyntaxDescription ldapSyntaxDesc,
-                           Schema schema,
-                           Set<String> modifiedSchemaFiles)
+  private void addLdapSyntaxDescription(final String definition, Schema schema, Set<String> modifiedSchemaFiles)
           throws DirectoryException
   {
-       //Check if there is an existing syntax with this oid.
-    String oid = ldapSyntaxDesc.getSyntax().getOID();
+    // Check if there is an existing syntax with this oid.
+    String oid =
+        Schema.parseOID(definition, ResultCode.INVALID_ATTRIBUTE_SYNTAX, ERR_ATTR_SYNTAX_LDAPSYNTAX_EMPTY_VALUE);
 
     // We allow only unimplemented syntaxes to be substituted.
-    if(schema.getSyntax(oid) !=null)
+    if (schema.hasSyntax(oid))
     {
-      LocalizableMessage message =
-          ERR_ATTR_SYNTAX_INVALID_LDAP_SYNTAX.get(ldapSyntaxDesc, oid);
-      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
-                                     message);
+      LocalizableMessage message = ERR_ATTR_SYNTAX_INVALID_LDAP_SYNTAX.get(definition, oid);
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
     }
 
     LDAPSyntaxDescription existingLSD = schema.getLdapSyntaxDescription(oid);
-    SchemaUpdater schemaUpdater = serverContext.getSchemaUpdater();
-    org.forgerock.opendj.ldap.schema.Schema newSchema = null;
-
     // If there is no existing lsd, then we're adding a new ldapsyntax.
     // Otherwise, we're replacing an existing one.
     if (existingLSD == null)
     {
-      schema.registerLdapSyntaxDescription(ldapSyntaxDesc, false);
-      addNewSchemaElement(modifiedSchemaFiles, ldapSyntaxDesc);
+      String def = Schema.addSchemaFileToElementDefinitionIfAbsent(definition, FILE_USER_SCHEMA_ELEMENTS);
+      schema.registerLdapSyntaxDescription(def, false);
 
-      // update schema NG
-      newSchema = schemaUpdater.getSchemaBuilder().buildSyntax(ldapSyntaxDesc.getSyntax()).addToSchema().toSchema();
-      schemaUpdater.updateSchema(newSchema);
+      String schemaFile = getSchemaFile(schema.getLdapSyntaxDescription(oid));
+      modifiedSchemaFiles.add(schemaFile);
     }
     else
     {
       schema.deregisterLdapSyntaxDescription(existingLSD);
-      schema.registerLdapSyntaxDescription(ldapSyntaxDesc, false);
-      // update schema NG
-      SchemaBuilder schemaBuilder = schemaUpdater.getSchemaBuilder();
-      schemaBuilder.removeSyntax(oid);
-      newSchema = schemaBuilder.buildSyntax(ldapSyntaxDesc.getSyntax()).addToSchema().toSchema();
-      schemaUpdater.updateSchema(newSchema);
+
+      String oldSchemaFile = getSchemaFile(existingLSD);
+      String schemaFile = oldSchemaFile != null && oldSchemaFile.length() > 0 ?
+          oldSchemaFile : FILE_USER_SCHEMA_ELEMENTS;
+      String def = Schema.addSchemaFileToElementDefinitionIfAbsent(definition, schemaFile);
+      schema.registerLdapSyntaxDescription(def, false);
 
       schema.rebuildDependentElements(existingLSD);
-      replaceExistingSchemaElement(modifiedSchemaFiles, ldapSyntaxDesc, existingLSD);
+      String newSchemaFile = getSchemaFile(schema.getLdapSyntaxDescription(oid));
+
+      if (oldSchemaFile != null)
+      {
+        modifiedSchemaFiles.add(oldSchemaFile);
+      }
+      if (newSchemaFile != null)
+      {
+        modifiedSchemaFiles.add(newSchemaFile);
+      }
     }
   }
 
 
 
   /** Gets rid of the ldap syntax description. */
-  private void removeLdapSyntaxDescription(LDAPSyntaxDescription ldapSyntaxDesc,
-                                    Schema schema,
-                                    Set<String> modifiedSchemaFiles)
-          throws DirectoryException
+  private void removeLdapSyntaxDescription(String definition, Schema schema, Set<String> modifiedSchemaFiles)
+      throws DirectoryException
   {
     /*
      * See if the specified ldap syntax description is actually defined in the
@@ -2772,22 +2677,17 @@
      * part of the ldapsyntaxes attribute. A virtual value is not searched and
      * hence never deleted.
      */
-    String oid = ldapSyntaxDesc.getSyntax().getOID();
-    LDAPSyntaxDescription removeLSD = schema.getLdapSyntaxDescription(oid);
+    String oid =
+        Schema.parseOID(definition, ResultCode.INVALID_ATTRIBUTE_SYNTAX, ERR_ATTR_SYNTAX_LDAPSYNTAX_EMPTY_VALUE);
 
-    if (removeLSD == null || !removeLSD.equals(ldapSyntaxDesc))
+    LDAPSyntaxDescription removeLSD = schema.getLdapSyntaxDescription(oid);
+    if (removeLSD == null)
     {
       LocalizableMessage message =
           ERR_SCHEMA_MODIFY_REMOVE_NO_SUCH_LSD.get(oid);
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
     }
 
-    // update schema NG
-    SchemaUpdater schemaUpdater = serverContext.getSchemaUpdater();
-    SchemaBuilder schemaBuilder = schemaUpdater.getSchemaBuilder();
-    schemaBuilder.removeSyntax(oid);
-    schemaUpdater.updateSchema(schemaBuilder.toSchema());
-
     schema.deregisterLdapSyntaxDescription(removeLSD);
     String schemaFile = getSchemaFile(removeLSD);
     if (schemaFile != null)
@@ -2886,9 +2786,10 @@
     // same file are written before the subordinate types.
     Set<AttributeType> addedTypes = new HashSet<>();
     values = new LinkedHashSet<>();
-    for (AttributeType at : schema.getAttributeTypes().values())
+    for (AttributeType at : schema.getAttributeTypes())
     {
-      if (schemaFile.equals(getSchemaFile(at)))
+      String atSchemaFile = new SomeSchemaElement(at).getSchemaFile();
+      if (schemaFile.equals(atSchemaFile))
       {
         addAttrTypeToSchemaFile(schema, schemaFile, at, values, addedTypes, 0);
       }
@@ -3070,7 +2971,7 @@
 
     AttributeType superiorType = attributeType.getSuperiorType();
     if (superiorType != null &&
-        schemaFile.equals(getSchemaFile(superiorType)) &&
+        schemaFile.equals(new SomeSchemaElement(attributeType).getSchemaFile()) &&
         !addedTypes.contains(superiorType))
     {
       addAttrTypeToSchemaFile(schema, schemaFile, superiorType, values,
@@ -3618,8 +3519,8 @@
   private void importEntry(Entry newSchemaEntry)
           throws DirectoryException
   {
-    Schema schema = DirectoryServer.getSchema();
-    Schema newSchema = DirectoryServer.getSchema().duplicate();
+    Schema schema = serverContext.getSchema();
+    Schema newSchema = schema.duplicate();
     TreeSet<String> modifiedSchemaFiles = new TreeSet<>();
 
     // Get the attributeTypes attribute from the entry.
@@ -3628,8 +3529,7 @@
     {
       attrTypeSyntax = CoreSchema.getAttributeTypeDescriptionSyntax();
     }
-    AttributeType attributeAttrType = DirectoryServer.getAttributeTypeOrDefault(
-        ATTR_ATTRIBUTE_TYPES_LC, ATTR_ATTRIBUTE_TYPES, attrTypeSyntax);
+    AttributeType attributeAttrType = CoreSchema.getAttributeTypesAttributeType();
 
     // loop on the attribute types in the entry just received
     // and add them in the existing schema.
@@ -3641,8 +3541,8 @@
       for (ByteString v : a)
       {
         // Parse the attribute type.
-        AttributeType attrType = AttributeTypeSyntax.decodeAttributeType(v, schema, false);
-        String schemaFile = getSchemaFile(attrType);
+        AttributeType attrType = schema.parseAttributeType(v.toString());
+        String schemaFile = new SomeSchemaElement(attrType).getSchemaFile();
         if (CONFIG_SCHEMA_ELEMENTS_FILE.equals(schemaFile))
         {
           // Don't import the file containing the definitions of the
@@ -3676,14 +3576,10 @@
 
     // loop on all the attribute types in the current schema and delete
     // them from the new schema if they are not in the imported schema entry.
-    ConcurrentHashMap<String, AttributeType> currentAttrTypes =
-      newSchema.getAttributeTypes();
-
-    for (AttributeType removeType : currentAttrTypes.values())
+    for (AttributeType removeType : newSchema.getAttributeTypes())
     {
-      String schemaFile = getSchemaFile(removeType);
-      if (CONFIG_SCHEMA_ELEMENTS_FILE.equals(schemaFile)
-          || CORE_SCHEMA_ELEMENTS_FILE.equals(schemaFile))
+      String schemaFile = new SomeSchemaElement(removeType).getSchemaFile();
+      if (CONFIG_SCHEMA_ELEMENTS_FILE.equals(schemaFile) || CORE_SCHEMA_ELEMENTS_FILE.equals(schemaFile))
       {
         // Don't import the file containing the definitions of the
         // Schema elements used for configuration because these
@@ -3696,7 +3592,7 @@
         newSchema.deregisterAttributeType(removeType);
         if (schemaFile != null)
         {
-              modifiedSchemaFiles.add(schemaFile);
+          modifiedSchemaFiles.add(schemaFile);
         }
       }
     }
@@ -3708,8 +3604,7 @@
     {
       ocSyntax = CoreSchema.getObjectClassDescriptionSyntax();
     }
-    AttributeType objectclassAttrType = DirectoryServer.getAttributeTypeOrDefault(
-        ATTR_OBJECTCLASSES_LC, ATTR_OBJECTCLASSES, ocSyntax);
+    AttributeType objectclassAttrType = CoreSchema.getObjectClassAttributeType();
 
     oidList.clear();
     List<Attribute> ocList = newSchemaEntry.getAttribute(objectclassAttrType);
@@ -3761,10 +3656,9 @@
       }
     }
 
-    // loop on all the attribute types in the current schema and delete
+    // loop on all the object classes in the current schema and delete
     // them from the new schema if they are not in the imported schema entry.
-    ConcurrentHashMap<String, ObjectClass> currentObjectClasses =
-      newSchema.getObjectClasses();
+    ConcurrentHashMap<String, ObjectClass> currentObjectClasses = newSchema.getObjectClasses();
 
     for (ObjectClass removeClass : currentObjectClasses.values())
     {

--
Gitblit v1.10.0