opendj-core/clirr-ignored-api-changes.xml
@@ -67,4 +67,24 @@ <method>org.forgerock.opendj.ldap.spi.BindResultLdapPromiseImpl newBindLdapPromise(int, org.forgerock.opendj.ldap.requests.BindRequest, org.forgerock.opendj.ldap.requests.BindClient, org.forgerock.opendj.ldap.IntermediateResponseHandler, org.forgerock.opendj.ldap.spi.LDAPConnectionImpl)</method> <justification>Code cleanup: remove overloaded method with unused parameter</justification> </difference> <difference> <className>%regex[org/forgerock/opendj/ldap/schema/(AttributeType|DITContentRule|DITStructureRule|MatchingRule|MatchingRuleUse|NameForm|ObjectClass|Syntax)\$Builder]</className> <differenceType>7006</differenceType> <method>%regex[org\.forgerock\.opendj\.ldap\.schema\.SchemaElement\$SchemaElementBuilder (description|extraProperties|removeAllExtraProperties|removeExtraProperty)\([^)]*\)]</method> <to>org.forgerock.opendj.ldap.schema.AbstractSchemaElement$SchemaElementBuilder</to> <justification>Renamed class SchemaElement to AbstractSchemaElement</justification> </difference> <difference> <className>%regex[org/forgerock/opendj/ldap/schema/(AttributeType|DITContentRule|DITStructureRule|MatchingRule|MatchingRuleUse|NameForm|ObjectClass|Syntax)]</className> <differenceType>5001</differenceType> <to>org/forgerock/opendj/ldap/schema/**SchemaElement</to> <justification>Renamed class SchemaElement to AbstractSchemaElement</justification> </difference> <difference> <className>%regex[org/forgerock/opendj/ldap/schema/(AttributeType|DITContentRule|DITStructureRule|MatchingRule|MatchingRuleUse|NameForm|ObjectClass|Syntax)\$Builder]</className> <differenceType>5001</differenceType> <to>org/forgerock/opendj/ldap/schema/**SchemaElement$SchemaElementBuilder</to> <justification>Renamed class SchemaElement to AbstractSchemaElement</justification> </difference> </differences> opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSchemaElement.java
New file @@ -0,0 +1,287 @@ /* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2009 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. */ package org.forgerock.opendj.ldap.schema; import static org.forgerock.opendj.ldap.schema.SchemaUtils.unmodifiableCopyOfExtraProperties; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.forgerock.util.Reject; /** * An abstract base class for LDAP schema definitions which contain an * description, and an optional set of extra properties. * <p> * This class defines common properties and behaviour of the various types of * schema definitions (e.g. object class definitions, and attribute type * definitions). */ abstract class AbstractSchemaElement implements SchemaElement { static abstract class SchemaElementBuilder<T extends SchemaElementBuilder<T>> { private String definition; private String description; private final Map<String, List<String>> extraProperties; private final SchemaBuilder schemaBuilder; SchemaElementBuilder(final SchemaBuilder schemaBuilder) { this.schemaBuilder = schemaBuilder; this.description = ""; this.extraProperties = new LinkedHashMap<>(1); } SchemaElementBuilder(final SchemaBuilder schemaBuilder, final AbstractSchemaElement copy) { this.schemaBuilder = schemaBuilder; this.description = copy.description; this.extraProperties = new LinkedHashMap<>(copy.extraProperties); } /* * The abstract methods in this class are required in order to obtain * meaningful Javadoc. If the methods were defined in this class then * the resulting Javadoc in sub-class is invalid. The only workaround is * to make the methods abstract, provide "xxx0" implementations, and * override the abstract methods in sub-classes as delegates to the * "xxx0" methods. Ghastly! Thanks Javadoc. */ /** * Sets the description. * * @param description * The description, which may be {@code null} in which case * the empty string will be used. * @return This builder. */ public abstract T description(final String description); /** * Adds the provided collection of extended properties. * * @param extraProperties * The collection of extended properties. * @return This builder. */ public abstract T extraProperties(final Map<String, List<String>> extraProperties); /** * Adds the provided extended property. * * @param extensionName * The name of the extended property. * @param extensionValues * The optional list of values for the extended property. * @return This builder. */ public abstract T extraProperties(final String extensionName, final String... extensionValues); /** * Adds the provided extended property. * * @param extensionName * The name of the extended property. * @param extensionValues * The optional list of values for the extended property. * @return This builder. */ public T extraProperties(final String extensionName, final List<String> extensionValues) { return extraProperties(extensionName, extensionValues.toArray(new String[extensionValues.size()])); } /** * Removes all extra properties. * * @return This builder. */ public abstract T removeAllExtraProperties(); /** * Removes the specified extended property. * * @param extensionName * The name of the extended property. * @param extensionValues * The optional list of values for the extended property, * which may be empty indicating that the entire property * should be removed. * @return This builder. */ public abstract T removeExtraProperty(final String extensionName, final String... extensionValues); T definition(final String definition) { this.definition = definition; return getThis(); } T description0(final String description) { this.description = description == null ? "" : description; return getThis(); } T extraProperties0(final Map<String, List<String>> extraProperties) { this.extraProperties.putAll(extraProperties); return getThis(); } T extraProperties0(final String extensionName, final String... extensionValues) { if (this.extraProperties.get(extensionName) != null) { final List<String> tempExtraProperties = new ArrayList<>(this.extraProperties.get(extensionName)); tempExtraProperties.addAll(Arrays.asList(extensionValues)); this.extraProperties.put(extensionName, tempExtraProperties); } else { this.extraProperties.put(extensionName, Arrays.asList(extensionValues)); } return getThis(); } String getDescription() { return description; } Map<String, List<String>> getExtraProperties() { return extraProperties; } SchemaBuilder getSchemaBuilder() { return schemaBuilder; } abstract T getThis(); T removeAllExtraProperties0() { this.extraProperties.clear(); return getThis(); } T removeExtraProperty0(final String extensionName, final String... extensionValues) { if (this.extraProperties.get(extensionName) != null && extensionValues.length > 0) { final List<String> tempExtraProperties = new ArrayList<>(this.extraProperties.get(extensionName)); tempExtraProperties.removeAll(Arrays.asList(extensionValues)); this.extraProperties.put(extensionName, tempExtraProperties); } else if (this.extraProperties.get(extensionName) != null) { this.extraProperties.remove(extensionName); } return getThis(); } } /** Lazily created string representation. */ private String definition; /** The description for this definition. */ private final String description; /** The set of additional name-value pairs. */ private final Map<String, List<String>> extraProperties; AbstractSchemaElement() { this.description = ""; this.extraProperties = Collections.<String, List<String>> emptyMap(); this.definition = null; } AbstractSchemaElement(final SchemaElementBuilder<?> builder) { this.description = builder.description; this.extraProperties = unmodifiableCopyOfExtraProperties(builder.extraProperties); this.definition = builder.definition; } AbstractSchemaElement(final String description, final Map<String, List<String>> extraProperties, final String definition) { Reject.ifNull(description, extraProperties); this.description = description; this.extraProperties = extraProperties; // Should already be unmodifiable. this.definition = definition; } @Override public abstract boolean equals(Object obj); @Override public final String getDescription() { return description; } @Override public final Map<String, List<String>> getExtraProperties() { return extraProperties; } @Override public abstract int hashCode(); /** * Returns the string representation of this schema element as defined in * RFC 2252. * * @return The string representation of this schema element as defined in * RFC 2252. */ @Override public final String toString() { if (definition == null) { definition = buildDefinition(); } return definition; } final void appendDescription(final StringBuilder buffer) { if (description != null && description.length() > 0) { buffer.append(" DESC '"); buffer.append(description); buffer.append("'"); } } abstract void toStringContent(StringBuilder buffer); private final String buildDefinition() { final StringBuilder buffer = new StringBuilder(); buffer.append("( "); toStringContent(buffer); if (!extraProperties.isEmpty()) { for (final Map.Entry<String, List<String>> e : extraProperties.entrySet()) { final String property = e.getKey(); final List<String> valueList = e.getValue(); buffer.append(" "); buffer.append(property); if (valueList.size() == 1) { buffer.append(" '"); buffer.append(valueList.get(0)); buffer.append("'"); } else { buffer.append(" ( "); for (final String value : valueList) { buffer.append("'"); buffer.append(value); buffer.append("' "); } buffer.append(")"); } } } buffer.append(" )"); return buffer.toString(); } } opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AttributeType.java
@@ -47,7 +47,7 @@ * will be preserved when the associated fields are accessed via their getters * or via the {@link #toString()} methods. */ public final class AttributeType extends SchemaElement implements Comparable<AttributeType> { public final class AttributeType extends AbstractSchemaElement implements Comparable<AttributeType> { /** A fluent API for incrementally constructing attribute type. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITContentRule.java
@@ -41,7 +41,7 @@ * objectclass, and also indicates which auxiliary classes may be included in * the entry. */ public final class DITContentRule extends SchemaElement { public final class DITContentRule extends AbstractSchemaElement { /** A fluent API for incrementally constructing DIT content rule. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DITStructureRule.java
@@ -40,7 +40,7 @@ * This class defines a DIT structure rule, which is used to indicate the types * of children that entries may have. */ public final class DITStructureRule extends SchemaElement { public final class DITStructureRule extends AbstractSchemaElement { /** A fluent API for incrementally constructing DIT structure rules. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
@@ -48,7 +48,7 @@ * will be preserved when the associated fields are accessed via their getters * or via the {@link #toString()} methods. */ public final class MatchingRule extends SchemaElement { public final class MatchingRule extends AbstractSchemaElement { /** A fluent API for incrementally constructing matching rules. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleUse.java
@@ -40,7 +40,7 @@ * matching rule use definition, which may be used to restrict the set of * attribute types that may be used for a given matching rule. */ public final class MatchingRuleUse extends SchemaElement { public final class MatchingRuleUse extends AbstractSchemaElement { /** A fluent API for incrementally constructing matching rule uses. */ public static final class Builder extends SchemaElementBuilder<Builder> { private String oid; opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java
@@ -40,7 +40,7 @@ * form, which defines the attribute type(s) that must and/or may be used in the * RDN of an entry with a given structural objectclass. */ public final class NameForm extends SchemaElement { public final class NameForm extends AbstractSchemaElement { /** A fluent API for incrementally constructing name forms. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/ObjectClass.java
@@ -47,7 +47,7 @@ * provided, the ordering will be preserved when the associated fields are * accessed via their getters or via the {@link #toString()} methods. */ public final class ObjectClass extends SchemaElement { public final class ObjectClass extends AbstractSchemaElement { /** A fluent API for incrementally constructing object classes. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaElement.java
@@ -11,289 +11,30 @@ * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2009 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. * Copyright 2016 ForgeRock AS. */ package org.forgerock.opendj.ldap.schema; import static org.forgerock.opendj.ldap.schema.SchemaUtils.unmodifiableCopyOfExtraProperties; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.forgerock.util.Reject; /** * An abstract base class for LDAP schema definitions which contain an * description, and an optional set of extra properties. * <p> * This class defines common properties and behaviour of the various types of * schema definitions (e.g. object class definitions, and attribute type * definitions). * Interface for schema elements. */ abstract class SchemaElement { static abstract class SchemaElementBuilder<T extends SchemaElementBuilder<T>> { private String definition; private String description; private final Map<String, List<String>> extraProperties; private final SchemaBuilder schemaBuilder; SchemaElementBuilder(final SchemaBuilder schemaBuilder) { this.schemaBuilder = schemaBuilder; this.description = ""; this.extraProperties = new LinkedHashMap<>(1); } SchemaElementBuilder(final SchemaBuilder schemaBuilder, final SchemaElement copy) { this.schemaBuilder = schemaBuilder; this.description = copy.description; this.extraProperties = new LinkedHashMap<>(copy.extraProperties); } /* * The abstract methods in this class are required in order to obtain * meaningful Javadoc. If the methods were defined in this class then * the resulting Javadoc in sub-class is invalid. The only workaround is * to make the methods abstract, provide "xxx0" implementations, and * override the abstract methods in sub-classes as delegates to the * "xxx0" methods. Ghastly! Thanks Javadoc. */ /** * Sets the description. * * @param description * The description, which may be {@code null} in which case * the empty string will be used. * @return This builder. */ public abstract T description(final String description); /** * Adds the provided collection of extended properties. * * @param extraProperties * The collection of extended properties. * @return This builder. */ public abstract T extraProperties(final Map<String, List<String>> extraProperties); /** * Adds the provided extended property. * * @param extensionName * The name of the extended property. * @param extensionValues * The optional list of values for the extended property. * @return This builder. */ public abstract T extraProperties(final String extensionName, final String... extensionValues); /** * Adds the provided extended property. * * @param extensionName * The name of the extended property. * @param extensionValues * The optional list of values for the extended property. * @return This builder. */ public T extraProperties(final String extensionName, final List<String> extensionValues) { return extraProperties(extensionName, extensionValues.toArray(new String[extensionValues.size()])); } /** * Removes all extra properties. * * @return This builder. */ public abstract T removeAllExtraProperties(); /** * Removes the specified extended property. * * @param extensionName * The name of the extended property. * @param extensionValues * The optional list of values for the extended property, * which may be empty indicating that the entire property * should be removed. * @return This builder. */ public abstract T removeExtraProperty(final String extensionName, final String... extensionValues); T definition(final String definition) { this.definition = definition; return getThis(); } T description0(final String description) { this.description = description == null ? "" : description; return getThis(); } T extraProperties0(final Map<String, List<String>> extraProperties) { this.extraProperties.putAll(extraProperties); return getThis(); } T extraProperties0(final String extensionName, final String... extensionValues) { if (this.extraProperties.get(extensionName) != null) { final List<String> tempExtraProperties = new ArrayList<>(this.extraProperties.get(extensionName)); tempExtraProperties.addAll(Arrays.asList(extensionValues)); this.extraProperties.put(extensionName, tempExtraProperties); } else { this.extraProperties.put(extensionName, Arrays.asList(extensionValues)); } return getThis(); } String getDescription() { return description; } Map<String, List<String>> getExtraProperties() { return extraProperties; } SchemaBuilder getSchemaBuilder() { return schemaBuilder; } abstract T getThis(); T removeAllExtraProperties0() { this.extraProperties.clear(); return getThis(); } T removeExtraProperty0(final String extensionName, final String... extensionValues) { if (this.extraProperties.get(extensionName) != null && extensionValues.length > 0) { final List<String> tempExtraProperties = new ArrayList<>(this.extraProperties.get(extensionName)); tempExtraProperties.removeAll(Arrays.asList(extensionValues)); this.extraProperties.put(extensionName, tempExtraProperties); } else if (this.extraProperties.get(extensionName) != null) { this.extraProperties.remove(extensionName); } return getThis(); } } /** Lazily created string representation. */ private String definition; /** The description for this definition. */ private final String description; /** The set of additional name-value pairs. */ private final Map<String, List<String>> extraProperties; SchemaElement() { this.description = ""; this.extraProperties = Collections.<String, List<String>> emptyMap(); this.definition = null; } SchemaElement(final SchemaElementBuilder<?> builder) { this.description = builder.description; this.extraProperties = unmodifiableCopyOfExtraProperties(builder.extraProperties); this.definition = builder.definition; } SchemaElement(final String description, final Map<String, List<String>> extraProperties, final String definition) { Reject.ifNull(description, extraProperties); this.description = description; this.extraProperties = extraProperties; // Should already be unmodifiable. this.definition = definition; } @Override public abstract boolean equals(Object obj); public interface SchemaElement { /** * Returns the description of this schema element, or the empty string if it * does not have a description. * Returns the description of this schema element, or the empty string if it does not have a description. * * @return The description of this schema element, or the empty string if it * does not have a description. * @return The description of this schema element, or the empty string if it does not have a description. */ public final String getDescription() { return description; } String getDescription(); /** * Returns an unmodifiable map containing all of the extra properties * associated with this schema element. * Returns an unmodifiable map containing all of the extra properties associated with this schema element. * * @return An unmodifiable map containing all of the extra properties * associated with this schema element. * @return An unmodifiable map containing all of the extra properties associated with this schema element. */ public final Map<String, List<String>> getExtraProperties() { return extraProperties; } Map<String, List<String>> getExtraProperties(); @Override public abstract int hashCode(); /** * Returns the string representation of this schema element as defined in * RFC 2252. * * @return The string representation of this schema element as defined in * RFC 2252. */ @Override public final String toString() { if (definition == null) { definition = buildDefinition(); } return definition; } final void appendDescription(final StringBuilder buffer) { if (description != null && description.length() > 0) { buffer.append(" DESC '"); buffer.append(description); buffer.append("'"); } } abstract void toStringContent(StringBuilder buffer); private final String buildDefinition() { final StringBuilder buffer = new StringBuilder(); buffer.append("( "); toStringContent(buffer); if (!extraProperties.isEmpty()) { for (final Map.Entry<String, List<String>> e : extraProperties.entrySet()) { final String property = e.getKey(); final List<String> valueList = e.getValue(); buffer.append(" "); buffer.append(property); if (valueList.size() == 1) { buffer.append(" '"); buffer.append(valueList.get(0)); buffer.append("'"); } else { buffer.append(" ( "); for (final String value : valueList) { buffer.append("'"); buffer.append(value); buffer.append("' "); } buffer.append(")"); } } } buffer.append(" )"); return buffer.toString(); } } opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Syntax.java
@@ -43,7 +43,7 @@ * will be preserved when the associated fields are accessed via their getters * or via the {@link #toString()} methods. */ public final class Syntax extends SchemaElement { public final class Syntax extends AbstractSchemaElement { /** A fluent API for incrementally constructing syntaxes. */ public static final class Builder extends SchemaElementBuilder<Builder> { opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AbstractSchemaElementTestCase.java
@@ -50,14 +50,14 @@ * If the test failed unexpectedly. */ @Test(dataProvider = "equalsTestData") public final void testEquals(final SchemaElement e1, final SchemaElement e2, public final void testEquals(final AbstractSchemaElement e1, final AbstractSchemaElement e2, final boolean result) throws Exception { Assert.assertEquals(e1.equals(e2), result); Assert.assertEquals(e2.equals(e1), result); } /** * Check that the {@link SchemaElement#getDescription()} method returns a * Check that the {@link AbstractSchemaElement#getDescription()} method returns a * description. * * @throws Exception @@ -65,12 +65,12 @@ */ @Test public final void testGetDescription() throws Exception { final SchemaElement e = getElement("hello", EMPTY_PROPS); final AbstractSchemaElement e = getElement("hello", EMPTY_PROPS); Assert.assertEquals(e.getDescription(), "hello"); } /** * Check that the {@link SchemaElement#getDescription()} method returns * Check that the {@link AbstractSchemaElement#getDescription()} method returns * <code>null</code> when there is no description. * * @throws Exception @@ -78,12 +78,12 @@ */ @Test public final void testGetDescriptionDefault() throws Exception { final SchemaElement e = getElement("", EMPTY_PROPS); final AbstractSchemaElement e = getElement("", EMPTY_PROPS); Assert.assertEquals(e.getDescription(), ""); } /** * Check that the {@link SchemaElement#getExtraProperties()} method * Check that the {@link AbstractSchemaElement#getExtraProperties()} method * returns values. * * @throws Exception @@ -95,7 +95,7 @@ values.add("one"); values.add("two"); final Map<String, List<String>> props = Collections.singletonMap("test", values); final SchemaElement e = getElement("", props); final AbstractSchemaElement e = getElement("", props); int i = 0; for (final String value : e.getExtraProperties().get("test")) { @@ -105,7 +105,7 @@ } /** * Check that the {@link SchemaElement#getExtraProperties()} method * Check that the {@link AbstractSchemaElement#getExtraProperties()} method * returns <code>null</code> when there is no property. * * @throws Exception @@ -113,7 +113,7 @@ */ @Test public final void testGetExtraPropertyDefault() throws Exception { final SchemaElement e = getElement("", EMPTY_PROPS); final AbstractSchemaElement e = getElement("", EMPTY_PROPS); Assert.assertNull(e.getExtraProperties().get("test")); } @@ -130,11 +130,11 @@ * If the test failed unexpectedly. */ @Test(dataProvider = "equalsTestData") public final void testHashCode(final SchemaElement e1, final SchemaElement e2, public final void testHashCode(final AbstractSchemaElement e1, final AbstractSchemaElement e2, final boolean result) throws Exception { Assert.assertEquals(e1.hashCode() == e2.hashCode(), result); } protected abstract SchemaElement getElement(String description, protected abstract AbstractSchemaElement getElement(String description, Map<String, List<String>> extraProperties) throws SchemaException; } opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/AttributeTypeTest.java
@@ -530,7 +530,7 @@ } @Override protected SchemaElement getElement(final String description, protected AbstractSchemaElement getElement(final String description, final Map<String, List<String>> extraProperties) throws SchemaException { final SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema()); builder.buildAttributeType("1.2.3") opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/ObjectClassBuilderTestCase.java
@@ -171,21 +171,21 @@ ocBuilder.addToSchema().toSchema(); } private void assertSchemaElementsContainsAll(final Set<? extends SchemaElement> elements, private void assertSchemaElementsContainsAll(final Set<? extends AbstractSchemaElement> elements, final Set<String> namesOrOIDs) throws Exception { assertSchemaElementsContainsAll(elements, namesOrOIDs.toArray(new String[namesOrOIDs.size()])); } private void assertSchemaElementsContainsAll(final Set<? extends SchemaElement> elements, private void assertSchemaElementsContainsAll(final Set<? extends AbstractSchemaElement> elements, final String... namesOrOIDs) throws Exception { for (final String nameOrOID : namesOrOIDs) { assertThat(assertSchemaElementsContains(elements, nameOrOID)).isTrue(); } } private boolean assertSchemaElementsContains(final Set<? extends SchemaElement> elements, final String nameOrOID) { for (final SchemaElement element : elements) { private boolean assertSchemaElementsContains(final Set<? extends AbstractSchemaElement> elements, final String nameOrOID) { for (final AbstractSchemaElement element : elements) { final String oid = element instanceof AttributeType ? ((AttributeType) element).getNameOrOID() : ((ObjectClass) element).getNameOrOID(); if (oid.equals(nameOrOID)) {