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"); } /**