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

Jean-Noel Rouvignac
28.55.2014 53921b5a1f1d0db4cad85c15d6e7709dd339fe59
OPENDJ-1308 (CR-3121) Migrate schema support

Factorized duplicated code from org.forgerock.opendj.ldap.schema into SchemaUtils.java
22 files modified
750 ■■■■ changed files
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java 9 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleImpl.java 26 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleImpl.java 44 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleImpl.java 46 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleImpl.java 25 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleImpl.java 25 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleImpl.java 24 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java 45 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java 45 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListEqualityMatchingRuleImpl.java 39 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListSubstringMatchingRuleImpl.java 58 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleImpl.java 26 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleImpl.java 25 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java 30 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnumSyntaxImpl.java 21 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/KeywordEqualityMatchingRuleImpl.java 19 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleImpl.java 12 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleImpl.java 13 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleImpl.java 13 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleImpl.java 26 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleImpl.java 26 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java 153 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java
@@ -92,13 +92,4 @@
            throws DecodeException {
        return UNDEFINED_ASSERTION;
    }
    static void trimConsecutiveSpaces(StringBuilder buffer) {
        for (int pos = buffer.length() - 1; pos > 0; pos--) {
            if (buffer.charAt(pos) == ' '
                    && buffer.charAt(pos - 1) == ' ') {
                buffer.delete(pos, pos + 1);
            }
        }
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactEqualityMatchingRuleImpl.java
@@ -26,36 +26,18 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class defines the caseExactMatch matching rule defined in X.520 and
 * referenced in RFC 4519.
 */
final class CaseExactEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, NO_CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5EqualityMatchingRuleImpl.java
@@ -26,16 +26,12 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import static com.forgerock.opendj.ldap.CoreMessages.WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the caseExactIA5Match matching rule defined in RFC
 * 2252.
@@ -43,40 +39,6 @@
final class CaseExactIA5EqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
            throws DecodeException {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        // Replace any consecutive spaces with a single space and watch out
        // for non-ASCII characters.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            final char c = buffer.charAt(pos);
            if (c == ' ') {
                if (buffer.charAt(pos - 1) == ' ') {
                    buffer.delete(pos, pos + 1);
                }
            } else if ((c & 0x7F) != c) {
                // This is not a valid character for an IA5 string. If strict
                // syntax enforcement is enabled, then we'll throw an exception.
                // Otherwise, we'll get rid of the character.
                final LocalizableMessage message =
                        WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER.get(value.toString(), String
                                .valueOf(c));
                throw DecodeException.error(message);
            }
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeIA5StringAttributeValue(value, TRIM, NO_CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactIA5SubstringMatchingRuleImpl.java
@@ -22,19 +22,16 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import static com.forgerock.opendj.ldap.CoreMessages.WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the caseExactIA5SubstringsMatch matching rule. This
 * matching rule actually isn't defined in any official specification, but some
@@ -42,6 +39,7 @@
 * private namespace.
 */
final class CaseExactIA5SubstringMatchingRuleImpl extends AbstractSubstringMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
            throws DecodeException {
        return normalize(TRIM, value);
@@ -55,40 +53,6 @@
    private ByteString normalize(final boolean trim, final ByteSequence value)
            throws DecodeException {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, trim, NO_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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        // Replace any consecutive spaces with a single space and watch out
        // for non-ASCII characters.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            final char c = buffer.charAt(pos);
            if (c == ' ') {
                if (buffer.charAt(pos - 1) == ' ') {
                    buffer.delete(pos, pos + 1);
                }
            } else if ((c & 0x7F) != c) {
                // This is not a valid character for an IA5 string. If strict
                // syntax enforcement is enabled, then we'll throw an exception.
                // Otherwise, we'll get rid of the character.
                final LocalizableMessage message =
                        WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER.get(value.toString(), String
                                .valueOf(c));
                throw DecodeException.error(message);
            }
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeIA5StringAttributeValue(value, trim, NO_CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactOrderingMatchingRuleImpl.java
@@ -26,36 +26,17 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class defines the caseExactOrderingMatch matching rule defined in X.520
 * and referenced in RFC 4519.
 */
final class CaseExactOrderingMatchingRuleImpl extends AbstractOrderingMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, NO_CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseExactSubstringMatchingRuleImpl.java
@@ -26,14 +26,12 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class defines the caseExactSubstringsMatch matching rule defined in
 * X.520 and referenced in RFC 2252.
@@ -50,23 +48,6 @@
    }
    private ByteString normalize(final boolean trim, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, trim, NO_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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, trim, NO_CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreEqualityMatchingRuleImpl.java
@@ -26,9 +26,7 @@
 */
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;
import static com.forgerock.opendj.util.StringPrepProfile.*;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
@@ -38,24 +36,8 @@
 * referenced in RFC 2252.
 */
final class CaseIgnoreEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, 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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5EqualityMatchingRuleImpl.java
@@ -26,57 +26,20 @@
 */
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;
import static com.forgerock.opendj.ldap.CoreMessages.WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the caseIgnoreIA5Match matching rule defined in RFC
 * 2252.
 */
final class CaseIgnoreIA5EqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
            throws DecodeException {
        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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        // Replace any consecutive spaces with a single space and watch out
        // for non-ASCII characters.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            final char c = buffer.charAt(pos);
            if (c == ' ') {
                if (buffer.charAt(pos - 1) == ' ') {
                    buffer.delete(pos, pos + 1);
                }
            } else if ((c & 0x7F) != c) {
                // This is not a valid character for an IA5 string. If strict
                // syntax enforcement is enabled, then we'll throw an exception.
                // Otherwise, we'll get rid of the character.
                final LocalizableMessage message =
                        WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER.get(value.toString(), String
                                .valueOf(c));
                throw DecodeException.error(message);
            }
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeIA5StringAttributeValue(value, TRIM, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreIA5SubstringMatchingRuleImpl.java
@@ -22,19 +22,16 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
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;
import static com.forgerock.opendj.ldap.CoreMessages.WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the caseIgnoreIA5SubstringsMatch matching rule defined
 * in RFC 2252.
@@ -53,40 +50,6 @@
    private ByteString normalize(final boolean trim, final ByteSequence value)
            throws DecodeException {
        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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        // Replace any consecutive spaces with a single space and watch out
        // for non-ASCII characters.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            final char c = buffer.charAt(pos);
            if (c == ' ') {
                if (buffer.charAt(pos - 1) == ' ') {
                    buffer.delete(pos, pos + 1);
                }
            } else if ((c & 0x7F) != c) {
                // This is not a valid character for an IA5 string. If strict
                // syntax enforcement is enabled, then we'll throw an exception.
                // Otherwise, we'll get rid of the character.
                final LocalizableMessage message =
                        WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER.get(value.toString(), String
                                .valueOf(c));
                throw DecodeException.error(message);
            }
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeIA5StringAttributeValue(value, trim, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListEqualityMatchingRuleImpl.java
@@ -27,50 +27,17 @@
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;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the caseIgnoreListMatch matching rule defined in X.520
 * and referenced in RFC 2252.
 */
final class CaseIgnoreListEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, 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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        // Replace any consecutive spaces with a single space. Any spaces
        // around a dollar sign will also be removed.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            if (buffer.charAt(pos) == ' ') {
                final char c = buffer.charAt(pos - 1);
                if (c == ' ') {
                    buffer.delete(pos, pos + 1);
                } else if (c == '$') {
                    if (pos <= 1 || buffer.charAt(pos - 2) != '\\') {
                        buffer.delete(pos, pos + 1);
                    }
                } else if (buffer.charAt(pos + 1) == '$') {
                    buffer.delete(pos, pos + 1);
                }
            }
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringListAttributeValue(value, TRIM, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreListSubstringMatchingRuleImpl.java
@@ -26,14 +26,11 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import com.forgerock.opendj.util.StringPrepProfile;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the caseIgnoreListSubstringsMatch matching rule defined
@@ -41,39 +38,7 @@
 */
final class CaseIgnoreListSubstringMatchingRuleImpl extends AbstractSubstringMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, StringPrepProfile.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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        // Replace any consecutive spaces with a single space. Any spaces
        // around a dollar sign will also be removed.
        for (int pos = bufferLength - 1; pos > 0; pos--) {
            if (buffer.charAt(pos) == ' ') {
                final char c = buffer.charAt(pos - 1);
                if (c == ' ') {
                    buffer.delete(pos, pos + 1);
                } else if (c == '$') {
                    if (pos <= 1 || buffer.charAt(pos - 2) != '\\') {
                        buffer.delete(pos, pos + 1);
                    }
                } else if (buffer.charAt(pos + 1) == '$') {
                    buffer.delete(pos, pos + 1);
                }
            }
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringListAttributeValue(value, TRIM, CASE_FOLD);
    }
    @Override
@@ -82,23 +47,6 @@
        // In this case, the process for normalizing a substring is the same
        // as normalizing a full value with the exception that it may
        // include an opening or trailing space.
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, false, 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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return value.toByteString();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, false, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreOrderingMatchingRuleImpl.java
@@ -26,36 +26,18 @@
 */
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;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class defines the caseIgnoreOrderingMatch matching rule defined in X.520
 * and referenced in RFC 2252.
 */
final class CaseIgnoreOrderingMatchingRuleImpl extends AbstractOrderingMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, 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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CaseIgnoreSubstringMatchingRuleImpl.java
@@ -26,14 +26,11 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import com.forgerock.opendj.util.StringPrepProfile;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class defines the caseIgnoreSubstringsMatch matching rule defined in
@@ -51,24 +48,6 @@
    }
    private ByteString normalize(final boolean trim, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        StringPrepProfile.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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return value.toByteString();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, trim, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java
@@ -28,11 +28,9 @@
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;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_EMPTY_VALUE;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_EXPECTED_OPEN_PARENTHESIS;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
@@ -51,24 +49,7 @@
final class DirectoryStringFirstComponentEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, assertionValue, TRIM, CASE_FOLD);
        final int bufferLength = buffer.length();
        if (bufferLength == 0) {
            if (assertionValue.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 new DefaultEqualityAssertion(SchemaConstants.SINGLE_SPACE_VALUE);
            } else {
                // The value is empty, so it is already normalized.
                return new DefaultEqualityAssertion(ByteString.empty());
            }
        }
        trimConsecutiveSpaces(buffer);
        return new DefaultEqualityAssertion(ByteString.valueOf(buffer.toString()));
        return new DefaultEqualityAssertion(SchemaUtils.normalizeStringAttributeValue(assertionValue, TRIM, CASE_FOLD));
    }
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
@@ -84,18 +65,15 @@
            // This means that the value was empty or contained only
            // whitespace.
            // That is illegal.
            final LocalizableMessage message = ERR_ATTR_SYNTAX_EMPTY_VALUE.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_EMPTY_VALUE.get());
        }
        // The next character must be an open parenthesis. If it is not,
        // then that is an error.
        final char c = reader.read();
        if (c != '(') {
            final LocalizableMessage message =
                    ERR_ATTR_SYNTAX_EXPECTED_OPEN_PARENTHESIS.get(definition, (reader.pos() - 1),
                            String.valueOf(c));
            throw DecodeException.error(message);
            throw DecodeException.error(
                    ERR_ATTR_SYNTAX_EXPECTED_OPEN_PARENTHESIS.get(definition, reader.pos() - 1, c));
        }
        // Skip over any spaces immediately following the opening parenthesis.
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EnumSyntaxImpl.java
@@ -28,10 +28,8 @@
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;
import static com.forgerock.opendj.ldap.CoreMessages.WARN_ATTR_SYNTAX_LDAPSYNTAX_ENUM_INVALID_VALUE;
import static org.forgerock.opendj.ldap.schema.AbstractMatchingRuleImpl.*;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.AMR_DOUBLE_METAPHONE_OID;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_CASE_IGNORE_OID;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.OMR_OID_GENERIC_ENUM;
@@ -118,23 +116,6 @@
    }
    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 "";
            }
        }
        trimConsecutiveSpaces(buffer);
        return buffer.toString();
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, CASE_FOLD).toString();
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/KeywordEqualityMatchingRuleImpl.java
@@ -28,7 +28,6 @@
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;
import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteSequence;
@@ -116,22 +115,6 @@
    }
    private String normalize(final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, CASE_FOLD);
        if (buffer.length() == 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 "";
            }
        }
        trimConsecutiveSpaces(buffer);
        return buffer.toString();
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, CASE_FOLD).toString();
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringEqualityMatchingRuleImpl.java
@@ -26,10 +26,6 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
@@ -40,12 +36,6 @@
 */
