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

Matthew Swift
25.33.2012 263d085885df024dca9250cc03c807912b0a7662
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/EnumSyntaxImpl.java
@@ -6,17 +6,16 @@
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * 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/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * 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
@@ -27,8 +26,6 @@
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
@@ -49,144 +46,101 @@
import com.forgerock.opendj.util.Validator;
/**
 * This class provides an enumeration-based mechanism where a new syntax and its
 * corresponding matching rules can be created on-the-fly. An enum syntax is an
 * LDAPSyntaxDescriptionSyntax with X-ENUM extension.
 */
final class EnumSyntaxImpl extends AbstractSyntaxImpl
{
  private final String oid;
  // Set of read-only enum entries.
  private final List<String> entries;
final class EnumSyntaxImpl extends AbstractSyntaxImpl {
    private final String oid;
    // Set of read-only enum entries.
    private final List<String> entries;
    EnumSyntaxImpl(final String oid, final List<String> entries) {
        Validator.ensureNotNull(oid, entries);
        this.oid = oid;
        final List<String> entryStrings = new ArrayList<String>(entries.size());
  EnumSyntaxImpl(final String oid, final List<String> entries)
  {
    Validator.ensureNotNull(oid, entries);
    this.oid = oid;
    final List<String> entryStrings = new ArrayList<String>(entries.size());
    for (final String entry : entries)
    {
      final String normalized = normalize(ByteString.valueOf(entry));
      if (!entryStrings.contains(normalized))
      {
        entryStrings.add(normalized);
      }
    }
    this.entries = Collections.unmodifiableList(entryStrings);
  }
  @Override
  public String getApproximateMatchingRule()
  {
    return AMR_DOUBLE_METAPHONE_OID;
  }
  @Override
  public String getEqualityMatchingRule()
  {
    return EMR_CASE_IGNORE_OID;
  }
  public String getName()
  {
    return oid;
  }
  @Override
  public String getOrderingMatchingRule()
  {
    return OMR_OID_GENERIC_ENUM + "." + oid;
  }
  @Override
  public String getSubstringMatchingRule()
  {
    return SMR_CASE_IGNORE_OID;
  }
  public int indexOf(final ByteSequence value)
  {
    return entries.indexOf(normalize(value));
  }
  public boolean isHumanReadable()
  {
    return true;
  }
  public boolean valueIsAcceptable(final Schema schema,
      final ByteSequence value, final LocalizableMessageBuilder invalidReason)
  {
    // The value is acceptable if it belongs to the set.
    final boolean isAllowed = entries.contains(normalize(value));
    if (!isAllowed)
    {
      final LocalizableMessage message = WARN_ATTR_SYNTAX_LDAPSYNTAX_ENUM_INVALID_VALUE
          .get(value.toString(), oid);
      invalidReason.append(message);
    }
    return isAllowed;
  }
  private String normalize(final ByteSequence value)
  {
    final StringBuilder buffer = new StringBuilder();
    prepareUnicode(buffer, value, TRIM, CASE_FOLD);
    final int bufferLength = buffer.length();
    if (bufferLength == 0)
    {
      if (value.length() > 0)
      {
        // This should only happen if the value is composed entirely of
        // spaces. In that case, the normalized value is a single space.
        return " ";
      }
      else
      {
        // The value is empty, so it is already normalized.
        return "";
      }
    }
    // Replace any consecutive spaces with a single space.
    for (int pos = bufferLength - 1; pos > 0; pos--)
    {
      if (buffer.charAt(pos) == ' ')
      {
        if (buffer.charAt(pos - 1) == ' ')
        {
          buffer.delete(pos, pos + 1);
        for (final String entry : entries) {
            final String normalized = normalize(ByteString.valueOf(entry));
            if (!entryStrings.contains(normalized)) {
                entryStrings.add(normalized);
            }
        }
      }
        this.entries = Collections.unmodifiableList(entryStrings);
    }
    return buffer.toString();
  }
    @Override
    public String getApproximateMatchingRule() {
        return AMR_DOUBLE_METAPHONE_OID;
    }
    @Override
    public String getEqualityMatchingRule() {
        return EMR_CASE_IGNORE_OID;
    }
    public String getName() {
        return oid;
    }
    @Override
    public String getOrderingMatchingRule() {
        return OMR_OID_GENERIC_ENUM + "." + oid;
    }
    @Override
    public String getSubstringMatchingRule() {
        return SMR_CASE_IGNORE_OID;
    }
    public int indexOf(final ByteSequence value) {
        return entries.indexOf(normalize(value));
    }
    public boolean isHumanReadable() {
        return true;
    }
    public boolean valueIsAcceptable(final Schema schema, final ByteSequence value,
            final LocalizableMessageBuilder invalidReason) {
        // The value is acceptable if it belongs to the set.
        final boolean isAllowed = entries.contains(normalize(value));
        if (!isAllowed) {
            final LocalizableMessage message =
                    WARN_ATTR_SYNTAX_LDAPSYNTAX_ENUM_INVALID_VALUE.get(value.toString(), oid);
            invalidReason.append(message);
        }
        return isAllowed;
    }
    private String normalize(final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, CASE_FOLD);
        final int bufferLength = buffer.length();
        if (bufferLength == 0) {
            if (value.length() > 0) {
                // This should only happen if the value is composed entirely of
                // spaces. In that case, the normalized value is a single space.
                return " ";
            } else {
                // The value is empty, so it is already normalized.
                return "";
            }
        }
        // Replace any consecutive spaces with a single space.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            if (buffer.charAt(pos) == ' ') {
                if (buffer.charAt(pos - 1) == ' ') {
                    buffer.delete(pos, pos + 1);
                }
            }
        }
        return buffer.toString();
    }
}