From e263f56c0c62b6941249f3541fd2c89e9ebb0306 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 29 May 2007 11:59:21 +0000
Subject: [PATCH] Fix issue 1580: support overriding of property default values.
---
opendj-sdk/opends/resource/admin/metaMO.xsl | 144 ++++++------
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml | 60 +++--
opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java | 87 ++-----
opendj-sdk/opends/resource/admin/admin.xsd | 67 ++++++
opendj-sdk/opends/resource/admin/preprocessor.xsl | 115 ++++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AbstractManagedObjectDefinitionTest.java | 86 +++++++
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java | 16 +
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml | 60 +++--
8 files changed, 447 insertions(+), 188 deletions(-)
diff --git a/opendj-sdk/opends/resource/admin/admin.xsd b/opendj-sdk/opends/resource/admin/admin.xsd
index 281d00a..c011f3b 100644
--- a/opendj-sdk/opends/resource/admin/admin.xsd
+++ b/opendj-sdk/opends/resource/admin/admin.xsd
@@ -115,6 +115,21 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
+ <xsd:element name="property-override"
+ type="tns:property-override-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ Overrides a property definition inherited from a parent
+ managed object definition. Using a property override it is
+ possible to modify the behavior of an inherited property
+ definition in a non-critical way. For example, a managed
+ object definition might override the default behavior of
+ an inherited Java implementation class property so that
+ new instances are created with the correct default
+ implementation class.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
<xsd:element name="property-reference"
type="tns:property-reference-type">
<xsd:annotation>
@@ -407,6 +422,58 @@
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
+ <xsd:complexType name="property-override-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ Overrides a property definition inherited from a parent managed
+ object definition. Using a property override it is possible to
+ modify the behavior of an inherited property definition in a
+ non-critical way. For example, a managed object definition might
+ override the default behavior of an inherited Java
+ implementation class property so that new instances are created
+ with the correct default implementation class.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="requires-admin-action"
+ type="tns:admin-action-type" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ Optionally override the administrative action defined in the
+ overridden property definition. An administrative action
+ defines an optional action which administators must perform
+ after they have modified this property. By default
+ modifications to properties are assumed to take effect
+ immediately and require no additional administrative action.
+ Developers should be aware that, where feasible, they should
+ implement components such that property modifications
+ require no additional administrative action. This is
+ required in order to minimize server downtime during
+ administration and provide a more user-friendly experience.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="default-behavior" type="tns:default-type"
+ minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ Optionally override the default behavior defined in the
+ overridden property definition. The default behavior is
+ applicable when the property has no values specified. All
+ properties must have a default behavior defined unless they
+ are mandatory.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="tns:name-type" use="required">
+ <xsd:annotation>
+ <xsd:documentation>
+ The name of the overridden property.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
<xsd:complexType name="relation-type">
<xsd:annotation>
<xsd:documentation>
diff --git a/opendj-sdk/opends/resource/admin/metaMO.xsl b/opendj-sdk/opends/resource/admin/metaMO.xsl
index 9ba6a10..904b0b9 100644
--- a/opendj-sdk/opends/resource/admin/metaMO.xsl
+++ b/opendj-sdk/opends/resource/admin/metaMO.xsl
@@ -594,86 +594,79 @@
<xsl:value-of
select="' builder.setOption(PropertyOption.HIDDEN);
'" />
</xsl:if>
+ <xsl:if
+ test="not(@mandatory='true') and not(adm:default-behavior)">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('No default behavior defined for non-mandatory property "', @name,
+ '".')" />
+ </xsl:message>
+ </xsl:if>
<xsl:choose>
- <xsl:when test="@mandatory='true'">
+ <xsl:when test="not(adm:default-behavior) or adm:default-behavior/adm:undefined">
<xsl:value-of
select="concat(' builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<', $value-type,'>());
')" />
</xsl:when>
- <xsl:otherwise>
- <xsl:if test="not(adm:default-behavior)">
- <xsl:message terminate="yes">
- <xsl:value-of
- select="concat('No default behavior defined for non-mandatory property "', @name,
- '".')" />
- </xsl:message>
- </xsl:if>
- <xsl:choose>
- <xsl:when test="adm:default-behavior/adm:undefined">
- <xsl:value-of
- select="concat(' builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<', $value-type,'>());
')" />
- </xsl:when>
- <xsl:when test="adm:default-behavior/adm:alias">
- <xsl:value-of
- select="concat(' builder.setDefaultBehaviorProvider(new AliasDefaultBehaviorProvider<', $value-type,'>(INSTANCE, "', @name, '"));
')" />
- </xsl:when>
- <xsl:when test="adm:default-behavior/adm:defined">
- <xsl:value-of
- select="concat(' DefaultBehaviorProvider<', $value-type,'> provider = ',
+ <xsl:when test="adm:default-behavior/adm:alias">
+ <xsl:value-of
+ select="concat(' builder.setDefaultBehaviorProvider(new AliasDefaultBehaviorProvider<', $value-type,'>(INSTANCE, "', @name, '"));
')" />
+ </xsl:when>
+ <xsl:when test="adm:default-behavior/adm:defined">
+ <xsl:value-of
+ select="concat(' DefaultBehaviorProvider<', $value-type,'> provider = ',
'new DefinedDefaultBehaviorProvider<', $value-type,'>(')" />
- <xsl:for-each
- select="adm:default-behavior/adm:defined/adm:value">
- <xsl:value-of
- select="concat('"', normalize-space(), '"')" />
- <xsl:if test="position() != last()">
- <xsl:value-of select="', '" />
- </xsl:if>
- </xsl:for-each>
- <xsl:value-of select="');
'" />
- <xsl:value-of
- select="' builder.setDefaultBehaviorProvider(provider);
'" />
- </xsl:when>
- <xsl:when
- test="adm:default-behavior/adm:inherited/adm:relative">
- <xsl:value-of
- select="concat(' DefaultBehaviorProvider<', $value-type,'> provider = ',
+ <xsl:for-each
+ select="adm:default-behavior/adm:defined/adm:value">
+ <xsl:value-of
+ select="concat('"', normalize-space(), '"')" />
+ <xsl:if test="position() != last()">
+ <xsl:value-of select="', '" />
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:value-of select="');
'" />
+ <xsl:value-of
+ select="' builder.setDefaultBehaviorProvider(provider);
'" />
+ </xsl:when>
+ <xsl:when
+ test="adm:default-behavior/adm:inherited/adm:relative">
+ <xsl:value-of
+ select="concat(' DefaultBehaviorProvider<', $value-type,'> provider = ',
'new RelativeInheritedDefaultBehaviorProvider<', $value-type,'>(')" />
- <xsl:variable name="managed-object-name">
- <xsl:call-template name="name-to-java">
- <xsl:with-param name="value"
- select="adm:default-behavior/adm:inherited/adm:relative/@managed-object-name" />
- </xsl:call-template>
- </xsl:variable>
- <xsl:variable name="property-name"
- select="adm:default-behavior/adm:inherited/adm:relative/@property-name" />
- <xsl:variable name="offset"
- select="adm:default-behavior/adm:inherited/adm:relative/@offset" />
- <xsl:value-of
- select="concat($managed-object-name, 'CfgDefn.getInstance(), "', $property-name, '", ', $offset, ');
')" />
- <xsl:value-of
- select="' builder.setDefaultBehaviorProvider(provider);
'" />
- </xsl:when>
- <xsl:when
- test="adm:default-behavior/adm:inherited/adm:absolute">
- <xsl:value-of
- select="concat(' DefaultBehaviorProvider<', $value-type,'> provider = ',
+ <xsl:variable name="managed-object-name">
+ <xsl:call-template name="name-to-java">
+ <xsl:with-param name="value"
+ select="adm:default-behavior/adm:inherited/adm:relative/@managed-object-name" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="property-name"
+ select="adm:default-behavior/adm:inherited/adm:relative/@property-name" />
+ <xsl:variable name="offset"
+ select="adm:default-behavior/adm:inherited/adm:relative/@offset" />
+ <xsl:value-of
+ select="concat($managed-object-name, 'CfgDefn.getInstance(), "', $property-name, '", ', $offset, ');
')" />
+ <xsl:value-of
+ select="' builder.setDefaultBehaviorProvider(provider);
'" />
+ </xsl:when>
+ <xsl:when
+ test="adm:default-behavior/adm:inherited/adm:absolute">
+ <xsl:value-of
+ select="concat(' DefaultBehaviorProvider<', $value-type,'> provider = ',
'new AbsoluteInheritedDefaultBehaviorProvider<', $value-type,'>(')" />
- <xsl:variable name="property-name"
- select="adm:default-behavior/adm:inherited/adm:absolute/@property-name" />
- <xsl:variable name="path"
- select="adm:default-behavior/adm:inherited/adm:absolute/@path" />
- <xsl:value-of
- select="concat('ManagedObjectPath.valueOf("', $path, '"), "', $property-name, '");
')" />
- <xsl:value-of
- select="' builder.setDefaultBehaviorProvider(provider);
'" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:message terminate="yes">
- <xsl:value-of
- select="concat('Unrecognized default behavior type for property "', @name,
+ <xsl:variable name="property-name"
+ select="adm:default-behavior/adm:inherited/adm:absolute/@property-name" />
+ <xsl:variable name="path"
+ select="adm:default-behavior/adm:inherited/adm:absolute/@path" />
+ <xsl:value-of
+ select="concat('ManagedObjectPath.valueOf("', $path, '"), "', $property-name, '");
')" />
+ <xsl:value-of
+ select="' builder.setDefaultBehaviorProvider(provider);
'" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('Unrecognized default behavior type for property "', @name,
'".')" />
- </xsl:message>
- </xsl:otherwise>
- </xsl:choose>
+ </xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="get-property-definition-ctor" />
@@ -1066,7 +1059,8 @@
</xsl:choose>
<xsl:value-of select="' value)'" />
<xsl:if test="@read-only='true'">
- <xsl:value-of select="' throws PropertyIsReadOnlyException'" />
+ <xsl:value-of
+ select="' throws PropertyIsReadOnlyException'" />
</xsl:if>
<xsl:value-of
select="concat(' {
' ,
@@ -1781,7 +1775,9 @@
<import>java.util.Collection</import>
</xsl:if>
<xsl:if test="$this-all-properties[@read-only='true']">
- <import>org.opends.server.admin.PropertyIsReadOnlyException</import>
+ <import>
+ org.opends.server.admin.PropertyIsReadOnlyException
+ </import>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
diff --git a/opendj-sdk/opends/resource/admin/preprocessor.xsl b/opendj-sdk/opends/resource/admin/preprocessor.xsl
index 246a4e2..2931923 100644
--- a/opendj-sdk/opends/resource/admin/preprocessor.xsl
+++ b/opendj-sdk/opends/resource/admin/preprocessor.xsl
@@ -208,11 +208,15 @@
<!--
Copy all inherited properties.
-->
- <xsl:copy-of select="$hierarchy/adm:managed-object/adm:property" />
+ <xsl:variable name="property-overrides"
+ select="adm:property-override" />
+ <xsl:copy-of
+ select="$hierarchy/adm:managed-object/adm:property[not(@name=$property-overrides/@name)]" />
<!--
Copy all local properties.
-->
- <xsl:apply-templates select="adm:property|adm:property-reference"
+ <xsl:apply-templates
+ select="adm:property|adm:property-reference|adm:property-override"
mode="pre-process">
<xsl:with-param name="moname" select="@name" />
<xsl:with-param name="mopackage" select="@package" />
@@ -463,6 +467,113 @@
</xsl:element>
</xsl:template>
<!--
+ Pre-process a property override pulling in the inherited property
+ definition and by adding a "preprocessor" profile which contains
+ information about where the property was redefined.
+ -->
+ <xsl:template match="adm:property-override" mode="pre-process">
+ <xsl:param name="mopackage" select="/.." />
+ <xsl:param name="moname" select="/.." />
+ <xsl:param name="hierarchy" />
+ <!--
+ Make sure that this property override does not have the same name as another
+ property override in this managed object.
+ -->
+ <xsl:variable name="name" select="@name" />
+ <xsl:if test="../adm:property-override[@name=$name][2]">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('Property override ', @name, ' is already overridden in this managed object')" />
+ </xsl:message>
+ </xsl:if>
+ <!--
+ Make sure that this property overrides an existing property.
+ -->
+ <xsl:if
+ test="not($hierarchy/adm:managed-object/adm:property[@name=$name])">
+ <xsl:message terminate="yes">
+ <xsl:value-of
+ select="concat('Cannot find inherited property ', @name, ' for property override')" />
+ </xsl:message>
+ </xsl:if>
+ <!--
+ Copy the inherited property definition taking care to override
+ the default behavior and admin action if required.
+ -->
+ <xsl:variable name="property"
+ select="$hierarchy/adm:managed-object/adm:property[@name=$name]" />
+ <xsl:element name="adm:property">
+ <xsl:copy-of select="$property/@*" />
+ <xsl:apply-templates
+ select="$property/adm:TODO | $property/adm:synopsis | $property/adm:description"
+ mode="pre-process">
+ <xsl:with-param name="mopackage" select="$mopackage" />
+ <xsl:with-param name="moname" select="$moname" />
+ <xsl:with-param name="hierarchy" select="$hierarchy" />
+ </xsl:apply-templates>
+ <xsl:choose>
+ <xsl:when test="adm:requires-admin-action">
+ <xsl:apply-templates select="adm:requires-admin-action"
+ mode="pre-process">
+ <xsl:with-param name="mopackage" select="$mopackage" />
+ <xsl:with-param name="moname" select="$moname" />
+ <xsl:with-param name="hierarchy" select="$hierarchy" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates
+ select="$property/adm:requires-admin-action"
+ mode="pre-process">
+ <xsl:with-param name="mopackage" select="$mopackage" />
+ <xsl:with-param name="moname" select="$moname" />
+ <xsl:with-param name="hierarchy" select="$hierarchy" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="adm:default-behavior">
+ <xsl:apply-templates select="adm:default-behavior"
+ mode="pre-process">
+ <xsl:with-param name="mopackage" select="$mopackage" />
+ <xsl:with-param name="moname" select="$moname" />
+ <xsl:with-param name="hierarchy" select="$hierarchy" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="$property/adm:default-behavior"
+ mode="pre-process">
+ <xsl:with-param name="mopackage" select="$mopackage" />
+ <xsl:with-param name="moname" select="$moname" />
+ <xsl:with-param name="hierarchy" select="$hierarchy" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates
+ select="$property/adm:syntax | $property/adm:profile[@name!='preprocessor']"
+ mode="pre-process">
+ <xsl:with-param name="mopackage" select="$mopackage" />
+ <xsl:with-param name="moname" select="$moname" />
+ <xsl:with-param name="hierarchy" select="$hierarchy" />
+ </xsl:apply-templates>
+ <!--
+ Now append the preprocessor profile.
+ -->
+ <xsl:element name="adm:profile">
+ <xsl:attribute name="name">
+ <xsl:value-of select="'preprocessor'" />
+ </xsl:attribute>
+ <xsl:element name="admpp:managed-object">
+ <xsl:attribute name="name">
+ <xsl:value-of select="$moname" />
+ </xsl:attribute>
+ <xsl:attribute name="package">
+ <xsl:value-of select="$mopackage" />
+ </xsl:attribute>
+ </xsl:element>
+ </xsl:element>
+ </xsl:element>
+ </xsl:template>
+ <!--
Pre-process a relation, merging information from the referenced
managed object where required, and by adding a "preprocessor" profile
which contains information about where the relation was defined.
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
index 974adcb..0491e22 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/JMXConnectionHandlerConfiguration.xml
@@ -1,31 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ! 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.
- ! -->
-
+ ! 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.
+ ! -->
<adm:managed-object name="jmx-connection-handler"
plural-name="jmx-connection-handlers"
package="org.opends.server.admin.std" extends="connection-handler"
@@ -44,6 +43,15 @@
<ldap:superior>ds-cfg-connection-handler</ldap:superior>
</ldap:object-class>
</adm:profile>
+ <adm:property-override name="java-implementation-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.protocols.jmx.JmxConnectionHandler
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
<adm:property-reference name="listen-port" />
<adm:property-reference name="use-ssl" />
<adm:property-reference name="ssl-cert-nickname" />
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml
index 7ca121f..cfd93ba 100644
--- a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/LDAPConnectionHandlerConfiguration.xml
@@ -1,31 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ! 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.
- ! -->
-
+ ! 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.
+ ! -->
<adm:managed-object name="ldap-connection-handler"
plural-name="ldap-connection-handlers"
package="org.opends.server.admin.std" extends="connection-handler"
@@ -44,6 +43,15 @@
<ldap:superior>ds-cfg-connection-handler</ldap:superior>
</ldap:object-class>
</adm:profile>
+ <adm:property-override name="java-implementation-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.protocols.ldap.LDAPConnectionHandler
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
<adm:property-reference name="listen-port" />
<adm:property-reference name="use-ssl" />
<adm:property-reference name="ssl-cert-nickname" />
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java b/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
index bdb6108..f2d1548 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -73,6 +73,14 @@
// definition.
private final Map<String, RelationDefinition<?, ?>> relationDefinitions;
+ // The set of all property definitions associated with this managed
+ // object definition including inherited property definitions.
+ private final Map<String, PropertyDefinition<?>> allPropertyDefinitions;
+
+ // The set of all relation definitions associated with this managed
+ // object definition including inherited relation definitions.
+ private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions;
+
// The set of managed object definitions which inherit from this definition.
private final Map<String,
AbstractManagedObjectDefinition<? extends C, ? extends S>> children;
@@ -94,12 +102,23 @@
this.parent = parent;
this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
this.relationDefinitions = new HashMap<String, RelationDefinition<?,?>>();
+ this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
+ this.allRelationDefinitions =
+ new HashMap<String, RelationDefinition<?, ?>>();
this.children = new HashMap<String,
- AbstractManagedObjectDefinition<? extends C, ? extends S>>();
+ AbstractManagedObjectDefinition<? extends C, ? extends S>>();
// If we have a parent definition then inherit its features.
if (parent != null) {
parent.children.put(name, this);
+
+ for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) {
+ allPropertyDefinitions.put(pd.getName(), pd);
+ }
+
+ for (RelationDefinition<?, ?> rd : parent.getAllRelationDefinitions()) {
+ allRelationDefinitions.put(rd.getName(), rd);
+ }
}
}
@@ -139,14 +158,7 @@
* object.
*/
public final Collection<PropertyDefinition<?>> getAllPropertyDefinitions() {
- if (parent == null) {
- return getPropertyDefinitions();
- } else {
- List<PropertyDefinition<?>> list = new ArrayList<PropertyDefinition<?>>(
- propertyDefinitions.values());
- list.addAll(parent.getAllPropertyDefinitions());
- return Collections.unmodifiableCollection(list);
- }
+ return Collections.unmodifiableCollection(allPropertyDefinitions.values());
}
@@ -162,14 +174,7 @@
*/
public final Collection<RelationDefinition<?, ?>>
getAllRelationDefinitions() {
- if (parent == null) {
- return getRelationDefinitions();
- } else {
- List<RelationDefinition<?, ?>> list =
- new ArrayList<RelationDefinition<?, ?>>(relationDefinitions.values());
- list.addAll(parent.getAllRelationDefinitions());
- return Collections.unmodifiableCollection(list);
- }
+ return Collections.unmodifiableCollection(allRelationDefinitions.values());
}
@@ -314,15 +319,10 @@
throw new IllegalArgumentException("null or empty property name");
}
- PropertyDefinition d = propertyDefinitions.get(name);
-
+ PropertyDefinition d = allPropertyDefinitions.get(name);
if (d == null) {
- if (parent != null) {
- return parent.getPropertyDefinition(name);
- } else {
- throw new IllegalArgumentException("property definition \"" + name
- + "\" not found");
- }
+ throw new IllegalArgumentException("property definition \"" + name
+ + "\" not found");
}
return d;
@@ -365,15 +365,10 @@
throw new IllegalArgumentException("null or empty relation name");
}
- RelationDefinition d = relationDefinitions.get(name);
-
+ RelationDefinition d = allRelationDefinitions.get(name);
if (d == null) {
- if (parent != null) {
- return parent.getRelationDefinition(name);
- } else {
- throw new IllegalArgumentException("relation definition \"" + name
- + "\" not found");
- }
+ throw new IllegalArgumentException("relation definition \"" + name
+ + "\" not found");
}
return d;
@@ -497,30 +492,6 @@
/**
- * Determine whether this type of managed object has any property definitions.
- *
- * @return Returns <code>true</code> if this type of managed object has any
- * property definitions, <code>false</code> otherwise.
- */
- public final boolean hasPropertyDefinitions() {
- return !propertyDefinitions.isEmpty();
- }
-
-
-
- /**
- * Determine whether this type of managed object has any relation definitions.
- *
- * @return Returns <code>true</code> if this type of managed object has any
- * relation definitions, <code>false</code> otherwise.
- */
- public final boolean hasRelationDefinitions() {
- return !relationDefinitions.isEmpty();
- }
-
-
-
- /**
* Determines whether or not this managed object definition is a
* sub-type of the provided managed object definition. This managed
* object definition is a sub-type of the provided managed object
@@ -579,6 +550,7 @@
String name = d.getName();
propertyDefinitions.put(name, d);
+ allPropertyDefinitions.put(name, d);
}
@@ -596,6 +568,7 @@
String name = d.getName();
relationDefinitions.put(name, d);
+ allRelationDefinitions.put(name, d);
}
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 a0a5bfc..5931ba3 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
@@ -424,7 +424,8 @@
for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
Property<?> p = properties.getProperty(pd);
- if (pd.hasOption(PropertyOption.MANDATORY) && p.isEmpty()) {
+ if (pd.hasOption(PropertyOption.MANDATORY)
+ && p.getEffectiveValues().isEmpty()) {
exceptions.add(new PropertyIsMandatoryException(pd));
}
}
@@ -941,8 +942,17 @@
private <T> void encodeProperty(Attribute attribute,
PropertyDefinition<T> pd, PropertySet properties) {
Property<T> p = properties.getProperty(pd);
- for (T value : p.getPendingValues()) {
- attribute.add(pd.encodeValue(value));
+ 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 (T value : p.getEffectiveValues()) {
+ attribute.add(pd.encodeValue(value));
+ }
+ } else {
+ for (T value : p.getPendingValues()) {
+ attribute.add(pd.encodeValue(value));
+ }
}
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AbstractManagedObjectDefinitionTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AbstractManagedObjectDefinitionTest.java
index 616f1b8..40f23b1 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AbstractManagedObjectDefinitionTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/AbstractManagedObjectDefinitionTest.java
@@ -32,7 +32,13 @@
import static org.testng.Assert.*;
import java.util.Collection;
+import java.util.Collections;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.std.meta.ConnectionHandlerCfgDefn;
+import org.opends.server.admin.std.meta.JMXConnectionHandlerCfgDefn;
+import org.opends.server.admin.std.meta.LDAPConnectionHandlerCfgDefn;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -78,6 +84,21 @@
/**
+ * 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();
+ }
+
+
+
+ /**
* @return data for testIsChildOf.
*/
@DataProvider(name = "testIsChildOf")
@@ -212,4 +233,69 @@
assertEquals(children.size(), 0);
}
+
+
+ /**
+ * Tests that overridden properties work properly. FIXME: should not
+ * use Connection Handlers - should define our own definitions.
+ * <p>
+ * Check that the generic connection handler definition does not
+ * have a default behavior defined for the
+ * java-implementation-class.
+ */
+ @Test
+ public void testPropertyOverride1() {
+ AbstractManagedObjectDefinition<?, ?> d = ConnectionHandlerCfgDefn
+ .getInstance();
+ PropertyDefinition<?> pd = d
+ .getPropertyDefinition("java-implementation-class");
+ DefaultBehaviorProvider<?> dbp = pd.getDefaultBehaviorProvider();
+ assertEquals(dbp.getClass(), UndefinedDefaultBehaviorProvider.class);
+ }
+
+
+
+ /**
+ * Tests that overridden properties work properly. FIXME: should not
+ * use Connection Handlers - should define our own definitions.
+ * <p>
+ * Check that the LDAP connection handler definition does have a
+ * default behavior defined for the java-implementation-class.
+ */
+ @Test
+ public void testPropertyOverride2() {
+ AbstractManagedObjectDefinition<?, ?> d = LDAPConnectionHandlerCfgDefn
+ .getInstance();
+ PropertyDefinition<?> pd = d
+ .getPropertyDefinition("java-implementation-class");
+ DefaultBehaviorProvider<?> dbp = pd.getDefaultBehaviorProvider();
+ assertEquals(dbp.getClass(), DefinedDefaultBehaviorProvider.class);
+
+ DefinedDefaultBehaviorProvider<?> ddbp = (DefinedDefaultBehaviorProvider<?>) dbp;
+ assertEquals(ddbp.getDefaultValues(), Collections
+ .singleton("org.opends.server.protocols.ldap.LDAPConnectionHandler"));
+ }
+
+
+
+ /**
+ * Tests that overridden properties work properly. FIXME: should not
+ * use Connection Handlers - should define our own definitions.
+ * <p>
+ * Check that the JMX connection handler definition does have a
+ * default behavior defined for the java-implementation-class.
+ */
+ @Test
+ public void testPropertyOverride3() {
+ AbstractManagedObjectDefinition<?, ?> d = JMXConnectionHandlerCfgDefn
+ .getInstance();
+ PropertyDefinition<?> pd = d
+ .getPropertyDefinition("java-implementation-class");
+ DefaultBehaviorProvider<?> dbp = pd.getDefaultBehaviorProvider();
+ assertEquals(dbp.getClass(), DefinedDefaultBehaviorProvider.class);
+
+ DefinedDefaultBehaviorProvider<?> ddbp = (DefinedDefaultBehaviorProvider<?>) dbp;
+ assertEquals(ddbp.getDefaultValues(), Collections
+ .singleton("org.opends.server.protocols.jmx.JmxConnectionHandler"));
+ }
}
--
Gitblit v1.10.0