final class NumericStringEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_CASE_FOLD);
        if (buffer.length() == 0) {
            return ByteString.empty();
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeNumericStringAttributeValue(value);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringOrderingMatchingRuleImpl.java
@@ -22,13 +22,10 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
@@ -38,12 +35,6 @@
 */
final class NumericStringOrderingMatchingRuleImpl extends AbstractOrderingMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_CASE_FOLD);
        if (buffer.length() == 0) {
            return ByteString.empty();
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeNumericStringAttributeValue(value);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NumericStringSubstringMatchingRuleImpl.java
@@ -22,13 +22,10 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StringPrepProfile.NO_CASE_FOLD;
import static com.forgerock.opendj.util.StringPrepProfile.TRIM;
import static com.forgerock.opendj.util.StringPrepProfile.prepareUnicode;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
@@ -38,12 +35,6 @@
 */
final class NumericStringSubstringMatchingRuleImpl extends AbstractSubstringMatchingRuleImpl {
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_CASE_FOLD);
        if (buffer.length() == 0) {
            return ByteString.empty();
        }
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeNumericStringAttributeValue(value);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/PresentationAddressEqualityMatchingRuleImpl.java
@@ -26,13 +26,11 @@
 */
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;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the presentationAddressMatch matching rule defined in
 * X.520 and referenced in RFC 2252. However, since this matching rule and the
@@ -40,24 +38,8 @@
 * like the caseIgnoreMatch rule.
 */
final class PresentationAddressEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, 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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ProtocolInformationEqualityMatchingRuleImpl.java
@@ -26,13 +26,11 @@
 */
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;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import static com.forgerock.opendj.util.StringPrepProfile.*;
/**
 * This class implements the protocolInformationMatch matching rule defined in
 * X.520 and referenced in RFC 2252. However, since this matching rule and the
@@ -40,24 +38,8 @@
 * like the caseIgnoreMatch rule.
 */
final class ProtocolInformationEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, 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 SchemaConstants.SINGLE_SPACE_VALUE;
            } else {
                // The value is empty, so it is already normalized.
                return ByteString.empty();
            }
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
        return SchemaUtils.normalizeStringAttributeValue(value, TRIM, CASE_FOLD);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java
