From a9f305153b30d5cb478c561467803512e90f3ba6 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Wed, 03 Feb 2016 11:57:34 +0000
Subject: [PATCH] OPENDJ-2647 Schema problems in control-panel

---
 opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java             |   18 ++++--
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/SchemaLoader.java |   48 +++++++++------
 opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java                     |   25 +++++--
 opendj-server-legacy/src/main/java/org/opends/server/core/SchemaConfigManager.java         |   32 +++++++++-
 opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java            |   54 ++++++-----------
 5 files changed, 105 insertions(+), 72 deletions(-)

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 d8ab0bf..22d05f1 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
@@ -35,14 +35,17 @@
 import java.util.List;
 
 import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.opendj.ldap.schema.Syntax;
-import org.forgerock.opendj.ldap.schema.MatchingRule;
-import org.opends.server.config.ConfigConstants;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.schema.AttributeType;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
+import org.forgerock.opendj.ldap.schema.SchemaBuilder;
+import org.forgerock.opendj.ldap.schema.Syntax;
+import org.opends.server.config.ConfigConstants;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.SchemaConfigManager;
 import org.opends.server.schema.SchemaConstants;
-import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.opends.server.types.DirectoryException;
 import org.opends.server.types.InitializationException;
 import org.opends.server.types.ObjectClass;
@@ -189,25 +192,32 @@
    */
   protected Schema getBaseSchema() throws DirectoryException
   {
-    // start from default schema
-    Schema schema = new Schema(org.forgerock.opendj.ldap.schema.Schema.getDefaultSchema());
-    for (MatchingRule mr : matchingRulesToKeep)
+    try
     {
-      schema.registerMatchingRule(mr, true);
+      SchemaBuilder builder = new SchemaBuilder(org.forgerock.opendj.ldap.schema.Schema.getDefaultSchema());
+      for (Syntax syntax : syntaxesToKeep)
+      {
+        builder.buildSyntax(syntax).addToSchemaOverwrite();
+      }
+      for (MatchingRule mr : matchingRulesToKeep)
+      {
+        builder.buildMatchingRule(mr).addToSchemaOverwrite();
+      }
+      for (AttributeType attr : attributesToKeep)
+      {
+        builder.buildAttributeType(attr).addToSchemaOverwrite();
+      }
+      Schema schema = new Schema(builder.toSchema());
+      for (ObjectClass oc : objectclassesToKeep)
+      {
+        schema.registerObjectClass(oc, true);
+      }
+      return schema;
     }
-    for (Syntax syntax : syntaxesToKeep)
+    catch (LocalizedIllegalArgumentException e)
     {
-      schema.registerSyntax(syntax, true);
+      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, e.getMessageObject(), e);
     }
