mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
21.12.2007 dd53b104fa766ea07e8d6a8e18b23a516b463109
Update the way the server normalizes schema element definitions so that they
are more correctly handled and are more forgiving with regard to things like
extra spaces in the definition.

OpenDS Issue Number: 2171
2 files modified
402 ■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/types/Schema.java 360 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java 42 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
@@ -25,7 +25,6 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.types;
import org.opends.messages.Message;
@@ -42,6 +41,7 @@
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.messages.Message;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.api.EqualityMatchingRule;
@@ -50,14 +50,15 @@
import org.opends.server.api.SubstringMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SchemaConfigManager;
import org.opends.server.protocols.asn1.ASN1OctetString;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.loggers.ErrorLogger.*;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.schema.CaseIgnoreEqualityMatchingRule;
import static org.opends.messages.BackendMessages.*;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -94,6 +95,10 @@
  // The matching rule that will be used to normalize schema element
  // definitions.
  private EqualityMatchingRule normalizationMatchingRule;
  // The set of subordinate attribute types registered within the
  // server schema.
  private ConcurrentHashMap<AttributeType,List<AttributeType>>
@@ -257,8 +262,9 @@
    nameFormSet         = new LinkedHashSet<AttributeValue>();
    objectClassSet      = new LinkedHashSet<AttributeValue>();
    oldestModificationTime   = System.currentTimeMillis();
    youngestModificationTime = oldestModificationTime;
    normalizationMatchingRule = new CaseIgnoreEqualityMatchingRule();
    oldestModificationTime    = System.currentTimeMillis();
    youngestModificationTime  = oldestModificationTime;
  }
@@ -398,8 +404,8 @@
      // that would kill performance.
      String valueString = attributeType.getDefinition();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      attributeTypeSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -435,12 +441,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = attributeType.getDefinition();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      attributeTypeSet.remove(new AttributeValue(rawValue,
                                                 normValue));
      try
      {
        String valueString = attributeType.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        attributeTypeSet.remove(new AttributeValue(rawValue,
                                                   normValue));
      }
      catch (Exception e)
      {
        String valueString = attributeType.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        attributeTypeSet.remove(new AttributeValue(rawValue,
                                                   normValue));
      }
    }
  }
@@ -666,8 +685,8 @@
      // that would kill performance.
      String valueString = objectClass.getDefinition();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      objectClassSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -697,11 +716,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = objectClass.getDefinition();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      objectClassSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = objectClass.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        objectClassSet.remove(new AttributeValue(rawValue,
                                                 normValue));
      }
      catch (Exception e)
      {
        String valueString = objectClass.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        objectClassSet.remove(new AttributeValue(rawValue,
                                                 normValue));
      }
    }
  }
@@ -813,8 +846,8 @@
      // that would kill performance.
      String valueString = syntax.toString();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      syntaxSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -838,11 +871,23 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = syntax.toString();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      syntaxSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = syntax.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        syntaxSet.remove(new AttributeValue(rawValue, normValue));
      }
      catch (Exception e)
      {
        String valueString = syntax.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        syntaxSet.remove(new AttributeValue(rawValue, normValue));
      }
    }
  }
@@ -1003,8 +1048,9 @@
        // match) that would kill performance.
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue  = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        matchingRuleSet.add(new AttributeValue(rawValue, normValue));
      }
    }
@@ -1059,12 +1105,25 @@
        // rather than the attribute type because otherwise it would
        // use a very expensive matching rule (OID first component
        // match) that would kill performance.
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue  = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
        try
        {
          String valueString = matchingRule.toString();
          ASN1OctetString rawValue = new ASN1OctetString(valueString);
          ByteString normValue =
               normalizationMatchingRule.normalizeValue(
                    new ASN1OctetString(valueString));
          matchingRuleSet.remove(new AttributeValue(rawValue,
                                                    normValue));
        }
        catch (Exception e)
        {
          String valueString = matchingRule.toString();
          ASN1OctetString rawValue = new ASN1OctetString(valueString);
          ASN1OctetString normValue =
               new ASN1OctetString(toLowerCase(valueString));
          matchingRuleSet.remove(new AttributeValue(rawValue,
                                                    normValue));
        }
      }
    }
  }
@@ -1181,8 +1240,8 @@
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      matchingRuleSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -1217,11 +1276,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      matchingRuleSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
      catch (Exception e)
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
    }
  }
@@ -1335,8 +1408,8 @@
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      matchingRuleSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -1372,11 +1445,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      matchingRuleSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
      catch (Exception e)
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
    }
  }
@@ -1490,8 +1577,8 @@
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      matchingRuleSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -1526,11 +1613,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      matchingRuleSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
      catch (Exception e)
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
    }
  }
@@ -1644,8 +1745,8 @@
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      matchingRuleSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -1680,11 +1781,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = matchingRule.toString();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      matchingRuleSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
      catch (Exception e)
      {
        String valueString = matchingRule.toString();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        matchingRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      }
    }
  }