@@ -22,14 +22,13 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 *      Portions copyright 2011-2014 ForgeRock AS
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StaticUtils.isAlpha;
import static com.forgerock.opendj.util.StaticUtils.isDigit;
import static com.forgerock.opendj.util.StaticUtils.isKeyChar;
import static com.forgerock.opendj.ldap.CoreMessages.*;
import static com.forgerock.opendj.util.StaticUtils.*;
import static com.forgerock.opendj.util.StringPrepProfile.*;
import java.util.ArrayList;
import java.util.Collections;
@@ -41,6 +40,8 @@
import java.util.Set;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import com.forgerock.opendj.util.SubstringReader;
@@ -116,8 +117,7 @@
            return values;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -162,8 +162,7 @@
            return values;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -279,8 +278,7 @@
        }
        if (length == 0) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_OID_NO_VALUE1.get(reader.pos() - 1);
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_OID_NO_VALUE1.get(reader.pos() - 1));
        }
        reader.reset();
@@ -336,13 +334,11 @@
                        }
                    } else if (!isDigit(c)) {
                        // Technically, this must be an illegal character.
                        // However,
                        // it is possible that someone just got sloppy and did
                        // not
                        // However, it is possible that someone just got sloppy
                        // and did not
                        // include a space between the name/OID and a closing
                        // parenthesis. In that case, we'll assume it's the end
                        // of
                        // the value.
                        // of the value.
                        if (c == ')') {
                            break;
                        }
@@ -421,8 +417,7 @@
            return oid;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -452,8 +447,7 @@
            return values;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -495,8 +489,7 @@
            reader.read();
            return str;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -536,12 +529,10 @@
            try {
                return Integer.valueOf(ruleID);
            } catch (final NumberFormatException e) {
                final LocalizableMessage message = ERR_ATTR_SYNTAX_RULE_ID_INVALID1.get(ruleID);
                throw DecodeException.error(message);
                throw DecodeException.error(ERR_ATTR_SYNTAX_RULE_ID_INVALID1.get(ruleID));
            }
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -570,8 +561,7 @@
            return values;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -617,8 +607,7 @@
            return token;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -725,8 +714,7 @@
            reader.read();
            return descr;
        } catch (final StringIndexOutOfBoundsException e) {
            final LocalizableMessage message = ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get();
            throw DecodeException.error(message);
            throw DecodeException.error(ERR_ATTR_SYNTAX_TRUNCATED_VALUE1.get());
        }
    }