-    for (AttributeType attr : attributesToKeep)
-    {
-      schema.registerAttributeType(attr, true);
-    }
-    for (ObjectClass oc : objectclassesToKeep)
-    {
-      schema.registerObjectClass(oc, true);
-    }
-    return schema;
   }
 
   /**
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
index b126ec0..c9fd068 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -890,10 +890,17 @@
       // Set default values for variables that may be needed during schema processing.
       directoryServer.syntaxEnforcementPolicy = AcceptRejectWarn.REJECT;
 
-      // Create the server schema and initialize and register a minimal set of
-      // matching rules and attribute syntaxes.
-      org.forgerock.opendj.ldap.schema.Schema coreSchema = org.forgerock.opendj.ldap.schema.Schema.getCoreSchema();
-      directoryServer.schema = new Schema(coreSchema);
+      // Create and initialize the server schema,
+      // and register a minimal set of matching rules and attribute syntaxes.
+      try
+      {
+        directoryServer.schema = new Schema(org.forgerock.opendj.ldap.schema.Schema.getCoreSchema());
+      }
+      catch (DirectoryException unexpected)
+      {
+        // the core schema should not have any warning
+        throw new RuntimeException(unexpected);
+      }
       directoryServer.bootstrapAttributeSyntaxes();
 
       // Perform any additional initialization that might be necessary before
@@ -6843,8 +6850,7 @@
                             theToolDescription, false);
     argParser.setShortToolDescription(REF_SHORT_DESC_START_DS.get());
 
-    // Initialize all the command-line argument types and register them with the
-    // parser.
+    // Initialize all the command-line argument types and register them with the parser.
     try
     {
       configClass = new StringArgument("configclass", 'C', "configClass",
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaConfigManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaConfigManager.java
index a055bc6..0a06942 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaConfigManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/SchemaConfigManager.java
@@ -42,8 +42,23 @@
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.forgerock.opendj.ldap.schema.CoreSchema;
 import org.forgerock.opendj.ldap.schema.Syntax;
-import org.opends.server.schema.*;
-import org.opends.server.types.*;
+import org.opends.server.schema.DITContentRuleSyntax;
+import org.opends.server.schema.DITStructureRuleSyntax;
+import org.opends.server.schema.MatchingRuleUseSyntax;
+import org.opends.server.schema.NameFormSyntax;
+import org.opends.server.schema.ObjectClassSyntax;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.DITContentRule;
+import org.opends.server.types.DITStructureRule;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.LDIFImportConfig;
+import org.opends.server.types.MatchingRuleUse;
+import org.opends.server.types.Modification;
+import org.opends.server.types.NameForm;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.Schema;
 import org.opends.server.util.LDIFReader;
 import org.opends.server.util.StaticUtils;
 
@@ -81,9 +96,16 @@
   public SchemaConfigManager(ServerContext serverContext)
   {
     this.serverContext = serverContext;
-    // the manager will build the schema from scratch, but we need to start from
-    // core schema for SDK schema
-    schema = new Schema(org.forgerock.opendj.ldap.schema.Schema.getCoreSchema());
+    try
+    {
+      // the manager will build the schema from scratch, but we need to start from core schema for SDK schema
+      schema = new Schema(org.forgerock.opendj.ldap.schema.Schema.getCoreSchema());
+    }
+    catch (DirectoryException unexpected)
+    {
+      // the core schema should not have any warning
+      throw new RuntimeException(unexpected);
+    }
   }
 
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java b/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java
index 1bdc922..494be91 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/types/Schema.java
@@ -201,10 +201,12 @@
    *
    * @param schemaNG
    *          The SDK schema
+   * @throws DirectoryException
+   *           if the schema has warnings
    */
