From 383ff591182ce9730728c938d9b86e95f86ad676 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Fri, 09 Sep 2016 09:45:24 +0000
Subject: [PATCH] OPENDJ-3089 Update SchemaLoader and RemoteSchemaLoader to use SchemaHandler and SDK Schema

---
 opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java                       |    4 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java         |   10 +
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java   |   82 ++++-----------
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java       |    7 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java         |  119 ++++++++++-------------
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java |   21 +--
 6 files changed, 96 insertions(+), 147 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java
index 6c755e8..624d7ec 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromConnection.java
@@ -50,6 +50,7 @@
 import org.forgerock.opendj.ldap.LdapException;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 import org.forgerock.opendj.server.config.client.AdministrationConnectorCfgClient;
 import org.forgerock.opendj.server.config.client.BackendCfgClient;
@@ -311,12 +312,12 @@
     {
       try
       {
-        readSchema(connWrapper);
-        if (getSchema() != null)
+        Schema schema = readSchema(connWrapper);
+        if (schema != null)
         {
           // Update the schema: so that when we call the server code the
           // latest schema read on the server we are managing is used.
-          DirectoryServer.setSchema(getSchema());
+          DirectoryServer.setSchema(schema);
         }
       }
       catch (OpenDsException oe)
@@ -629,20 +630,12 @@
    * @throws OpenDsException
    *           if an error occurs reading the schema.
    */
-  private void readSchema(ConnectionWrapper connWrapper) throws OpenDsException
+  private Schema readSchema(ConnectionWrapper connWrapper) throws OpenDsException
   {
     try
     {
-      if (isLocal)
-      {
-        super.readSchema();
-      }
-      else
-      {
-        RemoteSchemaLoader loader = new RemoteSchemaLoader();
-        loader.readSchema(connWrapper);
-        schema = loader.getSchema();
-      }
+      schema = isLocal ? super.readSchema() : new RemoteSchemaLoader().readSchema(connWrapper);
+      return schema;
     }
     catch (LdapException e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java
index e5fda02..bdec4ca 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigFromFile.java
@@ -34,6 +34,7 @@
 import org.forgerock.opendj.config.server.ConfigException;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.opendj.server.config.server.AdministrationConnectorCfg;
 import org.forgerock.opendj.server.config.server.BackendCfg;
 import org.forgerock.opendj.server.config.server.BackendIndexCfg;
@@ -132,12 +133,12 @@
     {
       try
       {
-        readSchema();
-        if (getSchema() != null)
+        Schema schema = readSchema();
+        if (schema != null)
         {
           // Update the schema: so that when we call the server code the
           // latest schema read on the server we are managing is used.
-          DirectoryServer.setSchema(getSchema());
+          DirectoryServer.setSchema(schema);
         }
       }
       catch (final OpenDsException oe)
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java
index 91f773b..e8ddc02 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/ConfigReader.java
@@ -31,6 +31,7 @@
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.config.server.ConfigException;
 import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.opendj.server.config.meta.AdministrationConnectorCfgDefn;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor;
@@ -42,7 +43,6 @@
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
 import org.opends.server.types.OpenDsException;
-import org.opends.server.types.Schema;
 
 /**
  * An abstract class providing some common interface for the class that read
@@ -251,18 +251,20 @@
 
   /**
    * Reads the schema from the files.
+   *
+   * @return the schema
    * @throws ConfigException if an error occurs reading the schema.
    * @throws InitializationException if an error occurs initializing
    * configuration to read schema.
    * @throws DirectoryException if there is an error registering the minimal
    * objectclasses.
    */
-  protected void readSchema() throws ConfigException, InitializationException,
+  protected Schema readSchema() throws ConfigException, InitializationException,
   DirectoryException
   {
     SchemaLoader loader = new SchemaLoader();
-    loader.readSchema();
-    schema = loader.getSchema();
+    schema = loader.readSchema();
+    return schema;
   }
 
   /**
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
index cc59818..48f1e2e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/RemoteSchemaLoader.java
@@ -21,11 +21,8 @@
 import static org.forgerock.opendj.ldap.schema.CoreSchema.*;
 import static org.forgerock.opendj.ldap.schema.Schema.*;
 import static org.opends.server.config.ConfigConstants.*;
-import static org.opends.server.config.ConfigConstants.ATTR_ATTRIBUTE_TYPES;
-import static org.opends.server.config.ConfigConstants.ATTR_LDAP_SYNTAXES;
 import static org.opends.server.schema.SchemaConstants.*;
 
-import java.util.Arrays;
 import java.util.Iterator;
 
 import org.forgerock.opendj.config.server.ConfigException;
@@ -37,20 +34,15 @@
 import org.forgerock.opendj.ldap.LdapException;
 import org.forgerock.opendj.ldap.requests.SearchRequest;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
-import org.forgerock.opendj.ldap.schema.MatchingRule;
 import org.forgerock.opendj.ldap.schema.MatchingRuleImpl;
+import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.opendj.ldap.schema.SchemaBuilder;
 import org.opends.admin.ads.util.ConnectionWrapper;
-import org.opends.server.api.AttributeSyntax;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.ServerContext;
 import org.opends.server.replication.plugin.HistoricalCsnOrderingMatchingRuleImpl;
 import org.opends.server.schema.AciSyntax;
 import org.opends.server.schema.SubtreeSpecificationSyntax;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
-import org.opends.server.types.Schema;
-import org.opends.server.types.Schema.SchemaUpdater;
 
 /** Class used to retrieve the schema from the schema files. */
 public class RemoteSchemaLoader extends SchemaLoader
@@ -70,10 +62,11 @@
   }
 
   /**
-   * Reads the schema.
+   * Reads and returns the schema.
    *
    * @param connWrapper
    *          the connection to be used to load the schema.
+   * @return the schema
    * @throws LdapException
    *           if an error occurs reading the schema.
    * @throws DirectoryException
@@ -83,72 +76,45 @@
    * @throws ConfigException
    *           if an error occurs loading the configuration required to use the schema classes.
    */
-  public void readSchema(ConnectionWrapper connWrapper) throws LdapException, DirectoryException,
+  public Schema readSchema(ConnectionWrapper connWrapper) throws LdapException, DirectoryException,
       InitializationException, ConfigException
   {
-    schema = getBaseSchema();
+    Schema baseSchema = getBaseSchema();
+    SchemaBuilder schemaBuilder = new SchemaBuilder(baseSchema);
+
     // Add missing matching rules and attribute syntaxes to base schema to allow read of remote server schema
     // (see OPENDJ-1122 for more details)
-    addMissingSyntaxesToBaseSchema(new AciSyntax(), new SubtreeSpecificationSyntax());
-    addMissingMatchingRuleToBaseSchema("1.3.6.1.4.1.26027.1.4.4", "historicalCsnOrderingMatch",
+    AciSyntax.addAciSyntax(schemaBuilder);
+    SubtreeSpecificationSyntax.addSubtreeSpecificationSyntax(schemaBuilder);
+    addMatchingRuleIfMissing(schemaBuilder, baseSchema, "1.3.6.1.4.1.26027.1.4.4", "historicalCsnOrderingMatch",
         "1.3.6.1.4.1.1466.115.121.1.40", new HistoricalCsnOrderingMatchingRuleImpl());
 
+    // Add remote schema entry
     final SearchRequest request = newSearchRequest(
         DN.valueOf(DN_DEFAULT_SCHEMA_ROOT), BASE_OBJECT, Filter.alwaysTrue(),
         ATTR_LDAP_SYNTAXES, ATTR_ATTRIBUTE_TYPES, ATTR_OBJECTCLASSES);
     final SearchResultEntry entry = connWrapper.getConnection().searchSingleEntry(request);
-
     removeNonOpenDjOrOpenDsSyntaxes(entry);
-    schema.updateSchema(new SchemaUpdater()
-    {
-      @Override
-      public org.forgerock.opendj.ldap.schema.Schema update(SchemaBuilder builder)
-      {
-        builder.addSchema(entry, true);
-        return builder.toSchema();
-      }
-    });
+    schemaBuilder.addSchema(entry, true);
+
+    return buildSchema(schemaBuilder);
+
   }
 
-  private void addMissingSyntaxesToBaseSchema(final AttributeSyntax<?>... syntaxes)
-      throws DirectoryException, InitializationException, ConfigException
+  private void addMatchingRuleIfMissing(SchemaBuilder schemaBuilder, Schema baseSchema, final String oid,
+      final String name, final String syntaxOID, final MatchingRuleImpl impl) throws InitializationException,
+      ConfigException, DirectoryException
   {
-    for (AttributeSyntax<?> syntax : syntaxes)
+    if (!baseSchema.hasMatchingRule(name))
     {
-      final ServerContext serverContext = DirectoryServer.getInstance().getServerContext();
-      final org.forgerock.opendj.ldap.schema.Schema schemaNG = serverContext.getSchemaNG();
-      if (!schemaNG.hasSyntax(syntax.getOID()))
-      {
-        syntax.initializeSyntax(null, serverContext);
-      }
-      schema.registerSyntax(syntax.getSDKSyntax(schemaNG), true);
+      schemaBuilder.buildMatchingRule(oid)
+        .names(name)
+        .syntaxOID(syntaxOID)
+        .implementation(impl)
+        .addToSchema();
     }
   }
 
-  private void addMissingMatchingRuleToBaseSchema(final String oid, final String name, final String syntaxOID,
-      final MatchingRuleImpl impl)
-      throws InitializationException, ConfigException, DirectoryException
-  {
-    final org.forgerock.opendj.ldap.schema.Schema schemaNG = schema.getSchemaNG();
-    final MatchingRule matchingRule;
-    if (schemaNG.hasMatchingRule(name))
-    {
-      matchingRule = schemaNG.getMatchingRule(name);
-    }
-    else
-    {
-      matchingRule = new SchemaBuilder(schemaNG)
-          .buildMatchingRule(oid)
-            .names(name)
-            .syntaxOID(syntaxOID)
-            .implementation(impl)
-          .addToSchema()
-          .toSchema()
-          .getMatchingRule(oid);
-    }
-    schema.registerMatchingRules(Arrays.asList(matchingRule), true);
-  }
-
   private void removeNonOpenDjOrOpenDsSyntaxes(final SearchResultEntry entry) throws DirectoryException
   {
     Attribute attribute = entry.getAttribute(AttributeDescription.create(getLDAPSyntaxesAttributeType()));
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java
index 6263a91..3ff69f3 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java
@@ -16,11 +16,12 @@
  */
 package org.opends.guitools.controlpanel.util;
 
+import static org.opends.messages.SchemaMessages.ERR_SCHEMA_HAS_WARNINGS;
 import static org.opends.messages.ConfigMessages.*;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -31,17 +32,17 @@
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.forgerock.opendj.ldap.schema.MatchingRule;
 import org.forgerock.opendj.ldap.schema.ObjectClass;
+import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.opendj.ldap.schema.SchemaBuilder;
 import org.forgerock.opendj.ldap.schema.Syntax;
+import org.forgerock.util.Utils;
 import org.opends.server.config.ConfigConstants;
 import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.SchemaConfigManager;
+import org.opends.server.core.SchemaHandler;
+import org.opends.server.core.ServerContext;
 import org.opends.server.schema.SchemaConstants;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
-import org.opends.server.types.Schema;
-
-import com.forgerock.opendj.util.OperatingSystem;
 
 /** Class used to retrieve the schema from the schema files. */
 public class SchemaLoader
@@ -63,13 +64,16 @@
   /** List of attribute syntaxes to keep in the schema. */
   protected final List<Syntax> syntaxesToKeep = new ArrayList<>();
 
+  private final ServerContext serverContext;
+
   /** Constructor. */
   public SchemaLoader()
   {
-    Schema sc = DirectoryServer.getSchema();
+    serverContext = DirectoryServer.getInstance().getServerContext();
+    Schema schema = serverContext.getSchemaHandler().getSchema();
     for (String name : OBJECTCLASS_TO_KEEP)
     {
-      ObjectClass oc = sc.getObjectClass(name);
+      ObjectClass oc = schema.getObjectClass(name);
       if (!oc.isPlaceHolder())
       {
         objectclassesToKeep.add(oc);
@@ -77,23 +81,19 @@
     }
     for (String name : ATTRIBUTES_TO_KEEP)
     {
-      if (sc.hasAttributeType(name))
+      if (schema.hasAttributeType(name))
       {
-        attributesToKeep.add(sc.getAttributeType(name));
+        attributesToKeep.add(schema.getAttributeType(name));
       }
     }
-    matchingRulesToKeep.addAll(sc.getMatchingRules());
-    syntaxesToKeep.addAll(sc.getSyntaxes());
-  }
-
-  private static String getSchemaDirectoryPath()
-  {
-    File schemaDir = DirectoryServer.getEnvironmentConfig().getSchemaDirectory();
-    return schemaDir != null ? schemaDir.getAbsolutePath() : null;
+    matchingRulesToKeep.addAll(schema.getMatchingRules());
+    syntaxesToKeep.addAll(schema.getSyntaxes());
   }
 
   /**
-   * Reads the schema.
+   * Reads and returns the schema.
+   *
+   * @return the schema
    *
    * @throws ConfigException
    *           if an error occurs reading the schema.
@@ -102,44 +102,41 @@
    * @throws DirectoryException
    *           if there is an error registering the minimal objectclasses.
    */
-  public void readSchema() throws DirectoryException, ConfigException, InitializationException
+  public Schema readSchema() throws DirectoryException, ConfigException, InitializationException
   {
-    schema = getBaseSchema();
+    SchemaHandler schemaHandler = serverContext.getSchemaHandler();
+    final File schemaDir = schemaHandler.getSchemaDirectoryPath();
+    final List<String> fileNames = getSchemaFileNames(schemaDir);
 
-    List<String> fileNames;
-    String schemaDirPath = getSchemaDirectoryPath();
+    // build the schema from schema files
+    Schema baseSchema = getBaseSchema();
+    SchemaBuilder schemaBuilder = new SchemaBuilder(baseSchema);
+    for (String schemaFile : fileNames)
+    {
+      schemaHandler.loadSchemaFileIntoSchemaBuilder(new File(schemaDir, schemaFile), schemaBuilder, baseSchema);
+    }
+    return buildSchema(schemaBuilder);
+  }
+
+  Schema buildSchema(SchemaBuilder schemaBuilder) throws InitializationException
+  {
+    schema = schemaBuilder.toSchema();
+    Collection<LocalizableMessage> warnings = schema.getWarnings();
+    if (!warnings.isEmpty())
+    {
+      throw new InitializationException(
+          ERR_SCHEMA_HAS_WARNINGS.get(warnings.size(), Utils.joinAsString("; ", warnings)));
+    }
+    return schema;
+  }
+
+  private List<String> getSchemaFileNames(final File schemaDir)
+      throws InitializationException
+  {
+    final List<String> fileNames;
     try
     {
-      // Load install directory schema
-      File schemaDir = new File(schemaDirPath);
-      if (schemaDirPath == null || !schemaDir.exists())
-      {
-        LocalizableMessage message = ERR_CONFIG_SCHEMA_NO_SCHEMA_DIR.get(schemaDirPath);
-        throw new InitializationException(message);
-      }
-      else if (!schemaDir.isDirectory())
-      {
-        LocalizableMessage message = ERR_CONFIG_SCHEMA_DIR_NOT_DIRECTORY.get(schemaDirPath);
-        throw new InitializationException(message);
-      }
-      FileFilter ldifFilesFilter = new FileFilter()
-      {
-        @Override
-        public boolean accept(File f)
-        {
-          if (f != null)
-          {
-            if (f.isDirectory())
-            {
-              return true;
-            }
-            return OperatingSystem.isWindows() ? f.getName().toLowerCase().endsWith(".ldif")
-                                               : f.getName().endsWith(".ldif");
-          }
-          return false;
-        }
-      };
-      File[] schemaFiles = schemaDir.listFiles(ldifFilesFilter);
+      File[] schemaFiles = schemaDir.listFiles(new SchemaHandler.SchemaFileFilter());
       fileNames = new ArrayList<>(schemaFiles.length);
       for (File f : schemaFiles)
       {
@@ -148,24 +145,12 @@
           fileNames.add(f.getName());
         }
       }
-
       Collections.sort(fileNames);
-    }
-    catch (InitializationException ie)
-    {
-      throw ie;
+      return fileNames;
     }
     catch (Exception e)
     {
-      throw new InitializationException(ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES.get(schemaDirPath, e.getMessage()), e);
-    }
-
-    // Iterate through the schema files and read them as an LDIF file containing a single entry.
-    // Then get the attributeTypes and objectClasses attributes from that entry
-    // and parse them to initialize the server schema.
-    for (String schemaFile : fileNames)
-    {
-      SchemaConfigManager.loadSchemaFile(schema, schemaFile);
+      throw new InitializationException(ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES.get(schemaDir, e.getMessage()), e);
     }
   }
 
@@ -198,7 +183,7 @@
       {
         builder.buildObjectClass(oc).addToSchemaOverwrite();
       }
-      return new Schema(builder.toSchema());
+      return builder.toSchema();
     }
     catch (LocalizedIllegalArgumentException e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
index e72e7af..087c8f4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaHandler.java
@@ -89,6 +89,7 @@
 import org.opends.server.util.SchemaUtils;
 import org.opends.server.util.StaticUtils;
 
+import com.forgerock.opendj.util.OperatingSystem;
 import com.sun.corba.se.spi.ior.WriteContents;
 
 /**
@@ -1012,7 +1013,8 @@
     @Override
     public boolean accept(File directory, String filename)
     {
-      return filename.endsWith(LDIF_SUFFIX);
+      return OperatingSystem.isWindows() ?
+          filename.toLowerCase().endsWith(LDIF_SUFFIX) : filename.endsWith(LDIF_SUFFIX);
     }
   }
 

--
Gitblit v1.10.0