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

Jean-Noel Rouvignac
05.48.2014 2dbccd52b144afe4813d0f70a335862009cbd750
OPENDJ-1308 Migrate schema support

Preparation work for adding the index query factory support code.

AbstractMatchingRuleImpl.java:
Renamed DefaultEqualityAssertion to DefaultAssertion.
Made DefaultAssertion ctor private.
Added equality() and approximate() static methods + indexID field to DefaultAssertion.

*.java:
Consequence of this change.
Some code cleanups.

CertificateExactMatchingRuleImpl.java:
Reworked the code a bit + extracted method normalizeDN().
8 files modified
170 ■■■■■ changed files
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractApproximateMatchingRuleImpl.java 2 ●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractEqualityMatchingRuleImpl.java 2 ●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java 16 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImpl.java 59 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java 6 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java 10 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierEqualityMatchingRuleImpl.java 60 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java 15 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractApproximateMatchingRuleImpl.java
@@ -42,7 +42,7 @@
    @Override
    public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue)
            throws DecodeException {
        return new DefaultEqualityAssertion(normalizeAttributeValue(schema, assertionValue));
        return DefaultAssertion.approximate(normalizeAttributeValue(schema, assertionValue));
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractEqualityMatchingRuleImpl.java
@@ -42,7 +42,7 @@
    @Override
    public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue)
            throws DecodeException {
        return new DefaultEqualityAssertion(normalizeAttributeValue(schema, assertionValue));
        return DefaultAssertion.equality(normalizeAttributeValue(schema, assertionValue));
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java
@@ -39,10 +39,22 @@
 * matches normalized values in byte order.
 */
abstract class AbstractMatchingRuleImpl implements MatchingRuleImpl {
    static final class DefaultEqualityAssertion implements Assertion {
    static final class DefaultAssertion implements Assertion {
        /** The ID of the DB index that to use with this assertion.*/
        private final String indexID;
        private final ByteSequence normalizedAssertionValue;
        DefaultEqualityAssertion(final ByteSequence normalizedAssertionValue) {
        static DefaultAssertion equality(final ByteSequence normalizedAssertionValue) {
            return new DefaultAssertion("equality", normalizedAssertionValue);
        }
        static DefaultAssertion approximate(final ByteSequence normalizedAssertionValue) {
            return new DefaultAssertion("approximate", normalizedAssertionValue);
        }
        private DefaultAssertion(final String indexID, final ByteSequence normalizedAssertionValue) {
            this.indexID = indexID;
            this.normalizedAssertionValue = normalizedAssertionValue;
        }
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImpl.java
@@ -23,6 +23,7 @@
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2013-2014 Manuel Gaupp
 *      Copyright 2014 ForgeRock AS
 */
package org.forgerock.opendj.ldap.schema;
@@ -32,9 +33,9 @@
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;
import com.forgerock.opendj.util.StaticUtils;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.Assertion;
@@ -45,11 +46,9 @@
import org.forgerock.opendj.ldap.GSERParser;
import org.forgerock.opendj.ldap.DN;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_MR_CERTIFICATE_MATCH_EXPECTED_END;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_MR_CERTIFICATE_MATCH_GSER_INVALID;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_MR_CERTIFICATE_MATCH_INVALID_DN;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_MR_CERTIFICATE_MATCH_IDENTIFIER_NOT_FOUND;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_MR_CERTIFICATE_MATCH_PARSE_ERROR;
import com.forgerock.opendj.util.StaticUtils;
import static com.forgerock.opendj.ldap.CoreMessages.*;
/**
 * This class implements the certificateExactMatch matching rule defined in
@@ -83,16 +82,15 @@
     *
     * @return The normalized version of the provided value.
     *
     * @throws DirectoryException If the provided value is invalid according to
     * @throws DecodeException If the provided value is invalid according to
     * the associated attribute syntax.
     */
    @Override
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
            throws DecodeException {
        // Read the X.509 Certificate and extract serialNumber and issuerDN
        final BigInteger serialNumber;
        final String dnstring;
        String certificateIssuer;
        // Read the X.509 Certificate and extract serialNumber and issuerDN
        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            InputStream inputStream = new ByteArrayInputStream(value.toByteArray());
@@ -112,38 +110,19 @@
            return value.toByteString();
        }
        // Normalize the DN
        try {
            DN dn = DN.valueOf(dnstring, schema.asNonStrictSchema());
            certificateIssuer = dn.toNormalizedString();
        } catch (Exception e) {
            // We couldn't normalize the DN for some reason.
            final LocalizableMessage message
                = ERR_MR_CERTIFICATE_MATCH_INVALID_DN.get(dnstring,
                    StaticUtils.getExceptionMessage(e));
            throw DecodeException.error(message);
        }
        // Create the encoded value
        final String certificateIssuer = normalizeDN(schema, dnstring);
        return createEncodedValue(serialNumber, certificateIssuer);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Assertion getAssertion(final Schema schema, final ByteSequence value)
            throws DecodeException {
        // validate and normalize the GSER structure
        // according to the definitions from RFC 4523, Appendix A.1
        final BigInteger serialNumber;
        final String dnstring;
        String certificateIssuer;
        final GSERParser parser;
        String identifier;
        parser = new GSERParser(value.toString());
        final GSERParser parser = new GSERParser(value.toString());
        try {
            // the String starts with a sequence
            parser.readStartSequence();
@@ -152,9 +131,12 @@
            // Assume the assertion value is a certificate and parse issuer and
            // serial number. If the value is not even a certificate then the
            // raw bytes will be returned.
            return new DefaultEqualityAssertion(normalizeAttributeValue(schema, value));
            return DefaultAssertion.equality(normalizeAttributeValue(schema, value));
        }
        final BigInteger serialNumber;
        final String dnstring;
        String identifier;
        try {
            // the first namedValue is serialNumber
            identifier = parser.nextNamedValueIdentifier();
@@ -203,10 +185,14 @@
            throw DecodeException.error(message);
        }
        // Normalize the DN
        final String certificateIssuer = normalizeDN(schema, dnstring);
        return DefaultAssertion.equality(createEncodedValue(serialNumber, certificateIssuer));
    }
    private String normalizeDN(final Schema schema, final String dnstring) throws DecodeException {
        try {
            DN dn = DN.valueOf(dnstring, schema.asNonStrictSchema());
            certificateIssuer = dn.toNormalizedString();
            return dn.toNormalizedString();
        } catch (Exception e) {
            logger.traceException(e);
@@ -216,9 +202,6 @@
                            StaticUtils.getExceptionMessage(e));
            throw DecodeException.error(message);
        }
        // Create the encoded value
        return new DefaultEqualityAssertion(createEncodedValue(serialNumber, certificateIssuer));
    }
    /**
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DirectoryStringFirstComponentEqualityMatchingRuleImpl.java
@@ -47,9 +47,10 @@
 * after the opening parenthesis.
 */
final class DirectoryStringFirstComponentEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue) {
        return new DefaultEqualityAssertion(SchemaUtils.normalizeStringAttributeValue(assertionValue, TRIM, CASE_FOLD));
        return DefaultAssertion.equality(SchemaUtils.normalizeStringAttributeValue(assertionValue, TRIM, CASE_FOLD));
    }
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
@@ -62,8 +63,7 @@
        reader.skipWhitespaces();
        if (reader.remaining() <= 0) {
            // This means that the value was empty or contained only
            // whitespace.
            // This means that the value was empty or contained only whitespace.
            // That is illegal.
            throw DecodeException.error(ERR_ATTR_SYNTAX_EMPTY_VALUE.get());
        }
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/IntegerFirstComponentEqualityMatchingRuleImpl.java
@@ -55,7 +55,7 @@
            final String definition = assertionValue.toString();
            final SubstringReader reader = new SubstringReader(definition);
            final int intValue = SchemaUtils.readRuleID(reader);
            return new DefaultEqualityAssertion(ByteString.valueOf(intValue));
            return DefaultAssertion.equality(ByteString.valueOf(intValue));
        } catch (final Exception e) {
            logger.debug(LocalizableMessage.raw("%s", e));
@@ -63,7 +63,6 @@
                    ERR_EMR_INTFIRSTCOMP_FIRST_COMPONENT_NOT_INT.get(assertionValue.toString());
            throw DecodeException.error(message);
        }
    }
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
@@ -82,8 +81,8 @@
            throw DecodeException.error(message);
        }
        // The next character must be an open parenthesis. If it is not,
        // then that is an error.
        // 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 =
