From 22117901143acf6b4d8c449ee88fab4fe1e4baf9 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Wed, 05 Sep 2007 20:12:11 +0000
Subject: [PATCH] Partial fix for issue 1449: administration framework aggregation support
---
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java | 11
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/AggregationTest.java | 357 +++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java | 108 +
opendj-sdk/opends/resource/admin/property-types.xsl | 1
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyValueVisitor.java | 29
opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java | 174 ++
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java | 144 ++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java | 25
opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java | 85 +
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildConfiguration.xml | 24
opendj-sdk/opends/src/server/org/opends/server/admin/Reference.java | 245 +++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java | 12
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java | 22
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.properties | 12
opendj-sdk/opends/build.xml | 5
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ConstraintTest.java | 34
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestCfg.java | 155 ++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java | 6
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java | 19
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.properties | 9
opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java | 551 +++++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java | 58
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java | 377 +++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java | 4
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java | 20
opendj-sdk/opends/resource/admin/admin.xsd | 95 +
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ListenerTest.java | 7
opendj-sdk/opends/resource/admin/property-types/aggregation.xsl | 153 +++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AggregationPropertyDefinitionTest.java | 132 ++
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java | 50
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentConfiguration.xml | 6
31 files changed, 2,716 insertions(+), 214 deletions(-)
diff --git a/opendj-sdk/opends/build.xml b/opendj-sdk/opends/build.xml
index 7edae79..d3af905 100644
--- a/opendj-sdk/opends/build.xml
+++ b/opendj-sdk/opends/build.xml
@@ -1088,6 +1088,11 @@
<path refid="quickSetup.classpath" />
</classpath>
</javac>
+
+ <copy todir="${unittest.classes.dir}">
+ <fileset dir="${unittest.testng.src.dir}"
+ includes="**/*.properties" />
+ </copy>
<!-- Prep the TestNG XML file -->
diff --git a/opendj-sdk/opends/resource/admin/admin.xsd b/opendj-sdk/opends/resource/admin/admin.xsd
index b84659b..6dbbb93 100644
--- a/opendj-sdk/opends/resource/admin/admin.xsd
+++ b/opendj-sdk/opends/resource/admin/admin.xsd
@@ -61,9 +61,9 @@
type="tns:description-type">
<xsd:annotation>
<xsd:documentation>
- The user friendly plural name of this managed object. This element
- is optional and by default the user friendly plural name is derived
- from the definition's plural-name attribute.
+ The user friendly plural name of this managed object. This
+ element is optional and by default the user friendly plural
+ name is derived from the definition's plural-name attribute.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
@@ -678,17 +678,6 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
- <xsd:attribute name="aggregation" type="tns:path-type"
- use="optional">
- <xsd:annotation>
- <xsd:documentation>
- For aggregation relations, the path locating the relation
- beneath which the referenced (aggregated) managed objects can
- be found. If this attribute is not specified, the relation is
- a composition by default.
- </xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
<xsd:attribute name="managed-object-name" type="tns:name-type"
use="optional">
<xsd:annotation>
@@ -1032,6 +1021,84 @@
</xsd:documentation>
</xsd:annotation>
<xsd:choice>
+ <xsd:element name="aggregation">
+ <xsd:annotation>
+ <xsd:documentation>
+ An aggregation property names one or more managed objects
+ which are required by the managed object associated with
+ this property. An aggregation property definition takes care
+ to perform referential integrity checks: referenced managed
+ objects cannot be deleted. Nor can an aggregation reference
+ non-existent managed objects. Referential integrity checks
+ are not performed during value validation. Instead they are
+ performed when changes to the managed object are committed.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="parent-path" type="tns:path-type"
+ use="required">
+ <xsd:annotation>
+ <xsd:documentation>
+ The name of the managed object which is the parent of
+ the aggregated managed objects.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="relation-name" type="tns:name-type"
+ use="required">
+ <xsd:annotation>
+ <xsd:documentation>
+ The relation in the parent managed object which contains
+ the aggregated managed objects.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="managed-object-name" type="tns:name-type"
+ use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The type of managed object referenced by this
+ aggregation if different from this relation's name.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="managed-object-package"
+ type="tns:package-type" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The package containing the referenced managed object
+ definition if it is not the same as this managed
+ object's package.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="source-enabled-property-name"
+ type="tns:name-type" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The optional boolean "enabled" property in the
+ aggregating managed object. When this property is true,
+ the "target-enabled-property-name" in the aggregated
+ managed objects must also be true. The
+ "target-enabled-property-name" attribute must be
+ specified when this attribute is defined.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="target-enabled-property-name"
+ type="tns:name-type" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The optional boolean "enabled" property in the
+ aggregated managed objects. This property must not be
+ false while the aggregated managed object is referenced.
+ This attribute must be defined when the
+ "source-enabled-property-name" attribute is specified.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
<xsd:element name="attribute-type">
<xsd:annotation>
<xsd:documentation>
diff --git a/opendj-sdk/opends/resource/admin/property-types.xsl b/opendj-sdk/opends/resource/admin/property-types.xsl
index 69f94d0..760dc2e 100644
--- a/opendj-sdk/opends/resource/admin/property-types.xsl
+++ b/opendj-sdk/opends/resource/admin/property-types.xsl
@@ -39,6 +39,7 @@
-->
+ <xsl:include href="property-types/aggregation.xsl" />
<xsl:include href="property-types/attribute-type.xsl" />
<xsl:include href="property-types/boolean.xsl" />
<xsl:include href="property-types/dn.xsl" />
diff --git a/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl b/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl
new file mode 100644
index 0000000..158609c
--- /dev/null
+++ b/opendj-sdk/opends/resource/admin/property-types/aggregation.xsl
@@ -0,0 +1,153 @@
+<!--
+ ! CDDL HEADER START
+ !
+ ! The contents of this file are subject to the terms of the
+ ! Common Development and Distribution License, Version 1.0 only
+ ! (the "License"). You may not use this file except in compliance
+ ! with the License.
+ !
+ ! You can obtain a copy of the license at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ ! See the License for the specific language governing permissions
+ ! and limitations under the License.
+ !
+ ! When distributing Covered Code, include this CDDL HEADER in each
+ ! file and include the License file at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ ! add the following below this CDDL HEADER, with the fields enclosed
+ ! by brackets "[]" replaced with your own identifying information:
+ ! Portions Copyright [yyyy] [name of copyright owner]
+ !
+ ! CDDL HEADER END
+ !
+ !
+ ! Portions Copyright 2007 Sun Microsystems, Inc.
+ ! -->
+<xsl:stylesheet version="1.0" xmlns:adm="http://www.opends.org/admin"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ <!--
+ Templates for processing aggregation properties.
+ -->
+ <xsl:template match="adm:aggregation" mode="java-definition-imports">
+ <xsl:element name="import">
+ <xsl:call-template name="get-definition-package" />
+ <xsl:value-of select="'.client.'" />
+ <xsl:call-template name="get-client-type" />
+ </xsl:element>
+ <xsl:element name="import">
+ <xsl:call-template name="get-definition-package" />
+ <xsl:value-of select="'.server.'" />
+ <xsl:call-template name="get-server-type" />
+ </xsl:element>
+ <xsl:element name="import">
+ <xsl:call-template name="get-definition-package" />
+ <xsl:value-of select="'.meta.'" />
+ <xsl:call-template name="get-definition-type" />
+ </xsl:element>
+ <import>org.opends.server.admin.ManagedObjectPath</import>
+ </xsl:template>
+ <xsl:template match="adm:aggregation" mode="java-value-type">
+ <xsl:value-of select="'String'" />
+ </xsl:template>
+ <xsl:template match="adm:aggregation" mode="java-definition-type">
+ <xsl:value-of select="'AggregationPropertyDefinition'" />
+ </xsl:template>
+ <xsl:template match="adm:aggregation"
+ mode="java-definition-generic-type">
+ <xsl:call-template name="get-client-type" />
+ <xsl:value-of select="', '" />
+ <xsl:call-template name="get-server-type" />
+ </xsl:template>
+ <xsl:template match="adm:aggregation" mode="java-definition-ctor">
+ <xsl:if test="not(@parent-path)">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('No parent-path defined for aggregation property ', ../../@name)" />
+ </xsl:message>
+ </xsl:if>
+ <xsl:if test="not(@relation-name)">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('No relation-name defined for aggregation property ', ../../@name)" />
+ </xsl:message>
+ </xsl:if>
+ <xsl:if
+ test="@source-enabled-property-name and not(@target-enabled-property-name)">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('source-enabled-property-name defined but target-enabled-property-name undefined in aggregation property ', ../../@name)" />
+ </xsl:message>
+ </xsl:if>
+ <xsl:value-of
+ select="concat(' builder.setParentPath(ManagedObjectPath.valueOf("',
+ normalize-space(@parent-path), '"));
')" />
+ <xsl:value-of
+ select="concat(' builder.setRelationDefinition("',
+ normalize-space(@relation-name), '");
')" />
+ <xsl:value-of select="' builder.setManagedObjectDefinition('" />
+ <xsl:call-template name="get-definition-type" />
+ <xsl:value-of select="'.getInstance());
'" />
+ <xsl:if test="@source-enabled-property-name">
+ <xsl:value-of
+ select="concat(' builder.setSourceEnabledPropertyName("',
+ normalize-space(@source-enabled-property-name), '");
')" />
+ </xsl:if>
+ <xsl:if test="@target-enabled-property-name">
+ <xsl:value-of
+ select="concat(' builder.setTargetEnabledPropertyName("',
+ normalize-space(@target-enabled-property-name), '");
')" />
+ </xsl:if>
+ </xsl:template>
+ <!--
+ Gets the Java client configuration interface for the referenced type.
+ -->
+ <xsl:template name="get-client-type">
+ <xsl:call-template name="get-reference-type" />
+ <xsl:value-of select="'CfgClient'" />
+ </xsl:template>
+ <!--
+ Gets the Java server configuration interface for the referenced type.
+ -->
+ <xsl:template name="get-server-type">
+ <xsl:call-template name="get-reference-type" />
+ <xsl:value-of select="'Cfg'" />
+ </xsl:template>
+ <!--
+ Gets the Java definition configuration interface for the referenced type.
+ -->
+ <xsl:template name="get-definition-type">
+ <xsl:call-template name="get-reference-type" />
+ <xsl:value-of select="'CfgDefn'" />
+ </xsl:template>
+ <!--
+ Gets the Java definition configuration package.
+ -->
+ <xsl:template name="get-definition-package">
+ <xsl:choose>
+ <xsl:when test="@managed-object-package">
+ <xsl:value-of select="@managed-object-package" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$this-package" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ <!--
+ Gets the Java name for the referenced type.
+ -->
+ <xsl:template name="get-reference-type">
+ <xsl:choose>
+ <xsl:when test="@managed-object-name">
+ <xsl:call-template name="name-to-java">
+ <xsl:with-param name="value" select="@managed-object-name" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="name-to-java">
+ <xsl:with-param name="value" select="@relation-name" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
new file mode 100644
index 0000000..56bbccc
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
@@ -0,0 +1,551 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin;
+
+
+
+import static org.opends.server.util.Validator.*;
+
+import java.util.EnumSet;
+
+import org.opends.server.types.DN;
+
+
+
+/**
+ * Aggregation property definition.
+ * <p>
+ * An aggregation property names one or more managed objects which are
+ * required by the managed object associated with this property. An
+ * aggregation property definition takes care to perform referential
+ * integrity checks: referenced managed objects cannot be deleted. Nor
+ * can an aggregation reference non-existent managed objects.
+ * Referential integrity checks are <b>not</b> performed during value
+ * validation. Instead they are performed when changes to the managed
+ * object are committed.
+ * <p>
+ * An aggregation property definition can optionally identify two
+ * properties:
+ * <ul>
+ * <li>an <code>enabled</code> property in the aggregated managed
+ * object - the property must be a {@link BooleanPropertyDefinition}
+ * and indicate whether the aggregated managed object is enabled or
+ * not. If specified, the administration framework will prevent the
+ * aggregated managed object from being disabled while it is
+ * referenced
+ * <li>an <code>enabled</code> property in this property's managed
+ * object - the property must be a {@link BooleanPropertyDefinition}
+ * and indicate whether this property's managed object is enabled or
+ * not. If specified, and as long as there is an equivalent
+ * <code>enabled</code> property defined for the aggregated managed
+ * object, the <code>enabled</code> property in the aggregated
+ * managed object will only be checked when this property is true.
+ * </ul>
+ * In other words, these properties can be used to make sure that
+ * referenced managed objects are not disabled while they are
+ * referenced.
+ *
+ * @param <C>
+ * The type of client managed object configuration that this
+ * aggregation property definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that this
+ * aggregation property definition refers to.
+ */
+public final class AggregationPropertyDefinition
+ <C extends ConfigurationClient, S extends Configuration>
+ extends PropertyDefinition<String> {
+
+ /**
+ * An interface for incrementally constructing aggregation property
+ * definitions.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this aggregation property definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this aggregation property definition refers to.
+ */
+ public static class Builder
+ <C extends ConfigurationClient, S extends Configuration>
+ extends AbstractBuilder<String, AggregationPropertyDefinition<C, S>> {
+
+ // The name of the managed object which is the parent of the
+ // aggregated managed objects.
+ private ManagedObjectPath<?, ?> p = null;
+
+ // The name of a relation in the parent managed object which
+ // contains the aggregated managed objects.
+ private String rdName = null;
+
+ // The type of referenced managed objects.
+ private AbstractManagedObjectDefinition<?, ?> cd = null;
+
+ // The optional name of a boolean "enabled" property in this
+ // managed object. When this property is true, the enabled
+ // property in the aggregated managed object must also be true.
+ private String sourceEnabledPropertyName = null;
+
+ // The optional name of a boolean "enabled" property in the
+ // aggregated managed object. This property must not be false
+ // while the aggregated managed object is referenced.
+ private String targetEnabledPropertyName = null;
+
+
+
+ // Private constructor
+ private Builder(AbstractManagedObjectDefinition<?, ?> d,
+ String propertyName) {
+ super(d, propertyName);
+ }
+
+
+
+ /**
+ * Sets the name of the managed object which is the parent of the
+ * aggregated managed objects.
+ * <p>
+ * This must be defined before the property definition can be
+ * built.
+ *
+ * @param p
+ * The name of the managed object which is the parent of
+ * the aggregated managed objects.
+ */
+ public final void setParentPath(ManagedObjectPath<?, ?> p) {
+ this.p = p;
+ }
+
+
+
+ /**
+ * Sets the relation in the parent managed object which contains
+ * the aggregated managed objects.
+ * <p>
+ * This must be defined before the property definition can be
+ * built.
+ *
+ * @param rdName
+ * The name of a relation in the parent managed object
+ * which contains the aggregated managed objects.
+ */
+ public final void setRelationDefinition(String rdName) {
+ this.rdName = rdName;
+ }
+
+
+
+ /**
+ * Sets the definition of the type of referenced managed objects.
+ * <p>
+ * This must be defined before the property definition can be
+ * built.
+ *
+ * @param d
+ * The definition of the type of referenced managed
+ * objects.
+ */
+ public final void setManagedObjectDefinition(
+ AbstractManagedObjectDefinition<C, S> d) {
+ this.cd = d;
+ }
+
+
+
+ /**
+ * Sets the optional boolean "enabled" property in this managed
+ * object. When this property is true, the enabled property in the
+ * aggregated managed object must also be true.
+ * <p>
+ * By default no source property is defined. When it is defined,
+ * the target property must also be defined.
+ *
+ * @param sourceEnabledPropertyName
+ * The optional boolean "enabled" property in this
+ * managed object.
+ */
+ public final void setSourceEnabledPropertyName(
+ String sourceEnabledPropertyName) {
+ this.sourceEnabledPropertyName = sourceEnabledPropertyName;
+ }
+
+
+
+ /**
+ * Sets the optional boolean "enabled" property in the aggregated
+ * managed object. This property must not be false while the
+ * aggregated managed object is referenced.
+ * <p>
+ * By default no target property is defined. It must be defined,
+ * if the source property is defined.
+ *
+ * @param targetEnabledPropertyName
+ * The optional boolean "enabled" property in the
+ * aggregated managed object.
+ */
+ public final void setTargetEnabledPropertyName(
+ String targetEnabledPropertyName) {
+ this.targetEnabledPropertyName = targetEnabledPropertyName;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected AggregationPropertyDefinition<C, S> buildInstance(
+ AbstractManagedObjectDefinition<?, ?> d, String propertyName,
+ EnumSet<PropertyOption> options, AdministratorAction adminAction,
+ DefaultBehaviorProvider<String> defaultBehavior) {
+ // Make sure that the parent path has been defined.
+ if (p == null) {
+ throw new IllegalStateException("Parent path undefined");
+ }
+
+ // Make sure that the relation definition has been defined.
+ if (rdName == null) {
+ throw new IllegalStateException("Relation definition undefined");
+ }
+
+ // Make sure that the managed object definition has been
+ // defined.
+ if (cd == null) {
+ throw new IllegalStateException("Managed object definition undefined");
+ }
+
+ // Make sure that the relation definition is a member of the
+ // parent path's definition.
+ AbstractManagedObjectDefinition<?, ?> parent = p
+ .getManagedObjectDefinition();
+ RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName);
+
+ // Make sure the relation refers to the child type.
+ AbstractManagedObjectDefinition<?, ?> dTmp = rd.getChildDefinition();
+ if (dTmp != cd) {
+ throw new IllegalStateException("Relation definition \"" + rd.getName()
+ + "\" does not refer to definition " + d.getName());
+ }
+
+ // Force the relation to the correct type.
+ InstantiableRelationDefinition<C, S> relation =
+ (InstantiableRelationDefinition<C, S>) rd;
+
+ // Make sure that if a source property is specified then a
+ // target property is also specified.
+ if (sourceEnabledPropertyName != null
+ && targetEnabledPropertyName == null) {
+ throw new IllegalStateException(
+ "Source property defined but target property is undefined");
+ }
+
+ return new AggregationPropertyDefinition<C, S>(d, propertyName, options,
+ adminAction, defaultBehavior, p, relation, sourceEnabledPropertyName,
+ targetEnabledPropertyName);
+ }
+
+ }
+
+
+
+ /**
+ * Creates an aggregation property definition builder.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this aggregation property definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this aggregation property definition refers to.
+ * @param d
+ * The managed object definition associated with this
+ * property definition.
+ * @param propertyName
+ * The property name.
+ * @return Returns the new aggregation property definition builder.
+ */
+ public static <C extends ConfigurationClient, S extends Configuration>
+ Builder<C, S> createBuilder(
+ AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
+ return new Builder<C, S>(d, propertyName);
+ }
+
+ // The name of the managed object which is the parent of the
+ // aggregated managed objects.
+ private final ManagedObjectPath<?, ?> parentPath;
+
+ // The relation in the parent managed object which contains the
+ // aggregated managed objects.
+ private final InstantiableRelationDefinition<C, S> relationDefinition;
+
+ // The optional name of a boolean "enabled" property in this managed
+ // object. When this property is true, the enabled property in the
+ // aggregated managed object must also be true.
+ private final String sourceEnabledPropertyName;
+
+ // The optional name of a boolean "enabled" property in the
+ // aggregated managed object. This property must not be false while
+ // the aggregated managed object is referenced.
+ private final String targetEnabledPropertyName;
+
+
+
+ // Private constructor.
+ private AggregationPropertyDefinition(
+ AbstractManagedObjectDefinition<?, ?> d, String propertyName,
+ EnumSet<PropertyOption> options, AdministratorAction adminAction,
+ DefaultBehaviorProvider<String> defaultBehavior,
+ ManagedObjectPath<?, ?> parentPath,
+ InstantiableRelationDefinition<C, S> relationDefinition,
+ String sourceEnabledPropertyName, String targetEnabledPropertyName) {
+ super(d, String.class, propertyName, options, adminAction, defaultBehavior);
+
+ this.parentPath = parentPath;
+ this.relationDefinition = relationDefinition;
+ this.sourceEnabledPropertyName = sourceEnabledPropertyName;
+ this.targetEnabledPropertyName = targetEnabledPropertyName;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
+ return v.visitAggregation(this, p);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
+ return v.visitAggregation(this, value, p);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String decodeValue(String value)
+ throws IllegalPropertyValueStringException {
+ ensureNotNull(value);
+
+ try {
+ validateValue(value);
+ return value;
+ } catch (IllegalPropertyValueException e) {
+ throw new IllegalPropertyValueStringException(this, value);
+ }
+ }
+
+
+
+ /**
+ * Constructs a DN for a referenced managed object having the
+ * provided name. This method is implemented by first calling
+ * {@link #getChildPath(String)} and then invoking
+ * {@link ManagedObjectPath#toDN()} on the returned path.
+ *
+ * @param name
+ * The name of the child managed object.
+ * @return Returns a DN for a referenced managed object having the
+ * provided name.
+ */
+ public final DN getChildDN(String name) {
+ return getChildPath(name).toDN();
+ }
+
+
+
+ /**
+ * Constructs a managed object path for a referenced managed object
+ * having the provided name.
+ *
+ * @param name
+ * The name of the child managed object.
+ * @return Returns a managed object path for a referenced managed
+ * object having the provided name.
+ */
+ public final ManagedObjectPath<C, S> getChildPath(String name) {
+ return parentPath.child(relationDefinition, name);
+ }
+
+
+
+ /**
+ * Gets the name of the managed object which is the parent of the
+ * aggregated managed objects.
+ *
+ * @return Returns the name of the managed object which is the
+ * parent of the aggregated managed objects.
+ */
+ public final ManagedObjectPath<?, ?> getParentPath() {
+ return parentPath;
+ }
+
+
+
+ /**
+ * Gets the relation in the parent managed object which contains the
+ * aggregated managed objects.
+ *
+ * @return Returns the relation in the parent managed object which
+ * contains the aggregated managed objects.
+ */
+ public final InstantiableRelationDefinition<C, S> getRelationDefinition() {
+ return relationDefinition;
+ }
+
+
+
+ /**
+ * Gets the optional boolean "enabled" property in this managed
+ * object. When this property is true, the enabled property in the
+ * aggregated managed object must also be true.
+ *
+ * @return Returns the optional boolean "enabled" property in this
+ * managed object, or <code>null</code> if none is
+ * defined.
+ * @throws IllegalArgumentException
+ * If the named property does not exist in this property's
+ * associated managed object definition.
+ * @throws ClassCastException
+ * If the named property does exist but is not a
+ * {@link BooleanPropertyDefinition}.
+ */
+ public final BooleanPropertyDefinition getSourceEnabledPropertyDefinition()
+ throws IllegalArgumentException, ClassCastException {
+ if (sourceEnabledPropertyName == null) {
+ return null;
+ }
+
+ AbstractManagedObjectDefinition<?, ?> d = getManagedObjectDefinition();
+
+ PropertyDefinition<?> pd;
+ pd = d.getPropertyDefinition(sourceEnabledPropertyName);
+
+ return (BooleanPropertyDefinition) pd;
+ }
+
+
+
+ /**
+ * Gets the optional boolean "enabled" property in the aggregated
+ * managed object. This property must not be false while the
+ * aggregated managed object is referenced.
+ *
+ * @return Returns the optional boolean "enabled" property in the
+ * aggregated managed object, or <code>null</code> if none
+ * is defined.
+ * @throws IllegalArgumentException
+ * If the named property does not exist in the aggregated
+ * managed object's definition.
+ * @throws ClassCastException
+ * If the named property does exist but is not a
+ * {@link BooleanPropertyDefinition}.
+ */
+ public final BooleanPropertyDefinition getTargetEnabledPropertyDefinition()
+ throws IllegalArgumentException, ClassCastException {
+ if (targetEnabledPropertyName == null) {
+ return null;
+ }
+
+ AbstractManagedObjectDefinition<?, ?> d;
+ PropertyDefinition<?> pd;
+
+ d = relationDefinition.getChildDefinition();
+ pd = d.getPropertyDefinition(targetEnabledPropertyName);
+
+ return (BooleanPropertyDefinition) pd;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String normalizeValue(String value)
+ throws IllegalPropertyValueException {
+ try {
+ Reference<C, S> reference = Reference.parseName(parentPath,
+ relationDefinition, value);
+ return reference.getNormalizedName();
+ } catch (IllegalArgumentException e) {
+ throw new IllegalPropertyValueException(this, value);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void toString(StringBuilder builder) {
+ super.toString(builder);
+
+ builder.append(" parentPath=");
+ builder.append(parentPath);
+
+ builder.append(" relationDefinition=");
+ builder.append(relationDefinition.getName());
+
+ if (sourceEnabledPropertyName != null) {
+ builder.append(" sourceEnabledPropertyName=");
+ builder.append(sourceEnabledPropertyName);
+ }
+
+ if (targetEnabledPropertyName != null) {
+ builder.append(" targetEnabledPropertyName=");
+ builder.append(targetEnabledPropertyName);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void validateValue(String value) throws IllegalPropertyValueException {
+ try {
+ Reference.parseName(parentPath, relationDefinition, value);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalPropertyValueException(this, value);
+ }
+ }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java b/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
index 4615588..2280700 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
@@ -214,6 +214,91 @@
+ /**
+ * Forcefully removes any resource bundles associated with the
+ * provided definition and using the default locale.
+ * <p>
+ * This method is intended for internal testing only.
+ *
+ * @param d
+ * The managed object definition.
+ */
+ synchronized void removeResourceBundle(
+ AbstractManagedObjectDefinition<?, ?> d) {
+ removeResourceBundle(d, Locale.getDefault());
+ }
+
+
+
+ /**
+ * Forcefully removes any resource bundles associated with the
+ * provided definition and locale.
+ * <p>
+ * This method is intended for internal testing only.
+ *
+ * @param d
+ * The managed object definition.
+ * @param locale
+ * The locale.
+ */
+ synchronized void removeResourceBundle(
+ AbstractManagedObjectDefinition<?, ?> d, Locale locale) {
+ // Get the locale resource mapping.
+ Map<Locale, ResourceBundle> map = resources.get(d);
+ if (map != null) {
+ map.remove(locale);
+ }
+ }
+
+
+
+ /**
+ * Forcefully adds the provided resource bundle to this I18N
+ * resource for the default locale.
+ * <p>
+ * This method is intended for internal testing only.
+ *
+ * @param d
+ * The managed object definition.
+ * @param resoureBundle
+ * The resource bundle to be used.
+ */
+ synchronized void setResourceBundle(AbstractManagedObjectDefinition<?, ?> d,
+ ResourceBundle resoureBundle) {
+ setResourceBundle(d, Locale.getDefault(), resoureBundle);
+ }
+
+
+
+ /**
+ * Forcefully adds the provided resource bundle to this I18N
+ * resource.
+ * <p>
+ * This method is intended for internal testing only.
+ *
+ * @param d
+ * The managed object definition.
+ * @param locale
+ * The locale.
+ * @param resoureBundle
+ * The resource bundle to be used.
+ */
+ synchronized void setResourceBundle(AbstractManagedObjectDefinition<?, ?> d,
+ Locale locale, ResourceBundle resoureBundle) {
+ // First get the locale-resource mapping, creating it if
+ // necessary.
+ Map<Locale, ResourceBundle> map = resources.get(d);
+ if (map == null) {
+ map = new HashMap<Locale, ResourceBundle>();
+ resources.put(d, map);
+ }
+
+ // Add the resource bundle.
+ map.put(locale, resoureBundle);
+ }
+
+
+
// Retrieve the resource bundle associated with a managed object and
// locale, lazily loading it if necessary.
private synchronized ResourceBundle getResourceBundle(
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
index 466f5a3..e1292bf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
@@ -72,6 +72,17 @@
* {@inheritDoc}
*/
@Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ Message visitAggregation(AggregationPropertyDefinition<C, S> d, Void p) {
+ return Message.raw("NAME");
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public Message visitAttributeType(AttributeTypePropertyDefinition d,
Void p) {
return Message.raw("OID");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
index 63e7c0b..34cdd89 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
@@ -65,6 +65,28 @@
/**
+ * Visit an aggregation property definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this aggregation property definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this aggregation property definition refers to.
+ * @param d
+ * The aggregation property definition to visit.
+ * @param p
+ * A visitor specified parameter.
+ * @return Returns a visitor specified result.
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ R visitAggregation(AggregationPropertyDefinition<C, S> d, P p) {
+ return visitUnknown(d, p);
+ }
+
+
+
+ /**
* Visit an attribute type property definition.
*
* @param d
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyValueVisitor.java b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyValueVisitor.java
index 43038e8..27d5584 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyValueVisitor.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyValueVisitor.java
@@ -73,6 +73,31 @@
/**
+ * Visit an aggregation property value.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this aggregation property definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this aggregation property definition refers to.
+ * @param d
+ * The aggregation property definition to visit.
+ * @param v
+ * The property value to visit.
+ * @param p
+ * A visitor specified parameter.
+ * @return Returns a visitor specified result.
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ R visitAggregation(
+ AggregationPropertyDefinition<C, S> d, String v, P p) {
+ return visitUnknown(d, v, p);
+ }
+
+
+
+ /**
* Visit an attribute type.
*
* @param d
@@ -172,8 +197,8 @@
* A visitor specified parameter.
* @return Returns a visitor specified result.
*/
- public <E extends Enum<E>> R visitEnum(
- EnumPropertyDefinition<E> d, E v, P p) {
+ public <E extends Enum<E>>
+ R visitEnum(EnumPropertyDefinition<E> d, E v, P p) {
return visitUnknown(d, v, p);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/Reference.java b/opendj-sdk/opends/src/server/org/opends/server/admin/Reference.java
new file mode 100644
index 0000000..3792a26
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/Reference.java
@@ -0,0 +1,245 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin;
+
+
+
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.RDN;
+import org.opends.server.util.StaticUtils;
+
+
+
+/**
+ * A reference to another managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that this
+ * reference refers to.
+ * @param <S>
+ * The type of server managed object configuration that this
+ * reference refers to.
+ */
+public final class Reference<C extends ConfigurationClient,
+ S extends Configuration> {
+
+ /**
+ * Parses a DN string value as a reference using the provided
+ * managed object path and relation definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this reference refers to.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this reference refers to.
+ * @param p
+ * The path of the referenced managed object's parent.
+ * @param rd
+ * The instantiable relation in the parent which contains
+ * the referenced managed object.
+ * @param s
+ * The DN string value.
+ * @return Returns the new reference based on the provided DN string
+ * value.
+ * @throws IllegalArgumentException
+ * If the DN string value could not be decoded as a DN or
+ * if the provided DN did not correspond to the provided
+ * path and relation.
+ */
+ public static <C extends ConfigurationClient, S extends Configuration>
+ Reference<C, S> parseDN(
+ ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd,
+ String s) throws IllegalArgumentException {
+ AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition();
+ RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
+ if (tmp != rd) {
+ throw new IllegalArgumentException("The relation \"" + rd.getName()
+ + "\" is not associated with the definition \"" + d.getName() + "\"");
+ }
+
+ DN dn;
+ try {
+ dn = DN.decode(s);
+ } catch (DirectoryException e) {
+ throw new IllegalArgumentException("Unabled to decode the DN string: \""
+ + s + "\"");
+ }
+
+ RDN rdn = dn.getRDN();
+ if (rdn == null) {
+ throw new IllegalArgumentException("Unabled to decode the DN string: \""
+ + s + "\"");
+ }
+
+ AttributeValue av = rdn.getAttributeValue(0);
+ if (av == null) {
+ throw new IllegalArgumentException("Unabled to decode the DN string: \""
+ + s + "\"");
+ }
+
+ String name = av.getStringValue();
+
+ // Check that the DN was valid.
+ DN expected = p.child(rd, name).toDN();
+ if (!dn.equals(expected)) {
+ throw new IllegalArgumentException("Unabled to decode the DN string: \""
+ + s + "\"");
+ }
+
+ return new Reference<C, S>(p, rd, name);
+ }
+
+
+
+ /**
+ * Parses a name as a reference using the provided managed object
+ * path and relation definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that
+ * this reference refers to.
+ * @param <S>
+ * The type of server managed object configuration that
+ * this reference refers to.
+ * @param p
+ * The path of the referenced managed object's parent.
+ * @param rd
+ * The instantiable relation in the parent which contains
+ * the referenced managed object.
+ * @param s
+ * The name of the referenced managed object.
+ * @return Returns the new reference based on the provided name.
+ * @throws IllegalArgumentException
+ * If the relation is not associated with the provided
+ * parent's definition, or if the provided name is empty.
+ */
+ public static <C extends ConfigurationClient, S extends Configuration>
+ Reference<C, S> parseName(
+ ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd,
+ String s) throws IllegalArgumentException {
+ // Sanity checks.
+ AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition();
+ RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
+ if (tmp != rd) {
+ throw new IllegalArgumentException("The relation \"" + rd.getName()
+ + "\" is not associated with the definition \"" + d.getName() + "\"");
+ }
+
+ if (s.trim().length() == 0) {
+ throw new IllegalArgumentException("Empty names are not allowed");
+ }
+
+ return new Reference<C, S>(p, rd, s);
+ }
+
+ // The name of the referenced managed object.
+ private final String name;
+
+ // The path of the referenced managed object.
+ private final ManagedObjectPath<C, S> path;
+
+ // The instantiable relation in the parent which contains the
+ // referenced managed object.
+ private final InstantiableRelationDefinition<C, S> relation;
+
+
+
+ // Private constructor.
+ private Reference(ManagedObjectPath<?, ?> parent,
+ InstantiableRelationDefinition<C, S> relation, String name)
+ throws IllegalArgumentException {
+ this.relation = relation;
+ this.name = name;
+ this.path = parent.child(relation, name);
+ }
+
+
+
+ /**
+ * Gets the name of the referenced managed object.
+ *
+ * @return Returns the name of the referenced managed object.
+ */
+ public String getName() {
+ return name;
+ }
+
+
+
+ /**
+ * Gets the normalized name of the referenced managed object.
+ *
+ * @return Returns the normalized name of the referenced managed
+ * object.
+ */
+ public String getNormalizedName() {
+ PropertyDefinition<?> pd = relation.getNamingPropertyDefinition();
+ return normalizeName(pd);
+ }
+
+
+
+ /**
+ * Gets the DN of the referenced managed object.
+ *
+ * @return Returns the DN of the referenced managed object.
+ */
+ public DN toDN() {
+ return path.toDN();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return name;
+ }
+
+
+
+ // Normalize a value using the specified naming property definition
+ // if defined.
+ private <T> String normalizeName(PropertyDefinition<T> pd) {
+ if (pd != null) {
+ try {
+ T tvalue = pd.decodeValue(name);
+ return pd.normalizeValue(tvalue);
+ } catch (IllegalPropertyValueStringException e) {
+ // Fall through to default normalization.
+ }
+ }
+
+ // FIXME: should really use directory string normalizer.
+ String s = name.trim().replaceAll(" +", " ");
+ return StaticUtils.toLowerCase(s);
+ }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
index eaa99ab..668d495 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -49,6 +49,7 @@
import org.opends.messages.Message;
import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.DefaultBehaviorException;
@@ -61,11 +62,14 @@
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.PropertyDefinitionVisitor;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.PropertyIsMandatoryException;
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
@@ -84,6 +88,73 @@
*/
final class LDAPDriver extends Driver {
+ /**
+ * A visitor which is used to decode property LDAP values.
+ */
+ private static final class ValueDecoder extends
+ PropertyDefinitionVisitor<Object, String> {
+
+ /**
+ * Decodes the provided property LDAP value.
+ *
+ * @param <PD>
+ * The type of the property.
+ * @param pd
+ * The property definition.
+ * @param value
+ * The LDAP string representation.
+ * @return Returns the decoded LDAP value.
+ * @throws IllegalPropertyValueStringException
+ * If the property value could not be decoded because it
+ * was invalid.
+ */
+ public static <PD> PD decode(PropertyDefinition<PD> pd, Object value)
+ throws IllegalPropertyValueStringException {
+ String s = String.valueOf(value);
+ return pd.castValue(pd.accept(new ValueDecoder(), s));
+ }
+
+
+
+ // Prevent instantiation.
+ private ValueDecoder() {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ Object visitAggregation(AggregationPropertyDefinition<C, S> d, String p) {
+ // Aggregations values are stored as full DNs in LDAP, but
+ // just their common name is exposed in the admin framework.
+ try {
+ Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d
+ .getRelationDefinition(), p);
+ return reference.getName();
+ } catch (IllegalArgumentException e) {
+ throw new IllegalPropertyValueStringException(d, p);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> Object visitUnknown(PropertyDefinition<T> d, String p)
+ throws UnknownPropertyDefinitionException {
+ // By default the property definition's decoder will do.
+ return d.decodeValue(p);
+ }
+ }
+
+
+
// The LDAP connection.
private final LDAPConnection connection;
@@ -151,20 +222,8 @@
for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
String attrID = profile.getAttributeName(mod, pd);
Attribute attribute = attributes.get(attrID);
- List<String> values = new LinkedList<String>();
-
- if (attribute != null && attribute.size() != 0) {
- NamingEnumeration<?> ldapValues = attribute.getAll();
- while (ldapValues.hasMore()) {
- Object obj = ldapValues.next();
- if (obj != null) {
- values.add(obj.toString());
- }
- }
- }
-
try {
- decodeProperty(newProperties, path, pd, values);
+ decodeProperty(newProperties, path, pd, attribute);
} catch (PropertyException e) {
exceptions.add(e);
}
@@ -193,12 +252,23 @@
/**
* {@inheritDoc}
*/
+ @SuppressWarnings("unchecked")
@Override
- public <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path,
+ public <C extends ConfigurationClient, S extends Configuration, PD>
+ SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path,
PropertyDefinition<PD> pd) throws IllegalArgumentException,
DefinitionDecodingException, AuthorizationException,
ManagedObjectNotFoundException, CommunicationException,
PropertyException {
+ // Check that the requested property is from the definition
+ // associated with the path.
+ AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
+ PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
+ if (tmp != pd) {
+ throw new IllegalArgumentException("The property " + pd.getName()
+ + " is not associated with a " + d.getName());
+ }
+
if (!managedObjectExists(path)) {
throw new ManagedObjectNotFoundException();
}
@@ -206,26 +276,27 @@
try {
// Read the entry associated with the managed object.
LdapName dn = LDAPNameBuilder.create(path, profile);
- AbstractManagedObjectDefinition<?, ?> d = path
- .getManagedObjectDefinition();
- ManagedObjectDefinition<?, ?> mod = getEntryDefinition(d, dn);
+ ManagedObjectDefinition<? extends C, ? extends S> mod;
+ mod = getEntryDefinition(d, dn);
+
+ // Make sure we use the correct property definition, the
+ // provided one might have been overridden in the resolved
+ // definition.
+ pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
String attrID = profile.getAttributeName(mod, pd);
Attributes attributes = connection.readEntry(dn, Collections
.singleton(attrID));
Attribute attribute = attributes.get(attrID);
+ // Decode the values.
SortedSet<PD> values = new TreeSet<PD>(pd);
- if (attribute == null || attribute.size() == 0) {
- // Use the property's default values.
- values.addAll(findDefaultValues(path, pd, false));
- } else {
- // Decode the values.
+ if (attribute != null) {
NamingEnumeration<?> ldapValues = attribute.getAll();
while (ldapValues.hasMore()) {
Object obj = ldapValues.next();
if (obj != null) {
- PD value = pd.decodeValue(obj.toString());
+ PD value = ValueDecoder.decode(pd, obj);
values.add(value);
}
}
@@ -240,6 +311,11 @@
throw new PropertyIsMandatoryException(pd);
}
+ if (values.isEmpty()) {
+ // Use the property's default values.
+ values.addAll(findDefaultValues(path.asSubType(mod), pd, false));
+ }
+
return values;
} catch (NameNotFoundException e) {
throw new ManagedObjectNotFoundException();
@@ -471,24 +547,28 @@
// Create a property using the provided string values.
private <PD> void decodeProperty(PropertySet newProperties,
- ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, List<String> values)
- throws PropertyException {
+ ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd,
+ Attribute attribute) throws PropertyException,
+ NamingException {
PropertyException exception = null;
// Get the property's active values.
- Collection<PD> activeValues = new ArrayList<PD>(values.size());
- for (String value : values) {
- try {
- activeValues.add(pd.decodeValue(value));
- } catch (IllegalPropertyValueStringException e) {
- exception = e;
+ SortedSet<PD> activeValues = new TreeSet<PD>(pd);
+ if (attribute != null) {
+ NamingEnumeration<?> ldapValues = attribute.getAll();
+ while (ldapValues.hasMore()) {
+ Object obj = ldapValues.next();
+ if (obj != null) {
+ PD value = ValueDecoder.decode(pd, obj);
+ activeValues.add(value);
+ }
}
}
if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
// This exception takes precedence over previous exceptions.
exception = new PropertyIsSingleValuedException(pd);
- PD value = activeValues.iterator().next();
+ PD value = activeValues.first();
activeValues.clear();
activeValues.add(value);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
index 7b60e04..ec2f65e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -41,6 +41,7 @@
import javax.naming.ldap.Rdn;
import org.opends.messages.Message;
+import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.InstantiableRelationDefinition;
@@ -50,7 +51,10 @@
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.PropertyValueVisitor;
+import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
@@ -73,6 +77,47 @@
final class LDAPManagedObject<T extends ConfigurationClient> extends
AbstractManagedObject<T> {
+ /**
+ * A visitor which is used to encode property LDAP values.
+ */
+ private static final class ValueEncoder extends
+ PropertyValueVisitor<Object, Void> {
+
+ // Prevent instantiation.
+ private ValueEncoder() {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ Object visitAggregation(
+ AggregationPropertyDefinition<C, S> d, String v, Void p) {
+ // Aggregations values are stored as full DNs in LDAP, but
+ // just their common name is exposed in the admin framework.
+ Reference<C, S> reference = Reference.parseName(d.getParentPath(), d
+ .getRelationDefinition(), v);
+ return reference.toDN().toString();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <PD> Object visitUnknown(PropertyDefinition<PD> d, PD v, Void p)
+ throws UnknownPropertyDefinitionException {
+ return d.encodeValue(v);
+ }
+ }
+
+
+
// The LDAP management driver associated with this managed object.
private final LDAPDriver driver;
@@ -294,17 +339,18 @@
// Encode a property into LDAP string values.
private <PD> void encodeProperty(Attribute attribute,
PropertyDefinition<PD> pd) {
+ PropertyValueVisitor<Object, Void> visitor = new ValueEncoder();
Property<PD> p = getProperty(pd);
if (pd.hasOption(PropertyOption.MANDATORY)) {
// For mandatory properties we fall-back to the default values
// if defined which can sometimes be the case e.g when a
// mandatory property is overridden.
for (PD value : p.getEffectiveValues()) {
- attribute.add(pd.encodeValue(value));
+ attribute.add(pd.accept(visitor, value, null));
}
} else {
for (PD value : p.getPendingValues()) {
- attribute.add(pd.encodeValue(value));
+ attribute.add(pd.accept(visitor, value, null));
}
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java
index c39601d..e7b0a19 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java
@@ -430,6 +430,12 @@
* Gets the effective value of a property in the named managed
* object.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * path definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * path definition refers to.
* @param <PD>
* The type of the property to be retrieved.
* @param path
@@ -458,7 +464,8 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- public final <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path,
+ public final <C extends ConfigurationClient, S extends Configuration, PD>
+ PD getPropertyValue(ManagedObjectPath<C, S> path,
PropertyDefinition<PD> pd) throws IllegalArgumentException,
DefinitionDecodingException, AuthorizationException,
ManagedObjectNotFoundException, CommunicationException,
@@ -486,6 +493,12 @@
* managed object contains a property which inherits default values
* from another property in the same managed object.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * path definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * path definition refers to.
* @param <PD>
* The type of the property to be retrieved.
* @param path
@@ -514,8 +527,9 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- public abstract <PD> SortedSet<PD> getPropertyValues(
- ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd)
+ public abstract <C extends ConfigurationClient, S extends Configuration, PD>
+ SortedSet<PD> getPropertyValues(
+ ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd)
throws IllegalArgumentException, DefinitionDecodingException,
AuthorizationException, ManagedObjectNotFoundException,
CommunicationException, PropertyException;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java b/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
index ea2f943..a8d3391 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagementContext.java
@@ -47,6 +47,7 @@
import org.opends.messages.Message;
import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.AliasDefaultBehaviorProvider;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
@@ -62,14 +63,17 @@
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.PropertyDefinitionVisitor;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.PropertyIsMandatoryException;
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.PropertyNotFoundException;
import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
+import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.admin.std.server.RootCfg;
@@ -263,22 +267,22 @@
throw new PropertyNotFoundException(propertyName);
}
- List<String> stringValues = getAttribute(mod, pd2, configEntry);
- if (stringValues.isEmpty()) {
+ List<AttributeValue> values = getAttribute(mod, pd2, configEntry);
+ if (values.isEmpty()) {
// Recursively retrieve this property's default values.
Collection<T> tmp = find(target, pd2);
- Collection<T> values = new ArrayList<T>(tmp.size());
+ Collection<T> pvalues = new ArrayList<T>(tmp.size());
for (T value : tmp) {
pd1.validateValue(value);
- values.add(value);
+ pvalues.add(value);
}
- return values;
+ return pvalues;
} else {
- Collection<T> values = new ArrayList<T>(stringValues.size());
- for (String s : stringValues) {
- values.add(pd1.decodeValue(s));
+ Collection<T> pvalues = new ArrayList<T>(values.size());
+ for (AttributeValue value : values) {
+ pvalues.add(ValueDecoder.decode(pd1, value));
}
- return values;
+ return pvalues;
}
} catch (DefinitionDecodingException e) {
throw new DefaultBehaviorException(pd1, e);
@@ -321,7 +325,76 @@
String oc = LDAPProfile.getInstance().getObjectClass(d);
return entry.hasObjectClass(oc);
}
- };
+ }
+
+
+
+ /**
+ * A visitor which is used to decode property LDAP values.
+ */
+ private static final class ValueDecoder extends
+ PropertyDefinitionVisitor<Object, String> {
+
+ /**
+ * Decodes the provided property LDAP value.
+ *
+ * @param <PD>
+ * The type of the property.
+ * @param pd
+ * The property definition.
+ * @param value
+ * The LDAP string representation.
+ * @return Returns the decoded LDAP value.
+ * @throws IllegalPropertyValueStringException
+ * If the property value could not be decoded because it
+ * was invalid.
+ */
+ public static <PD> PD decode(PropertyDefinition<PD> pd,
+ AttributeValue value) throws IllegalPropertyValueStringException {
+ String s = value.getStringValue();
+ return pd.castValue(pd.accept(new ValueDecoder(), s));
+ }
+
+
+
+ // Prevent instantiation.
+ private ValueDecoder() {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ Object visitAggregation(AggregationPropertyDefinition<C, S> d, String p) {
+ // Aggregations values are stored as full DNs in LDAP, but
+ // just their common name is exposed in the admin framework.
+ try {
+ Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d
+ .getRelationDefinition(), p);
+ return reference.getName();
+ } catch (IllegalArgumentException e) {
+ throw new IllegalPropertyValueStringException(d, p);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> Object visitUnknown(PropertyDefinition<T> d, String p)
+ throws UnknownPropertyDefinitionException {
+ // By default the property definition's decoder will do.
+ return d.decodeValue(p);
+ }
+ }
+
+
// Singleton instance.
private final static ServerManagementContext INSTANCE =
@@ -399,6 +472,12 @@
* Gets the effective value of a property in the named managed
* object.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * path definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * path definition refers to.
* @param <PD>
* The type of the property to be retrieved.
* @param path
@@ -417,7 +496,8 @@
* If the named managed object could not be found or if it
* could not be decoded.
*/
- public <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path,
+ public <C extends ConfigurationClient, S extends Configuration, PD>
+ PD getPropertyValue(ManagedObjectPath<C, S> path,
PropertyDefinition<PD> pd) throws IllegalArgumentException,
ConfigException, PropertyException {
SortedSet<PD> values = getPropertyValues(path, pd);
@@ -434,6 +514,12 @@
* Gets the effective values of a property in the named managed
* object.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * path definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * path definition refers to.
* @param <PD>
* The type of the property to be retrieved.
* @param path
@@ -452,15 +538,27 @@
* If the named managed object could not be found or if it
* could not be decoded.
*/
- public <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path,
+ @SuppressWarnings("unchecked")
+ public <C extends ConfigurationClient, S extends Configuration, PD>
+ SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path,
PropertyDefinition<PD> pd) throws IllegalArgumentException,
ConfigException, PropertyException {
+ // Check that the requested property is from the definition
+ // associated with the path.
+ AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
+ PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
+ if (tmp != pd) {
+ throw new IllegalArgumentException("The property " + pd.getName()
+ + " is not associated with a " + d.getName());
+ }
+
+ // Determine the exact type of managed object referenced by the
+ // path.
DN dn = DNBuilder.create(path);
ConfigEntry configEntry = getManagedObjectConfigEntry(dn);
DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
- AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
- ManagedObjectDefinition<?, ?> mod;
+ ManagedObjectDefinition<? extends C, ? extends S> mod;
try {
mod = d.resolveManagedObjectDefinition(resolver);
@@ -469,8 +567,13 @@
.createDecodingExceptionAdaptor(dn, e);
}
- List<String> values = getAttribute(mod, pd, configEntry);
- return decodeProperty(path, pd, values, null);
+ // Make sure we use the correct property definition, the
+ // provided one might have been overridden in the resolved
+ // definition.
+ pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
+
+ List<AttributeValue> values = getAttribute(mod, pd, configEntry);
+ return decodeProperty(path.asSubType(mod), pd, values, null);
}
@@ -649,7 +752,7 @@
Map<PropertyDefinition<?>, SortedSet<?>> properties =
new HashMap<PropertyDefinition<?>, SortedSet<?>>();
for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
- List<String> values = getAttribute(mod, pd, configEntry);
+ List<AttributeValue> values = getAttribute(mod, pd, configEntry);
try {
SortedSet<?> pvalues = decodeProperty(path, pd, values, newConfigEntry);
properties.put(pd, pvalues);
@@ -686,16 +789,16 @@
// Create a property using the provided string values.
private <T> SortedSet<T> decodeProperty(ManagedObjectPath<?, ?> path,
- PropertyDefinition<T> pd, List<String> stringValues,
+ PropertyDefinition<T> pd, List<AttributeValue> values,
ConfigEntry newConfigEntry) throws PropertyException {
PropertyException exception = null;
- SortedSet<T> values = new TreeSet<T>(pd);
+ SortedSet<T> pvalues = new TreeSet<T>(pd);
- if (!stringValues.isEmpty()) {
+ if (!values.isEmpty()) {
// The property has values defined for it.
- for (String value : stringValues) {
+ for (AttributeValue value : values) {
try {
- values.add(pd.decodeValue(value));
+ pvalues.add(ValueDecoder.decode(pd, value));
} catch (IllegalPropertyValueStringException e) {
exception = e;
}
@@ -703,21 +806,21 @@
} else {
// No values defined so get the defaults.
try {
- values.addAll(getDefaultValues(path, pd, newConfigEntry));
+ pvalues.addAll(getDefaultValues(path, pd, newConfigEntry));
} catch (DefaultBehaviorException e) {
exception = e;
}
}
- if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+ if (pvalues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
// This exception takes precedence over previous exceptions.
exception = new PropertyIsSingleValuedException(pd);
- T value = values.first();
- values.clear();
- values.add(value);
+ T value = pvalues.first();
+ pvalues.clear();
+ pvalues.add(value);
}
- if (values.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
+ if (pvalues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
// The values maybe empty because of a previous exception.
if (exception == null) {
exception = new PropertyIsMandatoryException(pd);
@@ -727,29 +830,30 @@
if (exception != null) {
throw exception;
} else {
- return values;
+ return pvalues;
}
}
// Gets the attribute associated with a property from a ConfigEntry.
- private List<String> getAttribute(ManagedObjectDefinition<?, ?> d,
+ private List<AttributeValue> getAttribute(ManagedObjectDefinition<?, ?> d,
PropertyDefinition<?> pd, ConfigEntry configEntry) {
// TODO: we create a default attribute type if it is
// undefined. We should log a warning here if this is the case
// since the attribute should have been defined.
String attrID = LDAPProfile.getInstance().getAttributeName(d, pd);
AttributeType type = DirectoryServer.getAttributeType(attrID, true);
- AttributeValueDecoder<String> decoder =
- new AttributeValueDecoder<String>() {
+ AttributeValueDecoder<AttributeValue> decoder =
+ new AttributeValueDecoder<AttributeValue>() {
- public String decode(AttributeValue value) throws DirectoryException {
- return value.getStringValue();
+ public AttributeValue decode(AttributeValue value)
+ throws DirectoryException {
+ return value;
}
};
- List<String> values = new LinkedList<String>();
+ List<AttributeValue> values = new LinkedList<AttributeValue>();
try {
configEntry.getEntry().getAttributeValues(type, decoder, values);
} catch (DirectoryException e) {
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AggregationPropertyDefinitionTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AggregationPropertyDefinitionTest.java
new file mode 100644
index 0000000..48dadf9
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AggregationPropertyDefinitionTest.java
@@ -0,0 +1,132 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin;
+
+
+
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.types.DN;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * AggregationPropertyDefinition Tester.
+ */
+@Test(sequential = true)
+public class AggregationPropertyDefinitionTest extends DirectoryServerTestCase {
+
+ /**
+ * Sets up tests
+ *
+ * @throws Exception
+ * If the server could not be initialized.
+ */
+ @BeforeClass
+ public void setUp() throws Exception {
+ // This test suite depends on having the schema available, so
+ // we'll start the server.
+ TestCaseUtils.startServer();
+ TestCfg.setUp();
+ }
+
+
+
+ /**
+ * Tears down test environment.
+ */
+ @AfterClass
+ public void tearDown() {
+ TestCfg.cleanup();
+ }
+
+
+
+ /**
+ * Tests that the
+ * {@link AggregationPropertyDefinition#normalizeValue(String)}
+ * works.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testNormalizeValue() throws Exception {
+ TestChildCfgDefn d = TestChildCfgDefn.getInstance();
+ AggregationPropertyDefinition<?, ?> pd = d
+ .getAggregationPropertyPropertyDefinition();
+ String nvalue = pd.normalizeValue(" LDAP connection handler ");
+ Assert.assertEquals(nvalue, "ldap connection handler");
+ }
+
+
+
+ /**
+ * Tests that the
+ * {@link AggregationPropertyDefinition#getChildDN(String)} works.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testGetChildDN() throws Exception {
+ TestChildCfgDefn d = TestChildCfgDefn.getInstance();
+ AggregationPropertyDefinition<?, ?> pd = d
+ .getAggregationPropertyPropertyDefinition();
+ DN expected = DN
+ .decode("cn=ldap connection handler, cn=connection handlers, cn=config");
+ DN actual = pd.getChildDN(" LDAP connection handler ");
+ Assert.assertEquals(actual, expected);
+ }
+
+
+
+ /**
+ * Tests that the
+ * {@link AggregationPropertyDefinition#getChildPath(String)} works.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testGetChildPath() throws Exception {
+ TestChildCfgDefn d = TestChildCfgDefn.getInstance();
+ AggregationPropertyDefinition<?, ?> pd = d
+ .getAggregationPropertyPropertyDefinition();
+ ManagedObjectPath<?, ?> path = pd.getChildPath("LDAP connection handler");
+
+ Assert.assertSame(path.getManagedObjectDefinition(), pd
+ .getRelationDefinition().getChildDefinition());
+ Assert.assertSame(path.getRelationDefinition(), pd.getRelationDefinition());
+ }
+
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
index 399c4df..8effbd0 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
@@ -81,6 +81,8 @@
return "ds-cfg-virtual-attribute-base-dn";
} else if (pd == (PropertyDefinition<?>)td.getOptionalMultiValuedDNProperty2PropertyDefinition()) {
return "ds-cfg-virtual-attribute-group-dn";
+ } else if (pd == (PropertyDefinition<?>)td.getAggregationPropertyPropertyDefinition()) {
+ return "ds-cfg-backend-base-dn";
} else {
throw new RuntimeException("Unexpected test-child property"
+ pd.getName());
@@ -117,9 +119,9 @@
public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) {
// These casts throughout are required to work around a bug in JDK versions prior to 1.5.0_08.
if (d == (AbstractManagedObjectDefinition<?, ?>)TestParentCfgDefn.getInstance()) {
- return "ds-cfg-virtual-attribute";
+ return "ds-cfg-test-parent-dummy";
} else if (d == (AbstractManagedObjectDefinition<?, ?>)TestChildCfgDefn.getInstance()) {
- return "ds-cfg-virtual-attribute";
+ return "ds-cfg-test-child-dummy";
} else {
// Not known.
return null;
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestCfg.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestCfg.java
index 3745d18..53e2e37 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestCfg.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestCfg.java
@@ -28,7 +28,14 @@
+import java.util.ResourceBundle;
+
import org.opends.server.admin.std.meta.RootCfgDefn;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.schema.ObjectClassSyntax;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.ByteStringFactory;
+import org.opends.server.types.ObjectClass;
@@ -51,8 +58,7 @@
// Create a one-to-many relation for test-parent components.
static {
- InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder =
- new InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>(
+ InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder = new InstantiableRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>(
RootCfgDefn.getInstance(), "test-one-to-many-parent",
"test-one-to-many-parents", TestParentCfgDefn.getInstance());
RD_TEST_ONE_TO_MANY_PARENT = builder.getInstance();
@@ -60,13 +66,94 @@
// Create a one-to-many relation for test-parent components.
static {
- OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder =
- new OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>(
+ OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg> builder = new OptionalRelationDefinition.Builder<TestParentCfgClient, TestParentCfg>(
RootCfgDefn.getInstance(), "test-one-to-zero-or-one-parent",
TestParentCfgDefn.getInstance());
RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT = builder.getInstance();
}
+ // Test parent object class definition.
+ private static ObjectClass TEST_PARENT_OCD = null;
+
+ // Test child object class definition.
+ private static ObjectClass TEST_CHILD_OCD = null;
+
+
+
+ /**
+ * Registers test parent and child object class definitions and any
+ * required resource bundles.
+ * <p>
+ * Unit tests which call this method <b>must</b> call
+ * {@link #cleanup()} on completion.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ public synchronized static void setUp() throws Exception {
+ if (TEST_PARENT_OCD == null) {
+ String ocd = "( 1.3.6.1.4.1.26027.1.2.4455114401 "
+ + "NAME 'ds-cfg-test-parent-dummy' "
+ + "SUP top STRUCTURAL "
+ + "MUST ( cn $ ds-cfg-virtual-attribute-class $ "
+ + "ds-cfg-virtual-attribute-enabled $ ds-cfg-virtual-attribute-type ) "
+ + "MAY ( ds-cfg-virtual-attribute-base-dn $ ds-cfg-virtual-attribute-group-dn $ "
+ + "ds-cfg-virtual-attribute-filter $ ds-cfg-virtual-attribute-conflict-behavior ) "
+ + "X-ORIGIN 'OpenDS Directory Server' )";
+ ByteString b = ByteStringFactory.create(ocd);
+
+ TEST_PARENT_OCD = ObjectClassSyntax.decodeObjectClass(b, DirectoryServer
+ .getSchema(), false);
+ }
+
+ if (TEST_CHILD_OCD == null) {
+ String ocd = "( 1.3.6.1.4.1.26027.1.2.4455114402 "
+ + "NAME 'ds-cfg-test-child-dummy' "
+ + "SUP top STRUCTURAL "
+ + "MUST ( cn $ ds-cfg-virtual-attribute-class $ "
+ + "ds-cfg-virtual-attribute-enabled $ ds-cfg-virtual-attribute-type ) "
+ + "MAY ( ds-cfg-virtual-attribute-base-dn $ ds-cfg-virtual-attribute-group-dn $ "
+ + "ds-cfg-virtual-attribute-filter $ ds-cfg-virtual-attribute-conflict-behavior $"
+ + "ds-cfg-backend-base-dn) " + "X-ORIGIN 'OpenDS Directory Server' )";
+ ByteString b = ByteStringFactory.create(ocd);
+
+ TEST_CHILD_OCD = ObjectClassSyntax.decodeObjectClass(b, DirectoryServer
+ .getSchema(), false);
+ }
+
+ {
+ // Register the test parent object class.
+ DirectoryServer.registerObjectClass(TEST_PARENT_OCD, true);
+
+ // Register the test parent resource bundle.
+ TestParentCfgDefn d = TestParentCfgDefn.getInstance();
+ String baseName = d.getClass().getName();
+ ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName);
+ ManagedObjectDefinitionI18NResource.getInstance().setResourceBundle(d,
+ resourceBundle);
+ }
+
+ {
+ // Register the test child object class.
+ DirectoryServer.registerObjectClass(TEST_CHILD_OCD, true);
+
+ // Register the test child resource bundle.
+ TestChildCfgDefn d = TestChildCfgDefn.getInstance();
+ String baseName = d.getClass().getName();
+ ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName);
+ ManagedObjectDefinitionI18NResource.getInstance().setResourceBundle(d,
+ resourceBundle);
+ }
+
+ // Ensure that the relations are registered (do this after things
+ // that can fail and leave tests in a bad state).
+ RootCfgDefn.getInstance().registerRelationDefinition(
+ RD_TEST_ONE_TO_MANY_PARENT);
+ RootCfgDefn.getInstance().registerRelationDefinition(
+ RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT);
+ LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+ }
+
/**
@@ -74,10 +161,24 @@
* framework.
*/
public static void cleanup() {
- RootCfgDefn.getInstance().deregisterRelationDefinition(
- RD_TEST_ONE_TO_MANY_PARENT);
- RootCfgDefn.getInstance().deregisterRelationDefinition(
- RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT);
+ LDAPProfile.getInstance().popWrapper();
+
+ {
+ RootCfgDefn.getInstance().deregisterRelationDefinition(
+ RD_TEST_ONE_TO_MANY_PARENT);
+ RootCfgDefn.getInstance().deregisterRelationDefinition(
+ RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT);
+ DirectoryServer.deregisterObjectClass(TEST_PARENT_OCD);
+ TestParentCfgDefn d = TestParentCfgDefn.getInstance();
+ ManagedObjectDefinitionI18NResource.getInstance().removeResourceBundle(d);
+ }
+
+ {
+ DirectoryServer.deregisterObjectClass(TEST_CHILD_OCD);
+ TestChildCfgDefn d = TestChildCfgDefn.getInstance();
+ ManagedObjectDefinitionI18NResource.getInstance().removeResourceBundle(d);
+ }
+
}
@@ -86,16 +187,13 @@
* Gets the one-to-many relation between the root and test-parent
* components.
* <p>
- * Unit tests which call this method <b>must</b> call
- * {@link #cleanup()} on completion.
+ * Unit tests which call this method <b>must</b> have already
+ * called {@link #setUp()}.
*
* @return Returns the one-to-many relation between the root and
* test-parent components.
*/
public static InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg> getTestOneToManyParentRelationDefinition() {
- // Ensure that the relation is registered.
- RootCfgDefn.getInstance().registerRelationDefinition(
- RD_TEST_ONE_TO_MANY_PARENT);
return RD_TEST_ONE_TO_MANY_PARENT;
}
@@ -105,21 +203,42 @@
* Gets the one-to-zero-or-one relation between the root and a
* test-parent component.
* <p>
- * Unit tests which call this method <b>must</b> call
- * {@link #cleanup()} on completion.
+ * Unit tests which call this method <b>must</b> have already
+ * called {@link #setUp()}.
*
* @return Returns the one-to-zero-or-one relation between the root
* and a test-parent component.
*/
public static OptionalRelationDefinition<TestParentCfgClient, TestParentCfg> getTestOneToZeroOrOneParentRelationDefinition() {
- // Ensure that the relation is registered.
- RootCfgDefn.getInstance().registerRelationDefinition(
- RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT);
return RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT;
}
+ /**
+ * Adds a constraint temporarily with test child definition.
+ *
+ * @param constraint
+ * The constraint.
+ */
+ public static void addConstraint(Constraint constraint) {
+ TestChildCfgDefn.getInstance().registerConstraint(constraint);
+ }
+
+
+
+ /**
+ * Removes a constraint from the test child definition.
+ *
+ * @param constraint
+ * The constraint.
+ */
+ public static void removeConstraint(Constraint constraint) {
+ TestChildCfgDefn.getInstance().deregisterConstraint(constraint);
+ }
+
+
+
// Prevent instantiation.
private TestCfg() {
// No implementation required.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
index 3d391a2..fb79669 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
@@ -32,6 +32,7 @@
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.TestChildCfgClient;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
@@ -76,6 +77,17 @@
/**
+ * Get the "aggregation-property" property.
+ * <p>
+ * An aggregation property which references connection handlers.
+ *
+ * @return Returns the values of the "aggregation-property" property.
+ */
+ SortedSet<String> getAggregationProperty();
+
+
+
+ /**
* Get the "mandatory-boolean-property" property.
* <p>
* A mandatory boolean property.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
index b1a025a..6772f1b 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
@@ -34,6 +34,7 @@
import org.opends.server.admin.IllegalPropertyValueException;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.PropertyIsReadOnlyException;
+import org.opends.server.admin.TestChildCfg;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
@@ -59,6 +60,30 @@
/**
+ * Get the "aggregation-property" property.
+ * <p>
+ * An aggregation property which references connection handlers.
+ *
+ * @return Returns the values of the "aggregation-property" property.
+ */
+ SortedSet<String> getAggregationProperty();
+
+
+
+ /**
+ * Set the "aggregation-property" property.
+ * <p>
+ * An aggregation property which references connection handlers.
+ *
+ * @param values The values of the "aggregation-property" property.
+ * @throws IllegalPropertyValueException
+ * If one or more of the new values are invalid.
+ */
+ void setAggregationProperty(Collection<String> values) throws IllegalPropertyValueException;
+
+
+
+ /**
* Get the "mandatory-boolean-property" property.
* <p>
* A mandatory boolean property.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
index 7d91ae3..4a5780c 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
@@ -34,24 +34,30 @@
import org.opends.server.admin.AttributeTypePropertyDefinition;
import org.opends.server.admin.BooleanPropertyDefinition;
import org.opends.server.admin.ClassPropertyDefinition;
+import org.opends.server.admin.DNPropertyDefinition;
+import org.opends.server.admin.DefaultBehaviorProvider;
+import org.opends.server.admin.DefinedDefaultBehaviorProvider;
+import org.opends.server.admin.ManagedObjectAlreadyExistsException;
+import org.opends.server.admin.ManagedObjectDefinition;
+import org.opends.server.admin.ManagedObjectPath;
+import org.opends.server.admin.PropertyIsReadOnlyException;
+import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.PropertyProvider;
+import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
-import org.opends.server.admin.DefaultBehaviorProvider;
-import org.opends.server.admin.DefinedDefaultBehaviorProvider;
-import org.opends.server.admin.DNPropertyDefinition;
-import org.opends.server.admin.ManagedObjectAlreadyExistsException;
-import org.opends.server.admin.ManagedObjectDefinition;
-import org.opends.server.admin.PropertyIsReadOnlyException;
-import org.opends.server.admin.PropertyOption;
-import org.opends.server.admin.PropertyProvider;
-import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ServerManagedObject;
-import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
+import org.opends.server.admin.std.client.ConnectionHandlerCfgClient;
+import org.opends.server.admin.TestChildCfgClient;
+import org.opends.server.admin.std.meta.ConnectionHandlerCfgDefn;
+import org.opends.server.admin.std.server.ConnectionHandlerCfg;
+import org.opends.server.admin.TestChildCfg;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
@@ -72,6 +78,11 @@
+ // The "aggregation-property" property definition.
+ private static final AggregationPropertyDefinition<ConnectionHandlerCfgClient, ConnectionHandlerCfg> PD_AGGREGATION_PROPERTY;
+
+
+
// The "mandatory-boolean-property" property definition.
private static final BooleanPropertyDefinition PD_MANDATORY_BOOLEAN_PROPERTY;
@@ -97,6 +108,21 @@
+ // Build the "aggregation-property" property definition.
+ static {
+ AggregationPropertyDefinition.Builder<ConnectionHandlerCfgClient, ConnectionHandlerCfg> builder = AggregationPropertyDefinition.createBuilder(INSTANCE, "aggregation-property");
+ builder.setOption(PropertyOption.MULTI_VALUED);
+ builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "aggregation-property"));
+ builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
+ builder.setParentPath(ManagedObjectPath.valueOf("/"));
+ builder.setRelationDefinition("connection-handler");
+ builder.setManagedObjectDefinition(ConnectionHandlerCfgDefn.getInstance());
+ PD_AGGREGATION_PROPERTY = builder.getInstance();
+ INSTANCE.registerPropertyDefinition(PD_AGGREGATION_PROPERTY);
+ }
+
+
+
// Build the "mandatory-boolean-property" property definition.
static {
BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "mandatory-boolean-property");
@@ -180,28 +206,6 @@
private TestChildCfgDefn() {
super("test-child", null);
}
-
-
-
- /**
- * Adds a constraint temporarily with this test definition.
- *
- * @param constraint The constraint.
- */
- public void addConstraint(Constraint constraint) {
- registerConstraint(constraint);
- }
-
-
-
- /**
- * Removes a constraint from this test definition.
- *
- * @param constraint The constraint.
- */
- public void removeConstraint(Constraint constraint) {
- deregisterConstraint(constraint);
- }
@@ -235,6 +239,19 @@
/**
+ * Get the "aggregation-property" property definition.
+ * <p>
+ * An aggregation property which references connection handlers.
+ *
+ * @return Returns the "aggregation-property" property definition.
+ */
+ public AggregationPropertyDefinition<ConnectionHandlerCfgClient, ConnectionHandlerCfg> getAggregationPropertyPropertyDefinition() {
+ return PD_AGGREGATION_PROPERTY;
+ }
+
+
+
+ /**
* Get the "mandatory-boolean-property" property definition.
* <p>
* A mandatory boolean property.
@@ -323,6 +340,24 @@
/**
* {@inheritDoc}
*/
+ public SortedSet<String> getAggregationProperty() {
+ return impl.getPropertyValues(INSTANCE.getAggregationPropertyPropertyDefinition());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setAggregationProperty(Collection<String> values) {
+ impl.setPropertyValues(INSTANCE.getAggregationPropertyPropertyDefinition(), values);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
public Boolean isMandatoryBooleanProperty() {
return impl.getPropertyValue(INSTANCE.getMandatoryBooleanPropertyPropertyDefinition());
}
@@ -483,6 +518,15 @@
/**
* {@inheritDoc}
*/
+ public SortedSet<String> getAggregationProperty() {
+ return impl.getPropertyValues(INSTANCE.getAggregationPropertyPropertyDefinition());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
public boolean isMandatoryBooleanProperty() {
return impl.getPropertyValue(INSTANCE.getMandatoryBooleanPropertyPropertyDefinition());
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.properties b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.properties
new file mode 100644
index 0000000..a5d5ac7
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.properties
@@ -0,0 +1,9 @@
+user-friendly-name=Test Child
+user-friendly-plural-name=Test Children
+synopsis=A configuration for testing components that are subordinate to a parent component. It re-uses the virtual-attribute configuration LDAP profile.
+property.aggregation-property.synopsis=An aggregation property which references connection handlers.
+property.mandatory-boolean-property.synopsis=A mandatory boolean property.
+property.mandatory-class-property.synopsis=A mandatory Java-class property requiring a component restart.
+property.mandatory-read-only-attribute-type-property.synopsis=A mandatory read-only attribute type property.
+property.optional-multi-valued-dn-property1.synopsis=An optional multi-valued DN property which inherits its values from optional-multi-valued-dn-property in the parent.
+property.optional-multi-valued-dn-property2.synopsis=An optional multi-valued DN property which inherits its values from optional-multi-valued-dn-property1.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildConfiguration.xml b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildConfiguration.xml
index 48bcef1..a15de26 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildConfiguration.xml
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildConfiguration.xml
@@ -26,7 +26,7 @@
! Portions Copyright 2007 Sun Microsystems, Inc.
! -->
<adm:managed-object name="test-child" plural-name="test-children"
- package="org.opends.server.admin.std"
+ package="org.opends.server.admin"
xmlns:adm="http://www.opends.org/admin"
xmlns:ldap="http://www.opends.org/admin-ldap">
<adm:synopsis>
@@ -36,8 +36,8 @@
</adm:synopsis>
<adm:profile name="ldap">
<ldap:object-class>
- <ldap:oid>1.3.6.1.4.1.26027.1.2.91</ldap:oid>
- <ldap:name>ds-cfg-virtual-attribute</ldap:name>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.4455114402</ldap:oid>
+ <ldap:name>ds-cfg-test-child-dummy</ldap:name>
<ldap:superior>top</ldap:superior>
</ldap:object-class>
</adm:profile>
@@ -140,4 +140,22 @@
</ldap:attribute>
</adm:profile>
</adm:property>
+ <adm:property name="aggregation-property" multi-valued="true">
+ <adm:synopsis>
+ An aggregation property which references connection handlers.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:undefined />
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:aggregation parent-path="/"
+ relation-name="connection-handler" />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:oid>1.3.6.1.4.1.26027.1.1.332</ldap:oid>
+ <ldap:name>ds-task-initialize-domain-dn</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
</adm:managed-object>
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.properties b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.properties
new file mode 100644
index 0000000..2e5c044
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.properties
@@ -0,0 +1,12 @@
+user-friendly-name=Test Parent
+user-friendly-plural-name=Test Parents
+synopsis=A configuration for testing components that have child components. It re-uses the virtual-attribute configuration LDAP profile.
+property.mandatory-boolean-property.synopsis=A mandatory boolean property.
+property.mandatory-class-property.synopsis=A mandatory Java-class property requiring a component restart.
+property.mandatory-read-only-attribute-type-property.synopsis=A mandatory read-only attribute type property.
+property.optional-multi-valued-dn-property.synopsis=An optional multi-valued DN property with a defined default behavior.
+relation.optional-test-child.user-friendly-name=Optional Test Child
+relation.optional-test-child.synopsis=A configuration for testing components that are subordinate to a parent component. It re-uses the virtual-attribute configuration LDAP profile.
+relation.test-child.user-friendly-name=Test Child
+relation.test-child.user-friendly-plural-name=Test Children
+relation.test-child.synopsis=A configuration for testing components that are subordinate to a parent component. It re-uses the virtual-attribute configuration LDAP profile.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentConfiguration.xml b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentConfiguration.xml
index a32158a..85f5935 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentConfiguration.xml
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentConfiguration.xml
@@ -26,7 +26,7 @@
! Portions Copyright 2007 Sun Microsystems, Inc.
! -->
<adm:managed-object name="test-parent" plural-name="test-parents"
- package="org.opends.server.admin.std"
+ package="org.opends.server.admin"
xmlns:adm="http://www.opends.org/admin"
xmlns:ldap="http://www.opends.org/admin-ldap">
<adm:synopsis>
@@ -35,8 +35,8 @@
</adm:synopsis>
<adm:profile name="ldap">
<ldap:object-class>
- <ldap:oid>1.3.6.1.4.1.26027.1.2.91</ldap:oid>
- <ldap:name>ds-cfg-virtual-attribute</ldap:name>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.4455114401</ldap:oid>
+ <ldap:name>ds-cfg-test-parent-dummy</ldap:name>
<ldap:superior>top</ldap:superior>
</ldap:object-class>
</adm:profile>
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/AggregationTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/AggregationTest.java
new file mode 100644
index 0000000..13b226c
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/AggregationTest.java
@@ -0,0 +1,357 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.AdminTestCase;
+import org.opends.server.admin.DefinitionDecodingException;
+import org.opends.server.admin.IllegalPropertyValueStringException;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.PropertyException;
+import org.opends.server.admin.TestCfg;
+import org.opends.server.admin.TestChildCfgClient;
+import org.opends.server.admin.TestChildCfgDefn;
+import org.opends.server.admin.TestParentCfgClient;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.std.client.RootCfgClient;
+import org.opends.server.core.DirectoryServer;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test cases for aggregations on the client-side.
+ */
+@Test(sequential = true)
+public class AggregationTest extends AdminTestCase {
+
+ // Test LDIF.
+ private static final String[] TEST_LDIF = new String[] {
+ // Base entries.
+ "dn: cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: config",
+ "",
+ "dn: cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: test-parents",
+ "",
+ // Parent 1 - uses default values for
+ // optional-multi-valued-dn-property.
+ "dn: cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-parent-dummy",
+ "cn: test parent 1",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "",
+ // Child base entry.
+ "dn:cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: multiple children",
+ "",
+ // Child 1 has no references.
+ "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 1",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "",
+ // Child 2 has a single valid reference.
+ "dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 2",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config",
+ "",
+ // Child 3 has a multiple valid references.
+ "dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 3",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config",
+ "ds-cfg-backend-base-dn: cn=LDAPS Connection Handler, cn=connection handlers, cn=config",
+ "",
+ // Child 4 has a single bad reference.
+ "dn: cn=test child 4,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 4",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=bad rdn, cn=config",
+ "",
+ };
+
+
+
+ /**
+ * Sets up tests
+ *
+ * @throws Exception
+ * If the server could not be initialized.
+ */
+ @BeforeClass
+ public void setUp() throws Exception {
+ // This test suite depends on having the schema available, so
+ // we'll start the server.
+ TestCaseUtils.startServer();
+ TestCfg.setUp();
+ }
+
+
+
+ /**
+ * Tears down test environment.
+ */
+ @AfterClass
+ public void tearDown() {
+ TestCfg.cleanup();
+ }
+
+
+
+ /**
+ * Tests that aggregation contains no values when it contains does
+ * not contain any DN attribute values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationEmpty() throws Exception {
+ MockLDAPConnection c = new MockLDAPConnection();
+ c.importLDIF(TEST_LDIF);
+ ManagementContext ctx = LDAPManagementContext.createFromContext(c);
+ TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+ TestChildCfgClient child = parent.getTestChild("test child 1");
+ assertSetEquals(child.getAggregationProperty(), new String[0]);
+ }
+
+
+
+ /**
+ * Tests that aggregation contains single valid value when it
+ * contains a single valid DN attribute values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationSingle() throws Exception {
+ MockLDAPConnection c = new MockLDAPConnection();
+ c.importLDIF(TEST_LDIF);
+ ManagementContext ctx = LDAPManagementContext.createFromContext(c);
+ TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+ TestChildCfgClient child = parent.getTestChild("test child 2");
+
+ // Test normalization.
+ assertSetEquals(child.getAggregationProperty(), "LDAP Connection Handler");
+ assertSetEquals(child.getAggregationProperty(),
+ " LDAP Connection Handler ");
+ assertSetEquals(child.getAggregationProperty(),
+ " ldap connection HANDLER ");
+ }
+
+
+
+ /**
+ * Tests that aggregation contains multiple valid values when it
+ * contains a multiple valid DN attribute values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationMultiple() throws Exception {
+ MockLDAPConnection c = new MockLDAPConnection();
+ c.importLDIF(TEST_LDIF);
+ ManagementContext ctx = LDAPManagementContext.createFromContext(c);
+ TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+ TestChildCfgClient child = parent.getTestChild("test child 3");
+ assertSetEquals(child.getAggregationProperty(), "LDAPS Connection Handler",
+ "LDAP Connection Handler");
+ }
+
+
+
+ /**
+ * Tests that aggregation is rejected when the LDAP DN contains a
+ * valid RDN but an invalid parent DN.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationBadBaseDN() throws Exception {
+ MockLDAPConnection c = new MockLDAPConnection();
+ c.importLDIF(TEST_LDIF);
+ ManagementContext ctx = LDAPManagementContext.createFromContext(c);
+ TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+
+ try {
+ parent.getTestChild("test child 4");
+ Assert.fail("Unexpectedly retrieved test child 4"
+ + " when it had a bad aggregation value");
+ } catch (ManagedObjectDecodingException e) {
+ Collection<PropertyException> causes = e.getCauses();
+ Assert.assertEquals(causes.size(), 1);
+
+ Throwable cause = causes.iterator().next();
+ if (cause instanceof IllegalPropertyValueStringException) {
+ IllegalPropertyValueStringException pe = (IllegalPropertyValueStringException) cause;
+ Assert.assertEquals(pe.getPropertyDefinition(), TestChildCfgDefn
+ .getInstance().getAggregationPropertyPropertyDefinition());
+ Assert.assertEquals(pe.getIllegalValueString(),
+ "cn=LDAP Connection Handler, cn=bad rdn, cn=config");
+ } else {
+ // Got an unexpected cause.
+ throw e;
+ }
+ }
+ }
+
+
+
+ /**
+ * Tests creation of a child managed object with a single reference.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ @Test
+ public void testCreateChildManagedObject() throws Exception {
+ CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
+ "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ c.importLDIF(TEST_LDIF);
+ c.addExpectedAttribute("cn", "test child new");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy");
+ c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
+ c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ c.addExpectedAttribute("ds-cfg-virtual-attribute-type", "description");
+ c.addExpectedAttribute("ds-cfg-backend-base-dn",
+ "cn=LDAP Connection Handler,cn=connection handlers,cn=config");
+
+ ManagementContext ctx = LDAPManagementContext.createFromContext(c);
+ TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+ TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn
+ .getInstance(), "test child new", null);
+ child.setMandatoryBooleanProperty(true);
+ child.setMandatoryReadOnlyAttributeTypeProperty(DirectoryServer
+ .getAttributeType("description"));
+ child.setAggregationProperty(Collections
+ .singleton("LDAP Connection Handler"));
+ child.commit();
+
+ c.assertEntryIsCreated();
+ }
+
+
+
+ /**
+ * Tests modification of a child managed object so that it has a
+ * different reference.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ @Test
+ public void testModifyChildManagedObject() throws Exception {
+ ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
+ "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ c.importLDIF(TEST_LDIF);
+ c.addExpectedModification("ds-cfg-backend-base-dn",
+ "cn=LDAPS Connection Handler,cn=connection handlers,cn=config",
+ "cn=JMX Connection Handler,cn=connection handlers,cn=config");
+ ManagementContext ctx = LDAPManagementContext.createFromContext(c);
+ TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+ TestChildCfgClient child = parent.getTestChild("test child 2");
+ child.setAggregationProperty(Arrays.asList("LDAPS Connection Handler",
+ "JMX Connection Handler"));
+ child.commit();
+ Assert.assertTrue(c.isEntryModified());
+ }
+
+
+
+ // Retrieve the named test parent managed object.
+ private TestParentCfgClient getTestParent(ManagementContext context,
+ String name) throws DefinitionDecodingException,
+ ManagedObjectDecodingException, AuthorizationException,
+ ManagedObjectNotFoundException, ConcurrentModificationException,
+ CommunicationException {
+ ManagedObject<RootCfgClient> root = context
+ .getRootConfigurationManagedObject();
+ return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(),
+ name).getConfiguration();
+ }
+
+
+
+ // Asserts that the actual set of DNs contains the expected values.
+ private void assertSetEquals(SortedSet<String> actual, String... expected) {
+ SortedSet<String> values = new TreeSet<String>(TestChildCfgDefn
+ .getInstance().getAggregationPropertyPropertyDefinition());
+ if (expected != null) {
+ for (String value : expected) {
+ values.add(value);
+ }
+ }
+ Assert.assertEquals((Object) actual, (Object) values);
+ }
+
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java
index 9c7e8b1..624647e 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java
@@ -42,10 +42,8 @@
import org.opends.server.admin.AdminTestCase;
import org.opends.server.admin.Constraint;
import org.opends.server.admin.DefinitionDecodingException;
-import org.opends.server.admin.LDAPProfile;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectNotFoundException;
-import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.TestCfg;
import org.opends.server.admin.TestChildCfgClient;
import org.opends.server.admin.TestChildCfgDefn;
@@ -93,7 +91,7 @@
// optional-multi-valued-dn-property.
"dn: cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-parent-dummy",
"cn: test parent 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -103,7 +101,7 @@
// optional-multi-valued-dn-property.
"dn: cn=test parent 2,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-parent-dummy",
"cn: test parent 2",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -115,7 +113,7 @@
// optional-multi-valued-dn-property.
"dn: cn=test parent 3,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-parent-dummy",
"cn: test parent 3",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -139,7 +137,7 @@
// optional-multi-valued-dn-property2.
"dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -149,7 +147,7 @@
// optional-multi-valued-dn-property2.
"dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 2",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -162,7 +160,7 @@
// optional-multi-valued-dn-property2.
"dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 3",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -177,12 +175,12 @@
// optional-multi-valued-dn-property2.
"dn: cn=test child 1,cn=test children,cn=test parent 2,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
"ds-cfg-virtual-attribute-type: description",
- ""
+ "",
};
@@ -273,7 +271,7 @@
// This test suite depends on having the schema available, so
// we'll start the server.
TestCaseUtils.startServer();
- LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+ TestCfg.setUp();
}
@@ -283,7 +281,6 @@
*/
@AfterClass
public void tearDown() {
- LDAPProfile.getInstance().popWrapper();
TestCfg.cleanup();
}
@@ -301,7 +298,7 @@
"cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
c.importLDIF(TEST_LDIF);
c.addExpectedAttribute("cn", "test child new");
- c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy");
c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
"org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
@@ -372,7 +369,7 @@
"cn=test parent new,cn=test parents,cn=config");
c.importLDIF(TEST_LDIF);
c.addExpectedAttribute("cn", "test parent new");
- c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-parent-dummy");
c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
"org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
@@ -438,6 +435,7 @@
"dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com");
assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
"dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com");
+ Assert.assertEquals(child.isMandatoryBooleanProperty(), Boolean.TRUE);
}
@@ -537,7 +535,7 @@
"cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
c.importLDIF(TEST_LDIF);
c.addExpectedAttribute("cn", "test child new");
- c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy");
c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
"org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
@@ -582,7 +580,7 @@
"cn=test child new,cn=test children,cn=test parent 2,cn=test parents,cn=config");
c.importLDIF(TEST_LDIF);
c.addExpectedAttribute("cn", "test child new");
- c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy");
c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
"org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
@@ -808,14 +806,14 @@
@Test
public void testAddConstraintSuccess() throws Exception {
Constraint constraint = new MockConstraint(true, false, false);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
"cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
c.importLDIF(TEST_LDIF);
c.addExpectedAttribute("cn", "test child new");
- c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy");
c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
"org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
@@ -833,7 +831,7 @@
c.assertEntryIsCreated();
} finally {
// Clean up.
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
}
}
@@ -849,14 +847,14 @@
@Test(expectedExceptions=OperationRejectedException.class)
public void testAddConstraintFail() throws Exception {
Constraint constraint = new MockConstraint(false, true, true);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
"cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
c.importLDIF(TEST_LDIF);
c.addExpectedAttribute("cn", "test child new");
- c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute");
+ c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child-dummy");
c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true");
c.addExpectedAttribute("ds-cfg-virtual-attribute-class",
"org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
@@ -873,7 +871,7 @@
Assert.fail("The add constraint failed to prevent creation of the managed object");
} finally {
// Clean up.
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
}
}
@@ -889,7 +887,7 @@
@Test
public void testRemoveConstraintSuccess() throws Exception {
Constraint constraint = new MockConstraint(false, false, true);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection(
@@ -901,7 +899,7 @@
c.assertSubtreeIsDeleted();
} finally {
// Clean up.
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
}
}
@@ -917,7 +915,7 @@
@Test(expectedExceptions=OperationRejectedException.class)
public void testRemoveConstraintFail() throws Exception {
Constraint constraint = new MockConstraint(true, true, false);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection(
@@ -929,7 +927,7 @@
Assert.fail("The remove constraint failed to prevent removal of the managed object");
} finally {
// Clean up.
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
}
}
@@ -945,7 +943,7 @@
@Test
public void testModifyConstraintSuccess() throws Exception {
Constraint constraint = new MockConstraint(false, true, false);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
@@ -960,7 +958,7 @@
Assert.assertTrue(c.isEntryModified());
} finally {
// Clean up.
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
}
}
@@ -976,7 +974,7 @@
@Test(expectedExceptions = OperationRejectedException.class)
public void testModifyConstraintFail() throws Exception {
Constraint constraint = new MockConstraint(true, false, true);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
@@ -992,7 +990,7 @@
.fail("The modify constraint failed to prevent modification of the managed object");
} finally {
// Clean up.
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
}
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java
new file mode 100644
index 0000000..3641a92
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/AggregationTest.java
@@ -0,0 +1,377 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.server;
+
+
+
+import java.util.Collection;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.AdminTestCase;
+import org.opends.server.admin.IllegalPropertyValueStringException;
+import org.opends.server.admin.PropertyException;
+import org.opends.server.admin.TestCfg;
+import org.opends.server.admin.TestChildCfg;
+import org.opends.server.admin.TestChildCfgDefn;
+import org.opends.server.admin.TestParentCfg;
+import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
+import org.opends.server.admin.std.server.RootCfg;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test cases for aggregations on the server-side.
+ */
+@Test(sequential=true)
+public final class AggregationTest extends AdminTestCase {
+
+ // Test child 1 LDIF.
+ private static final String[] TEST_CHILD_1 = new String[] {
+ "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 1",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real"
+ };
+
+
+
+ // Assert that the values of child 1 are correct.
+ private void assertChild1(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertSetEquals(child.getAggregationProperty(), new String[0]);
+ }
+
+ // Test child 2 LDIF.
+ private static final String[] TEST_CHILD_2 = new String[] {
+ "dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 2",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config"
+ };
+
+
+
+ // Assert that the values of child 2 are correct.
+ private void assertChild2(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+
+ // Test normalization.
+ assertSetEquals(child.getAggregationProperty(), "LDAP Connection Handler");
+ assertSetEquals(child.getAggregationProperty(),
+ " LDAP Connection Handler ");
+ assertSetEquals(child.getAggregationProperty(),
+ " ldap connection HANDLER ");
+ }
+
+ // Test child 3 LDIF (invalid reference).
+ private static final String[] TEST_CHILD_3 = new String[] {
+ "dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 3",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=bad rdn, cn=config"
+ };
+
+ // Test child 4 LDIF.
+ private static final String[] TEST_CHILD_4 = new String[] {
+ "dn: cn=test child 4,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-child-dummy",
+ "cn: test child 4",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "ds-cfg-backend-base-dn: cn=LDAP Connection Handler, cn=connection handlers, cn=config",
+ "ds-cfg-backend-base-dn: cn=LDAPS Connection Handler, cn=connection handlers, cn=config"
+ };
+
+
+
+ // Assert that the values of child 4 are correct.
+ private void assertChild4(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertSetEquals(child.getAggregationProperty(), "LDAPS Connection Handler",
+ "LDAP Connection Handler");
+ }
+
+ // Test LDIF.
+ private static final String[] TEST_LDIF = new String[] {
+ // Base entries.
+ "dn: cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: test parents",
+ "",
+ // Parent 1.
+ "dn: cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-test-parent-dummy",
+ "cn: test parent 1",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "",
+ // Child base entries.
+ "dn:cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: test children",
+ ""
+ };
+
+ // JNDI LDAP context.
+ private JNDIDirContextAdaptor adaptor = null;
+
+
+
+ /**
+ * Sets up tests
+ *
+ * @throws Exception
+ * If the server could not be initialized.
+ */
+ @BeforeClass
+ public void setUp() throws Exception {
+ // This test suite depends on having the schema available, so
+ // we'll start the server.
+ TestCaseUtils.startServer();
+ TestCfg.setUp();
+
+ // Add test managed objects.
+ TestCaseUtils.addEntries(TEST_LDIF);
+ }
+
+
+
+ /**
+ * Tears down test environment.
+ *
+ * @throws Exception
+ * If the test entries could not be removed.
+ */
+ @AfterClass
+ public void tearDown() throws Exception {
+ TestCfg.cleanup();
+
+ // Remove test entries.
+ deleteSubtree("cn=test parents,cn=config");
+ }
+
+
+
+ /**
+ * Tests that aggregation contains no values when it
+ * contains does not contain any DN attribute values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationEmpty() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ assertChild1(parent.getTestChild("test child 1"));
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that aggregation contains single valid value when it
+ * contains a single valid DN attribute values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationSingle() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_2);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ assertChild2(parent.getTestChild("test child 2"));
+ } finally {
+ deleteSubtree("cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that aggregation is rejected when the LDAP DN contains a
+ * valid RDN but an invalid parent DN.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationBadBaseDN() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_3);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ parent.getTestChild("test child 3");
+ Assert
+ .fail("Unexpectedly added test child 3 when it had a bad aggregation value");
+ } catch (ConfigException e) {
+ // Check that we have a decoding exception as the cause and
+ // there was only one cause the illegal property value.
+ Throwable cause = e.getCause();
+ if (cause instanceof ServerManagedObjectDecodingException) {
+ ServerManagedObjectDecodingException de = (ServerManagedObjectDecodingException) cause;
+
+ Collection<PropertyException> causes = de.getCauses();
+ Assert.assertEquals(causes.size(), 1);
+
+ cause = causes.iterator().next();
+ if (cause instanceof IllegalPropertyValueStringException) {
+ IllegalPropertyValueStringException pe = (IllegalPropertyValueStringException) cause;
+ Assert.assertEquals(pe.getPropertyDefinition(), TestChildCfgDefn
+ .getInstance().getAggregationPropertyPropertyDefinition());
+ Assert.assertEquals(pe.getIllegalValueString(),
+ "cn=LDAP Connection Handler, cn=bad rdn, cn=config");
+ } else {
+ // Got an unexpected cause.
+ throw e;
+ }
+ } else {
+ // Got an unexpected cause.
+ throw e;
+ }
+ } finally {
+ deleteSubtree("cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that aggregation contains multiple valid values when it
+ * contains a multiple valid DN attribute values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAggregationMultipleValues() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_4);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ assertChild4(parent.getTestChild("test child 4"));
+ } finally {
+ deleteSubtree("cn=test child 4,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ // Asserts that the actual set of DNs contains the expected values.
+ private void assertSetEquals(SortedSet<String> actual, String... expected) {
+ SortedSet<String> values = new TreeSet<String>(TestChildCfgDefn
+ .getInstance().getAggregationPropertyPropertyDefinition());
+ if (expected != null) {
+ for (String value : expected) {
+ values.add(value);
+ }
+ }
+ Assert.assertEquals((Object) actual, (Object) values);
+ }
+
+
+
+ // Deletes the named sub-tree.
+ private void deleteSubtree(String dn) throws Exception {
+ getAdaptor().deleteSubtree(new LdapName(dn));
+ }
+
+
+
+ // Gets the JNDI connection for the test server instance.
+ private synchronized JNDIDirContextAdaptor getAdaptor() throws Exception {
+ if (adaptor == null) {
+ adaptor = JNDIDirContextAdaptor.simpleBind("127.0.0.1", TestCaseUtils
+ .getServerLdapPort(), "cn=directory manager", "password");
+ }
+ return adaptor;
+ }
+
+
+
+ // Gets the named parent configuration.
+ private TestParentCfg getParent(String name) throws IllegalArgumentException,
+ ConfigException {
+ ServerManagementContext ctx = ServerManagementContext.getInstance();
+ ServerManagedObject<RootCfg> root = ctx.getRootConfigurationManagedObject();
+ TestParentCfg parent = root.getChild(
+ TestCfg.getTestOneToManyParentRelationDefinition(), name)
+ .getConfiguration();
+ return parent;
+ }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ConstraintTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ConstraintTest.java
index a182534..a234ff8 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ConstraintTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ConstraintTest.java
@@ -36,11 +36,8 @@
import org.opends.messages.Message;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.AdminTestCase;
-import org.opends.server.admin.LDAPProfile;
-import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.TestCfg;
import org.opends.server.admin.TestChildCfg;
-import org.opends.server.admin.TestChildCfgDefn;
import org.opends.server.admin.TestParentCfg;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.std.server.RootCfg;
@@ -153,7 +150,7 @@
private static final String[] TEST_CHILD_1 = new String[] {
"dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -173,7 +170,7 @@
// optional-multi-valued-dn-property.
"dn: cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-parent-dummy",
"cn: test parent 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -204,7 +201,7 @@
// This test suite depends on having the schema available, so
// we'll start the server.
TestCaseUtils.startServer();
- LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+ TestCfg.setUp();
// Add test managed objects.
TestCaseUtils.addEntries(TEST_LDIF);
@@ -220,7 +217,6 @@
*/
@AfterClass
public void tearDown() throws Exception {
- LDAPProfile.getInstance().popWrapper();
TestCfg.cleanup();
// Remove test entries.
@@ -242,7 +238,7 @@
parent.addTestChildAddListener(listener);
MockConstraint constraint = new MockConstraint(true, false, false);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
try {
@@ -256,7 +252,7 @@
}
}
} finally {
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
parent.removeTestChildAddListener(listener);
}
}
@@ -276,7 +272,7 @@
parent.addTestChildAddListener(listener);
MockConstraint constraint = new MockConstraint(false, true, true);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
try {
@@ -290,7 +286,7 @@
}
}
} finally {
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
parent.removeTestChildAddListener(listener);
}
}
@@ -310,7 +306,7 @@
parent.addTestChildDeleteListener(listener);
MockConstraint constraint = new MockConstraint(false, false, true);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
// Add the entry.
@@ -319,7 +315,7 @@
// Now delete it - this should trigger the constraint.
deleteSubtree(TEST_CHILD_1_DN);
} finally {
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
parent.removeTestChildDeleteListener(listener);
try {
@@ -346,7 +342,7 @@
parent.addTestChildDeleteListener(listener);
MockConstraint constraint = new MockConstraint(true, true, false);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
// Add the entry.
@@ -361,7 +357,7 @@
// Ignore - this is the expected exception.
}
} finally {
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
parent.removeTestChildDeleteListener(listener);
try {
@@ -386,7 +382,7 @@
TestParentCfg parent = getParent("test parent 1");
MockConstraint constraint = new MockConstraint(false, true, false);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
// Add the entry.
@@ -412,7 +408,7 @@
int result = TestCaseUtils.applyModifications(changes);
Assert.assertEquals(result, ResultCode.SUCCESS.getIntValue());
} finally {
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
try {
deleteSubtree(TEST_CHILD_1_DN);
} catch (Exception e) {
@@ -434,7 +430,7 @@
TestParentCfg parent = getParent("test parent 1");
MockConstraint constraint = new MockConstraint(true, false, true);
- TestChildCfgDefn.getInstance().addConstraint(constraint);
+ TestCfg.addConstraint(constraint);
try {
// Add the entry.
@@ -461,7 +457,7 @@
Assert
.assertEquals(result, ResultCode.UNWILLING_TO_PERFORM.getIntValue());
} finally {
- TestChildCfgDefn.getInstance().removeConstraint(constraint);
+ TestCfg.removeConstraint(constraint);
try {
deleteSubtree(TEST_CHILD_1_DN);
} catch (Exception e) {
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
index a79be3a..de0aa89 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
@@ -36,7 +36,6 @@
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.LDAPProfile;
import org.opends.server.admin.ManagedObjectPath;
-import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.TestCfg;
@@ -67,7 +66,7 @@
// This test suite depends on having the schema available, so
// we'll start the server.
TestCaseUtils.startServer();
- LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+ TestCfg.setUp();
}
@@ -77,7 +76,6 @@
*/
@AfterClass
public void tearDown() {
- LDAPProfile.getInstance().popWrapper();
TestCfg.cleanup();
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java
index ea90fae..a6e5511 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java
@@ -33,11 +33,9 @@
import javax.naming.ldap.LdapName;
-import org.opends.server.TestCaseUtils;
import org.opends.messages.Message;
+import org.opends.server.TestCaseUtils;
import org.opends.server.admin.AdminTestCase;
-import org.opends.server.admin.LDAPProfile;
-import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.TestCfg;
import org.opends.server.admin.TestChildCfg;
import org.opends.server.admin.TestParentCfg;
@@ -181,7 +179,7 @@
private static final String[] TEST_CHILD_1 = new String[] {
"dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -193,7 +191,7 @@
private static final String[] TEST_CHILD_2 = new String[] {
"dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 2",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -207,7 +205,7 @@
private static final String[] TEST_CHILD_3 = new String[] {
"dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 3",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -223,7 +221,7 @@
private static final String[] TEST_CHILD_4 = new String[] {
"dn: cn=test child 4,cn=test children,cn=test parent 2,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-child-dummy",
"cn: test child 4",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -243,7 +241,7 @@
// optional-multi-valued-dn-property.
"dn: cn=test parent 1,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-parent-dummy",
"cn: test parent 1",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -254,7 +252,7 @@
// optional-multi-valued-dn-property.
"dn: cn=test parent 2,cn=test parents,cn=config",
"objectclass: top",
- "objectclass: ds-cfg-virtual-attribute",
+ "objectclass: ds-cfg-test-parent-dummy",
"cn: test parent 2",
"ds-cfg-virtual-attribute-enabled: true",
"ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
@@ -292,7 +290,7 @@
// This test suite depends on having the schema available, so
// we'll start the server.
TestCaseUtils.startServer();
- LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+ TestCfg.setUp();
// Add test managed objects.
TestCaseUtils.addEntries(TEST_LDIF);
@@ -308,7 +306,6 @@
*/
@AfterClass
public void tearDown() throws Exception {
- LDAPProfile.getInstance().popWrapper();
TestCfg.cleanup();
// Remove test entries.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ListenerTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ListenerTest.java
index 7fed672..dfb60db 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ListenerTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/ListenerTest.java
@@ -32,11 +32,9 @@
import java.util.List;
-import org.opends.server.TestCaseUtils;
import org.opends.messages.Message;
+import org.opends.server.TestCaseUtils;
import org.opends.server.admin.AdminTestCase;
-import org.opends.server.admin.LDAPProfile;
-import org.opends.server.admin.MockLDAPProfile;
import org.opends.server.admin.TestCfg;
import org.opends.server.admin.TestParentCfg;
import org.opends.server.admin.std.server.RootCfg;
@@ -125,7 +123,7 @@
// This test suite depends on having the schema available, so
// we'll start the server.
TestCaseUtils.startServer();
- LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+ TestCfg.setUp();
}
@@ -135,7 +133,6 @@
*/
@AfterClass
public void tearDown() {
- LDAPProfile.getInstance().popWrapper();
TestCfg.cleanup();
}
--
Gitblit v1.10.0