-  public Schema(org.forgerock.opendj.ldap.schema.Schema schemaNG)
+  public Schema(org.forgerock.opendj.ldap.schema.Schema schemaNG) throws DirectoryException
   {
-    setSchemaNG(schemaNG);
+    switchSchema(schemaNG);
 
     objectClasses = new ConcurrentHashMap<String,ObjectClass>();
     matchingRuleUses = new ConcurrentHashMap<MatchingRule,MatchingRuleUse>();
@@ -2022,16 +2024,23 @@
   }
 
   /**
-   * Creates a new <CODE>Schema</CODE> object that is a duplicate of
-   * this one.  It elements may be added and removed from the
-   * duplicate without impacting this version.
+   * Creates a new {@link Schema} object that is a duplicate of this one. It elements may be added
+   * and removed from the duplicate without impacting this version.
    *
-   * @return  A new <CODE>Schema</CODE> object that is a duplicate of
-   *          this one.
+   * @return A new {@link Schema} object that is a duplicate of this one.
    */
   public Schema duplicate()
   {
-    Schema dupSchema = new Schema(schemaNG);
+    Schema dupSchema;
+    try
+    {
+      dupSchema = new Schema(schemaNG);
+    }
+    catch (DirectoryException unexpected)
+    {
+      // the schema has already been validated
+      throw new RuntimeException(unexpected);
+    }
 
     dupSchema.subordinateTypes.putAll(subordinateTypes);
     dupSchema.objectClasses.putAll(objectClasses);
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java b/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java
index 2925e44..66606ef 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/schema/LDAPSyntaxTest.java
@@ -22,12 +22,11 @@
  *
  *
  *      Copyright 2006-2009 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2016 ForgeRock AS
  */
 package org.opends.server.schema;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.forgerock.opendj.ldap.ByteString;
@@ -51,22 +50,17 @@
 import static org.opends.server.protocols.internal.Requests.*;
 import static org.testng.Assert.*;
 
-/**
- * Test the LDAPSyntaxDescriptionSyntax.
- */
+/** Test the LDAPSyntaxDescriptionSyntax. */
 @RemoveOnceSDKSchemaIsUsed
 @SuppressWarnings("javadoc")
 public class LDAPSyntaxTest extends AttributeSyntaxTest
 {
-
-  /** {@inheritDoc} */
   @Override
   protected AttributeSyntax<?> getRule()
   {
     return new LDAPSyntaxDescriptionSyntax();
   }
 
-  /** {@inheritDoc} */
   @Override
   @DataProvider(name="acceptableValues")
   public Object[][] createAcceptableValues()
@@ -172,7 +166,7 @@
         " X-SUBST '1.3.6.1.4.1.1466.115.121.1.15' )");
 
       //This is not expected to happen
-      assertFalse(resultCode==0);
+      assertThat(resultCode).isNotEqualTo(0);
 
       //Test if we can substitute a directory string syntax by an undefined.
       resultCode = TestCaseUtils.applyModifications(true,
@@ -184,11 +178,10 @@
         " X-SUBST '1.1.1' )");
 
       //This is not expected to happen
-      assertFalse(resultCode==0);
+      assertThat(resultCode).isNotEqualTo(0);
 
 
-      //Test if we can substitute a core syntax with a user-defined
-      //syntax
+      //Test if we can substitute a core syntax with a user-defined syntax
       addSubtitutionSyntax();
       //Replace the IA5Stringsyntax with the custom syntax we just created.
       resultCode = TestCaseUtils.applyModifications(true,
@@ -200,7 +193,7 @@
         " X-SUBST '9.9.9' )");
 
       //This is not expected to happen
-      assertFalse(resultCode==0);
+      assertThat(resultCode).isNotEqualTo(0);
     }
     finally
     {
@@ -211,11 +204,9 @@
 
 
   /**
-    * Tests whether both the virtual and the newly added real substitution
-    * sytanx are available when a search is made for ldapsyntaxes attribute.
-    *
-    * @throws java.lang.Exception
-    */
+   * Tests whether both the virtual and the newly added real substitution syntax are available when
+   * a search is made for ldapsyntaxes attribute.
+   */
   @Test
   public void testSubstitutionSyntaxSearch() throws Exception
   {
@@ -229,28 +220,25 @@
 
       assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
       List<SearchResultEntry> entries = searchOperation.getSearchEntries();
+      assertThat(entries).isNotEmpty();
       SearchResultEntry e = entries.get(0);
-      //An entry must be returned.
       assertNotNull(e);
       Attribute attr = e.getAttribute("ldapsyntaxes").get(0);
-      Iterator<ByteString> iter = attr.iterator();
 
       //There are other ways of doing it but we will extract the OID
       //from the attribute values and then check to see if our
       //OID is found in the result set or not.
       List<String> syntaxList = new ArrayList<>();
-      while(iter.hasNext())
+      for (ByteString attrValue : attr)
       {
         //parse the OIDs.
-        syntaxList.add(getOIDFromLdapSyntax(iter.next().toString()));
+        syntaxList.add(getOIDFromLdapSyntax(attrValue.toString()));
       }
 
       //Check if we find our OID.
       assertThat(syntaxList).contains("9.9.9");
-      //DirectoryString.
-      assertThat(syntaxList).contains("1.3.6.1.4.1.1466.115.121.1.15");
-      //IA5String.
-      assertThat(syntaxList).contains("1.3.6.1.4.1.1466.115.121.1.26");
+      assertThat(syntaxList).contains(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID);
+      assertThat(syntaxList).contains(SchemaConstants.SYNTAX_IA5_STRING_OID);
     }
     finally
     {
@@ -261,11 +249,9 @@
 
 
    /**
-    * Tests whether it is possible to add values after an umimplemented syntax
-    * has been subsitutited by DirectoryString syntax.
-    *
-    * @throws java.lang.Exception
-    */
+   * Tests whether it is possible to add values after an unimplemented syntax has been substituted
+   * by DirectoryString syntax.
+   */
   @Test
    public void testSubsitutionSyntaxAddValues() throws Exception
    {
@@ -370,9 +356,8 @@
       InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
       assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
       List<SearchResultEntry> entries = searchOperation.getSearchEntries();
-      SearchResultEntry e = entries.get(0);
-      //An entry must be returned.
-      assertNotNull(e);
+      assertThat(entries).isNotEmpty();
+      assertNotNull(entries.get(0));
     }
     finally
     {
@@ -446,6 +431,7 @@
       InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
       assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
       List<SearchResultEntry> entries = searchOperation.getSearchEntries();
+      assertThat(entries).isNotEmpty();
       SearchResultEntry e = entries.get(0);
       //An entry must be returned.
       assertNotNull(e);

--
Gitblit v1.10.0