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

Matthew Swift
05.01.2016 c68958711a12eaf193fdb9d3770ec2bb6015b73c
OPENDJSDK-96 Add schema option for tolerating attribute type definitions without a SUP or SYNTAX

* added SchemaOptions#ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX
* updated SchemaBuilder/AttributeType to use the new option
* updated unit tests to deal with change in behavior.
5 files modified
117 ■■■■■ changed files
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java 24 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaOptions.java 12 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java 59 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java 20 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
@@ -19,6 +19,7 @@
import static java.util.Arrays.*;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.*;
import static org.forgerock.opendj.ldap.schema.SchemaOptions.ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX;
import static org.forgerock.opendj.ldap.schema.SchemaUtils.*;
import static com.forgerock.opendj.ldap.CoreMessages.*;
@@ -97,7 +98,7 @@
         *             numeric OID.
         */
        public SchemaBuilder addToSchema() {
            return getSchemaBuilder().addAttributeType(new AttributeType(this), false);
            return addToSchema(false);
        }
        /**
@@ -107,19 +108,11 @@
         * @return The parent schema builder.
         */
        public SchemaBuilder addToSchemaOverwrite() {
            return getSchemaBuilder().addAttributeType(new AttributeType(this), true);
            return addToSchema(true);
        }
        /**
         * Adds this attribute type to the schema, overwriting any existing attribute type
         * with the same numeric OID if the overwrite parameter is set to {@code true}.
         *
         * @param overwrite
         *            {@code true} if any attribute type with the same OID should be overwritten.
         * @return The parent schema builder.
         */
        SchemaBuilder addToSchema(final boolean overwrite) {
            return overwrite ? addToSchemaOverwrite() : addToSchema();
            return getSchemaBuilder().addAttributeType(new AttributeType(this), overwrite);
        }
        /**
@@ -424,8 +417,11 @@
    private AttributeType(Builder builder) {
        super(builder);
        Reject.ifTrue(builder.oid == null || builder.oid.isEmpty(), "An OID must be specified.");
        Reject.ifTrue(builder.superiorTypeOID == null && builder.syntaxOID == null,
                "Superior type and/or Syntax must not be null");
        if (builder.superiorTypeOID == null && builder.syntaxOID == null
                && !builder.getSchemaBuilder().getOptions().get(ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX)) {
            throw new IllegalArgumentException("Superior type and/or Syntax must not be null");
        }
        oid = builder.oid;
        names = unmodifiableCopyOfList(builder.names);
@@ -989,6 +985,8 @@
        } else if (getSuperiorType() != null && getSuperiorType().getSyntax() != null) {
            // Try to inherit the syntax from the superior type if possible
            syntax = getSuperiorType().getSyntax();
        } else {
            syntax = schema.getDefaultSyntax();
        }
        if (equalityMatchingRuleOID != null) {
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -364,7 +364,7 @@
                atBuilder.approximateMatchingRule(approxRules.get(0));
            }
            if (superiorType == null && syntax == null) {
            if (superiorType == null && syntax == null && !options.get(ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX)) {
                throw new LocalizedIllegalArgumentException(
                    WARN_ATTR_SYNTAX_ATTRTYPE_MISSING_SYNTAX_AND_SUPERIOR.get(definition));
            }
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaOptions.java
@@ -11,7 +11,7 @@
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2014-2015 ForgeRock AS.
 * Copyright 2014-2016 ForgeRock AS.
 */
package org.forgerock.opendj.ldap.schema;
@@ -51,6 +51,16 @@
    public static final Option<Boolean> ALLOW_MALFORMED_NAMES_AND_OPTIONS = Option.withDefault(true);
    /**
     * Specifies whether the schema should allow attribute type definitions that do not declare a superior attribute
     * type or syntax. When this compatibility option is set to {@code true} invalid attribute type definitions will
     * use the default syntax specifed by the {@link #DEFAULT_SYNTAX_OID} option.
     * <p>
     * By default this compatibility option is set to {@code true} in order to remain compatible with previous
     * versions of OpenDJ.
     */
    public static final Option<Boolean> ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX = Option.withDefault(true);
    /**
     * Specifies whether the JPEG Photo syntax should allow values which
     * do not conform to the JFIF or Exif specifications.
     * <p>
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java
@@ -16,6 +16,7 @@
 */