@@ -735,4 +723,107 @@
        // Nothing to do.
    }
    private static ByteString singleSpaceOrEmpty(final ByteSequence value) {
        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 SchemaConstants.SINGLE_SPACE_VALUE;
        }
        // The value is empty, so it is already normalized.
        return ByteString.empty();
    }
    static ByteString normalizeStringListAttributeValue(final ByteSequence value, boolean trim, boolean foldCase) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, trim, foldCase);
        if (buffer.length() == 0) {
            return singleSpaceOrEmpty(value);
        }
        trimConsecutiveSpacesInStringList(buffer);
        return ByteString.valueOf(buffer.toString());
    }
    private static void trimConsecutiveSpacesInStringList(StringBuilder buffer) {
        // Replace any consecutive spaces with a single space. Any spaces
        // around a dollar sign will also be removed.
        for (int pos = buffer.length() - 1; pos > 0; pos--) {
            if (buffer.charAt(pos) == ' ') {
                final char c = buffer.charAt(pos - 1);
                if (c == ' ') {
                    buffer.delete(pos, pos + 1);
                } else if (c == '$') {
                    if (pos <= 1 || buffer.charAt(pos - 2) != '\\') {
                        buffer.delete(pos, pos + 1);
                    }
                } else if (buffer.charAt(pos + 1) == '$') {
                    buffer.delete(pos, pos + 1);
                }
            }
        }
    }
    static ByteString normalizeStringAttributeValue(final ByteSequence value, final boolean trim,
            final boolean foldCase) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, trim, foldCase);
        if (buffer.length() == 0) {
            return singleSpaceOrEmpty(value);
        }
        trimConsecutiveSpaces(buffer);
        return ByteString.valueOf(buffer.toString());
    }
    private static void trimConsecutiveSpaces(StringBuilder buffer) {
        for (int pos = buffer.length() - 1; pos > 0; pos--) {
            if (buffer.charAt(pos) == ' '
                    && buffer.charAt(pos - 1) == ' ') {
                buffer.delete(pos, pos + 1);
            }
        }
    }
    static ByteString normalizeIA5StringAttributeValue(final ByteSequence value, boolean trim, boolean foldCase)
            throws DecodeException {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, trim, foldCase);
        if (buffer.length() == 0) {
            return singleSpaceOrEmpty(value);
        }
        trimConsecutiveSpacesInIA5String(buffer, value);
        return ByteString.valueOf(buffer.toString());
    }
    private static void trimConsecutiveSpacesInIA5String(StringBuilder buffer, ByteSequence value)
            throws DecodeException {
        // Replace any consecutive spaces with a single space and watch out
        // for non-ASCII characters.
        for (int pos = buffer.length() - 1; pos > 0; pos--) {
            final char c = buffer.charAt(pos);
            if (c == ' ') {
                if (buffer.charAt(pos - 1) == ' ') {
                    buffer.delete(pos, pos + 1);
                }
            } else if ((c & 0x7F) != c) {
                // This is not a valid character for an IA5 string. If strict
                // syntax enforcement is enabled, then we'll throw an exception.
                // Otherwise, we'll get rid of the character.
                throw DecodeException.error(
                        WARN_ATTR_SYNTAX_IA5_ILLEGAL_CHARACTER.get(value, c));
            }
        }
    }
    static ByteString normalizeNumericStringAttributeValue(final ByteSequence value) {
        final StringBuilder buffer = new StringBuilder();
        prepareUnicode(buffer, value, TRIM, NO_CASE_FOLD);
        if (buffer.length() == 0) {
            return ByteString.empty();
        }
        return ByteString.valueOf(buffer.toString());
    }
}