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

neil_a_wilson
11.17.2007 a1d57e5fa800648c2308a3daf2ea528a1504c646
Update the attribute type syntax so that it is possible to specify an
approximate matching rule for that attribute type using the X-APPROX extension.
This will be more standards-compliant than the way we were previously
handling it, by using an APPROX keyword (which was not in-line with the LDAP
specification).

OpenDS Issue Number: 1143
1 files added
3 files modified
286 ■■■■■ changed files
opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java 50 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/ServerConstants.java 8 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java 58 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/EqualLengthApproximateMatchingRule.java 170 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/schema/AttributeTypeSyntax.java
@@ -55,6 +55,7 @@
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.SchemaMessages.*;
import static org.opends.server.schema.SchemaConstants.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -628,31 +629,6 @@
        isNoUserModification    = superiorType.isNoUserModification();
        attributeUsage          = superiorType.getUsage();
      }
      else if (lowerTokenName.equals("approx") ||
               lowerTokenName.equals("approximate"))
      {
        // This specifies the name or OID of the approximate matching rule to
        // use for this attribute type.
        StringBuilder woidBuffer = new StringBuilder();
        pos = readWOID(lowerStr, woidBuffer, pos);
        ApproximateMatchingRule amr =
             schema.getApproximateMatchingRule(woidBuffer.toString());
        if (amr == null)
        {
          // This is bad because we have no idea what the approximate matching
          // rule should be.  Log a message and go with the default matching
          // rule for the associated syntax.
          int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_APPROXIMATE_MR;
          String message = getMessage(msgID, String.valueOf(oid),
                                      String.valueOf(woidBuffer));
          logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                   message, msgID);
        }
        else
        {
          approximateMatchingRule = amr;
        }
      }
      else if (lowerTokenName.equals("equality"))
      {
        // This specifies the name or OID of the equality matching rule to use
@@ -925,6 +901,30 @@
      }
    }
    List<String> approxRules = extraProperties.get(SCHEMA_PROPERTY_APPROX_RULE);
    if ((approxRules != null) && (! approxRules.isEmpty()))
    {
      String ruleName  = approxRules.get(0);
      String lowerName = toLowerCase(ruleName);
      ApproximateMatchingRule amr =
           schema.getApproximateMatchingRule(lowerName);
      if (amr == null)
      {
        // This is bad because we have no idea what the approximate matching
        // rule should be.  Log a message and go with the default matching
        // rule for the associated syntax.
        int    msgID   = MSGID_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_APPROXIMATE_MR;
        String message = getMessage(msgID, String.valueOf(oid),
                                    String.valueOf(ruleName));
        logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_WARNING,
                 message, msgID);
      }
      else
      {
        approximateMatchingRule = amr;
      }
    }
    return new AttributeType(value.stringValue(), primaryName, typeNames, oid,
                             description, superiorType, syntax,
opends/src/server/org/opends/server/util/ServerConstants.java
@@ -1909,6 +1909,14 @@
  /**
   * The name of the schema extension that will be used to specify the
   * approximate matching rule that should be used for a given attribute type.
   */
  public static final String SCHEMA_PROPERTY_APPROX_RULE = "X-APPROX";
  /**
   * The name of the schema property that will be used to specify the path to
   * the schema file from which the schema element was loaded.
   */
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/AttributeTypeSyntaxTest.java
@@ -26,8 +26,17 @@
 */
package org.opends.server.schema;
import org.opends.server.api.AttributeSyntax;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.AttributeType;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteStringFactory;
import static org.testng.Assert.*;
/**
 * Test the AttributeTypeSyntax.
@@ -63,4 +72,51 @@
    };
  }
  /**
   * Tests the use of the "X-APPROX" extension to specify a particular
   * approximate matching rule.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testXAPPROXExtension()
         throws Exception
  {
    // Create and register the approximate matching rule for testing purposes.
    EqualLengthApproximateMatchingRule testApproxRule =
         new EqualLengthApproximateMatchingRule();
    testApproxRule.initializeMatchingRule(null);
    DirectoryServer.registerApproximateMatchingRule(testApproxRule, false);
    // Get a reference to the attribute type syntax implementation in the
    // server.
    AttributeTypeSyntax attrTypeSyntax =
      (AttributeTypeSyntax)
      DirectoryServer.getAttributeSyntax("1.3.6.1.4.1.1466.115.121.1.3", false);
    assertNotNull(attrTypeSyntax);
    // Create an attribute type definition and verify that it is acceptable.
    ByteString definition = ByteStringFactory.create(
      "( testxapproxtype-oid NAME 'testXApproxType' " +
           "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " +
           "X-APPROX 'equalLengthApproximateMatch' )");
    StringBuilder invalidReason = new StringBuilder();
    assertTrue(attrTypeSyntax.valueIsAcceptable(definition, invalidReason),
               invalidReason.toString());
    // Verify that we can decode the attribute type and that it has the
    // correct approximate matching rule.
    AttributeType attrType =
         AttributeTypeSyntax.decodeAttributeType(definition,
                                                 DirectoryServer.getSchema());
    assertNotNull(attrType);
    assertNotNull(attrType.getApproximateMatchingRule());
    assertEquals(attrType.getApproximateMatchingRule(), testApproxRule);
}
}
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/EqualLengthApproximateMatchingRule.java
New file
@@ -0,0 +1,170 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 */
package org.opends.server.schema;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteStringFactory;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
import static org.opends.server.schema.SchemaConstants.*;
/**
 * This class implements an extremely simple approximate matching rule that will
 * consider two values approximately equal only if they have the same length.
 * It is intended purely for testing purposes.
 */
public class EqualLengthApproximateMatchingRule
       extends ApproximateMatchingRule
{
  /**
   * Creates a new instance of this equal length approximate matching rule.
   */
  public EqualLengthApproximateMatchingRule()
  {
    super();
  }
  /**
   * Initializes this matching rule based on the information in the provided
   * configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this matching rule.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization.
   *
   * @throws  InitializationException  If a problem that is not
   *                                   configuration-related occurs during
   *                                   initialization.
   */
  public void initializeMatchingRule(ConfigEntry configEntry)
         throws ConfigException, InitializationException
  {
    // No initialization is required.
  }
  /**
   * Retrieves the common name for this matching rule.
   *
   * @return  The common name for this matching rule, or <CODE>null</CODE> if
   * it does not have a name.
   */
  public String getName()
  {
    return "equalLengthApproximateMatch";
  }
  /**
   * Retrieves the OID for this matching rule.
   *
   * @return  The OID for this matching rule.
   */
  public String getOID()
  {
    return "equallengthapproximatematch-oid";
  }
  /**
   * Retrieves the description for this matching rule.
   *
   * @return  The description for this matching rule, or <CODE>null</CODE> if
   *          there is none.
   */
  public String getDescription()
  {
    return null;
  }
  /**
   * Retrieves the OID of the syntax with which this matching rule is
   * associated.
   *
   * @return  The OID of the syntax with which this matching rule is associated.
   */
  public String getSyntaxOID()
  {
    return SYNTAX_DIRECTORY_STRING_OID;
  }
  /**
   * Retrieves the normalized form of the provided value, which is best suited
   * for efficiently performing matching operations on that value.
   *
   * @param  value  The value to be normalized.
   *
   * @return  The normalized version of the provided value.
   *
   * @throws  DirectoryException  If the provided value is invalid according to
   *                              the associated attribute syntax.
   */
  public ByteString normalizeValue(ByteString value)
         throws DirectoryException
  {
    // Any value is acceptable, so we can just return a copy of the
    // value.
    return ByteStringFactory.create(value.value());
  }
  /**
   * Indicates whether the two provided normalized values are approximately
   * equal to each other.
   *
   * @param  value1  The normalized form of the first value to compare.
   * @param  value2  The normalized form of the second value to compare.
   *
   * @return  <CODE>true</CODE> if the provided values are approximately equal,
   *          or <CODE>false</CODE> if not.
   */
  public boolean approximatelyMatch(ByteString value1, ByteString value2)
  {
    return (value1.value().length == value2.value().length);
  }
}