package org.forgerock.opendj.ldap.schema;
import static org.assertj.core.api.Assertions.assertThat;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.*;
import java.util.Iterator;
@@ -481,37 +482,39 @@
        Assert.assertFalse(type.isSingleValue());
    }
    /**
     * Check that the simple constructor throws an NPE when mandatory parameters
     * are not specified.
     *
     * @throws Exception
     *             If the test failed unexpectedly.
     */
    @Test(expectedExceptions = IllegalArgumentException.class)
    public void testNoSupNorSyntax1() throws Exception {
        final SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
        builder.buildAttributeType("1.2.1")
               .names(EMPTY_NAMES)
               .obsolete(true)
               .usage(AttributeUsage.DSA_OPERATION)
               .addToSchema();
        builder.addAttributeType("( 1.2.2 OBSOLETE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", false);
    @Test(expectedExceptions = LocalizedIllegalArgumentException.class)
    public void attributeTypeDefinitionsRequireSyntaxOrSuperiorWhenStrict1() throws Exception {
        new SchemaBuilder(Schema.getCoreSchema())
                .setOption(SchemaOptions.ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX, false)
                .addAttributeType("(1.2.1)", true);
    }
    /**
     * Check that the simple constructor throws an NPE when mandatory parameters
     * are not specified.
     *
     * @throws Exception
     *             If the test failed unexpectedly.
     */
    @Test(expectedExceptions = IllegalArgumentException.class)
    public void testNoSupNorSyntax2() throws Exception {
        final SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
        builder.addAttributeType("( 1.2.2 OBSOLETE SINGLE-VALUE )", false);
    public void attributeTypeDefinitionsRequireSyntaxOrSuperiorWhenStrict2() throws Exception {
        new SchemaBuilder(Schema.getCoreSchema())
                .setOption(SchemaOptions.ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX, false)
                .buildAttributeType("1.2.1")
                .addToSchema();
    }
    @Test
    public void attributeTypeDefinitionsDoNotRequireSyntaxOrSuperiorWhenTolerant1() throws Exception {
        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
                .addAttributeType("(1.2.1)", true).toSchema();
        assertThat(schema.getWarnings()).isEmpty();
        assertThat(schema.getAttributeType("1.2.1").getSuperiorType()).isNull();
        assertThat(schema.getAttributeType("1.2.1").getSyntax()).isSameAs(schema.getDefaultSyntax());
    }
    @Test
    public void attributeTypeDefinitionsDoNotRequireSyntaxOrSuperiorWhenTolerant2() throws Exception {
        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
                .buildAttributeType("1.2.1")
                .addToSchema()
                .toSchema();
        assertThat(schema.getWarnings()).isEmpty();
        assertThat(schema.getAttributeType("1.2.1").getSuperiorType()).isNull();
        assertThat(schema.getAttributeType("1.2.1").getSyntax()).isSameAs(schema.getDefaultSyntax());
    }
    @Test
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/SchemaBuilderTestCase.java
@@ -84,11 +84,23 @@
                "1.3.6.1.4.1.1466.115.121.1.15");
    }
    /** Tests that attribute types must have a syntax or a superior. */
    /** Tests that attribute types must have a syntax or a superior when strict. */
    @Test(expectedExceptions = LocalizedIllegalArgumentException.class)
    public void attributeTypeNoSuperiorNoSyntax() {
        new SchemaBuilder(Schema.getCoreSchema()).addAttributeType(
                "( parenttype-oid NAME 'parenttype' )", false);
    public void attributeTypeNoSuperiorNoSyntaxWhenStrict() {
        new SchemaBuilder(Schema.getCoreSchema())
                .setOption(ALLOW_ATTRIBUTE_TYPES_WITH_NO_SUP_OR_SYNTAX, false)
                .addAttributeType("( parenttype-oid NAME 'parenttype' )", false);
    }
    /** Tests that attribute types do not have to have a syntax or a superior when leniant. */
    @Test
    public void attributeTypeNoSuperiorNoSyntaxWhenLeniant() {
        final Schema schema = new SchemaBuilder(Schema.getCoreSchema())
                .addAttributeType("( parenttype-oid NAME 'parenttype' )", false)
                .toSchema();
        assertThat(schema.getAttributeType("parenttype").getSyntax()).isNotNull();
        assertThat(schema.getAttributeType("parenttype").getSyntax().getOID())
                .isEqualTo("1.3.6.1.4.1.1466.115.121.1.40");
    }
    /**