@@ -1801,8 +1916,8 @@
      // that would kill performance.
      String valueString = matchingRuleUse.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      matchingRuleUseSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -1828,12 +1943,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = matchingRuleUse.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      matchingRuleUseSet.remove(new AttributeValue(rawValue,
                                                   normValue));
      try
      {
        String valueString = matchingRuleUse.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        matchingRuleUseSet.remove(new AttributeValue(rawValue,
                                                     normValue));
      }
      catch (Exception e)
      {
        String valueString = matchingRuleUse.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        matchingRuleUseSet.remove(new AttributeValue(rawValue,
                                                     normValue));
      }
    }
  }
@@ -1949,8 +2077,8 @@
      // that would kill performance.
      String valueString = ditContentRule.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      ditContentRuleSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -1975,12 +2103,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = ditContentRule.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ditContentRuleSet.remove(new AttributeValue(rawValue,
                                                  normValue));
      try
      {
        String valueString = ditContentRule.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        ditContentRuleSet.remove(new AttributeValue(rawValue,
                                                    normValue));
      }
      catch (Exception e)
      {
        String valueString = ditContentRule.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        ditContentRuleSet.remove(new AttributeValue(rawValue,
                                                    normValue));
      }
    }
  }
@@ -2165,8 +2306,8 @@
      // that would kill performance.
      String valueString = ditStructureRule.getDefinition();
      ASN1OctetString rawValue = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
          new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      ditStructureRuleSet.add(new AttributeValue(rawValue,
                                                 normValue));
    }
@@ -2195,12 +2336,25 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = ditStructureRule.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ditStructureRuleSet.remove(new AttributeValue(rawValue,
                                                    normValue));
      try
      {
        String valueString = ditStructureRule.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        ditStructureRuleSet.remove(new AttributeValue(rawValue,
                                                      normValue));
      }
      catch (Exception e)
      {
        String valueString = ditStructureRule.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        ditStructureRuleSet.remove(new AttributeValue(rawValue,
                                                      normValue));
      }
    }
  }
@@ -2394,8 +2548,8 @@
      // that would kill performance.
      String valueString = nameForm.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      ByteString normValue = normalizationMatchingRule.normalizeValue(
                                  new ASN1OctetString(valueString));
      nameFormSet.add(new AttributeValue(rawValue, normValue));
    }
  }
@@ -2424,11 +2578,23 @@
      // rather than the attribute type because otherwise it would use
      // a very expensive matching rule (OID first component match)
      // that would kill performance.
      String valueString = nameForm.getDefinition();
      ASN1OctetString rawValue  = new ASN1OctetString(valueString);
      ASN1OctetString normValue =
           new ASN1OctetString(toLowerCase(valueString));
      nameFormSet.remove(new AttributeValue(rawValue, normValue));
      try
      {
        String valueString = nameForm.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ByteString normValue =
             normalizationMatchingRule.normalizeValue(
                  new ASN1OctetString(valueString));
        nameFormSet.remove(new AttributeValue(rawValue, normValue));
      }
      catch (Exception e)
      {
        String valueString = nameForm.getDefinition();
        ASN1OctetString rawValue = new ASN1OctetString(valueString);
        ASN1OctetString normValue =
             new ASN1OctetString(toLowerCase(valueString));
        nameFormSet.remove(new AttributeValue(rawValue, normValue));
      }
    }
  }
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
@@ -5330,6 +5330,48 @@
  /**
   * Tests the ability to properly handle adding and removing a schema
   * definition in which the definition has extra spaces.  This was added as a
   * test case for issue #2171.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testAddAndDeleteDefinitionWithExtraSpaces()
         throws Exception
  {
    int resultCode = TestCaseUtils.applyModifications(
      "dn: cn=schema",
      "changetype: modify",
      "add: objectClasses",
      "objectClasses: ( testaddanddeletedefinitionwithextraspaces-oid",
      "  NAME 'testAddAndDeleteDefinitionWithExtraSpaces'  SUP person",
      "  MAY ( street $ c) X-ORIGIN 'user defined' )");
    assertEquals(resultCode, 0);
    assertNotNull(DirectoryServer.getObjectClass(
                       "testaddanddeletedefinitionwithextraspaces"));
    assertNotNull(DirectoryServer.getObjectClass(
                       "testaddanddeletedefinitionwithextraspaces-oid"));
    resultCode = TestCaseUtils.applyModifications(
      "dn: cn=schema",
      "changetype: modify",
      "delete: objectClasses",
      "objectClasses: ( testaddanddeletedefinitionwithextraspaces-oid",
      "  NAME 'testAddAndDeleteDefinitionWithExtraSpaces'  SUP person",
      "  MAY ( street $ c) X-ORIGIN 'user defined' )");
    assertEquals(resultCode, 0);
    assertNull(DirectoryServer.getObjectClass(
                    "testaddanddeletedefinitionwithextraspaces"));
    assertNull(DirectoryServer.getObjectClass(
                    "testaddanddeletedefinitionwithextraspaces-oid"));
  }
  /**
   * Tests the {@code exportLDIF} method with a valid configuration.
   *
   * @throws  Exception  If an unexpected problem occurs.