@@ -92,8 +91,7 @@
            throw DecodeException.error(message);
        }
        // Skip over any spaces immediately following the opening
        // parenthesis.
        // Skip over any spaces immediately following the opening parenthesis.
        reader.skipWhitespaces();
        // The next set of characters must be the OID.
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierEqualityMatchingRuleImpl.java
@@ -41,57 +41,37 @@
 * rule requires a schema to lookup object identifiers in the descriptor form.
 */
final class ObjectIdentifierEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    static String resolveNames(final Schema schema, final String oid) {
        if (!StaticUtils.isDigit(oid.charAt(0))) {
            // Do an best effort attempt to normalize names to OIDs.
            String schemaName = null;
            if (schema.hasAttributeType(oid)) {
                schemaName = schema.getAttributeType(oid).getOID();
            }
            if (schemaName == null) {
                if (schema.hasDITContentRule(oid)) {
                    schemaName = schema.getDITContentRule(oid).getStructuralClass().getOID();
                }
            if (schemaName == null && schema.hasDITContentRule(oid)) {
                schemaName = schema.getDITContentRule(oid).getStructuralClass().getOID();
            }
            if (schemaName == null) {
                if (schema.hasSyntax(oid)) {
                    schemaName = schema.getSyntax(oid).getOID();
                }
            if (schemaName == null && schema.hasSyntax(oid)) {
                schemaName = schema.getSyntax(oid).getOID();
            }
            if (schemaName == null) {
                if (schema.hasObjectClass(oid)) {
                    schemaName = schema.getObjectClass(oid).getOID();
                }
            if (schemaName == null && schema.hasObjectClass(oid)) {
                schemaName = schema.getObjectClass(oid).getOID();
            }
            if (schemaName == null) {
                if (schema.hasMatchingRule(oid)) {
                    schemaName = schema.getMatchingRule(oid).getOID();
                }
            if (schemaName == null && schema.hasMatchingRule(oid)) {
                schemaName = schema.getMatchingRule(oid).getOID();
            }
            if (schemaName == null) {
                if (schema.hasMatchingRuleUse(oid)) {
                    schemaName = schema.getMatchingRuleUse(oid).getMatchingRule().getOID();
                }
            if (schemaName == null && schema.hasMatchingRuleUse(oid)) {
                schemaName = schema.getMatchingRuleUse(oid).getMatchingRule().getOID();
            }
            if (schemaName == null) {
                if (schema.hasNameForm(oid)) {
                    schemaName = schema.getNameForm(oid).getOID();
                }
            if (schemaName == null && schema.hasNameForm(oid)) {
                schemaName = schema.getNameForm(oid).getOID();
            }
            if (schemaName != null) {
                return schemaName;
            } else {
                return StaticUtils.toLowerCase(oid);
            }
            return StaticUtils.toLowerCase(oid);
        }
        return oid;
    }
@@ -101,19 +81,17 @@
            throws DecodeException {
        final String definition = assertionValue.toString();
        final SubstringReader reader = new SubstringReader(definition);
        final String normalized =
                resolveNames(schema, SchemaUtils.readOID(reader, schema
                        .allowMalformedNamesAndOptions()));
        return new DefaultEqualityAssertion(ByteString.valueOf(normalized));
        final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions());
        final String normalized = resolveNames(schema, oid);
        return DefaultAssertion.equality(ByteString.valueOf(normalized));
    }
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
            throws DecodeException {
        final String definition = value.toString();
        final SubstringReader reader = new SubstringReader(definition);
        final String normalized =
                resolveNames(schema, SchemaUtils.readOID(reader, schema
                        .allowMalformedNamesAndOptions()));
        final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions());
        final String normalized = resolveNames(schema, oid);
        return ByteString.valueOf(normalized);
    }
}
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectIdentifierFirstComponentEqualityMatchingRuleImpl.java
@@ -46,15 +46,15 @@
 * after the opening parenthesis.
 */
final class ObjectIdentifierFirstComponentEqualityMatchingRuleImpl extends AbstractEqualityMatchingRuleImpl {
    @Override
    public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue)
            throws DecodeException {
        final String definition = assertionValue.toString();
        final SubstringReader reader = new SubstringReader(definition);
        final String normalized =
                ObjectIdentifierEqualityMatchingRuleImpl.resolveNames(schema, SchemaUtils.readOID(
                        reader, schema.allowMalformedNamesAndOptions()));
        return new DefaultEqualityAssertion(ByteString.valueOf(normalized));
        final String oid = SchemaUtils.readOID(reader, schema.allowMalformedNamesAndOptions());
        final String normalized = ObjectIdentifierEqualityMatchingRuleImpl.resolveNames(schema, oid);
        return DefaultAssertion.equality(ByteString.valueOf(normalized));
    }
    public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value)
@@ -73,8 +73,8 @@
            throw DecodeException.error(message);
        }
        // The next character must be an open parenthesis. If it is not,
        // then that is an error.
        // 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 =
@@ -83,8 +83,7 @@
            throw DecodeException.error(message);
        }
        // Skip over any spaces immediately following the opening
        // parenthesis.
        // Skip over any spaces immediately following the opening parenthesis.
        reader.skipWhitespaces();
        // The next set of characters must be the OID.