From b97785a371b09a674dbef8029a99a730ee928e8d Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Wed, 19 Dec 2007 09:55:26 +0000
Subject: [PATCH] Fix for issue 2446 part #1.
---
opends/resource/admin/preprocessor.xsl | 28 +
opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java | 27 +
opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java | 8
opends/resource/admin/admin.xsd | 119 +++++++
opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java | 67 +++
opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java | 1
opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java | 15
opends/src/server/org/opends/server/admin/client/ManagementContext.java | 7
opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java | 15
opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java | 19
opends/resource/admin/metaMO.xsl | 60 +++
opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java | 68 ++++
opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java | 4
opends/src/server/org/opends/server/admin/RelationDefinition.java | 14
opends/src/server/org/opends/server/admin/client/spi/Driver.java | 17
opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java | 101 +++++
opends/src/server/org/opends/server/admin/DefaultManagedObject.java | 200 ++++++++++++
opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java | 159 +++++++++
18 files changed, 869 insertions(+), 60 deletions(-)
diff --git a/opends/resource/admin/admin.xsd b/opends/resource/admin/admin.xsd
index 8a8625c..61e07b3 100644
--- a/opends/resource/admin/admin.xsd
+++ b/opends/resource/admin/admin.xsd
@@ -592,6 +592,66 @@
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
+ <xsd:complexType name="default-managed-object-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ Specifies the configuration of a default managed object which
+ should be created when a parent managed object is created. For
+ example, creation of a back-end could result in default indexes
+ being created.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="property" minOccurs="0"
+ maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation>
+ Specifies one or more initial values for a property in the
+ default managed object.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" minOccurs="1"
+ maxOccurs="unbounded" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation>
+ The string representation of a value of this property.
+ </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 property.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="managed-object-name" type="tns:name-type"
+ use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The type of default managed object to be created. This must be
+ either the type of the managed object referenced by this
+ relation (this is the default behavior) or a sub-type.
+ </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 default managed object definition
+ if it is not the same as this managed object's package.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
<xsd:complexType name="relation-type">
<xsd:annotation>
<xsd:documentation>
@@ -657,7 +717,20 @@
another type of managed object.
</xsd:documentation>
</xsd:annotation>
- <xsd:complexType />
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="default-managed-object"
+ type="tns:default-managed-object-type" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines a default managed object configuration which
+ should be automatically created when the parent
+ managed object is created.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
</xsd:element>
<xsd:element name="one-to-zero-or-one">
<xsd:annotation>
@@ -666,7 +739,20 @@
with another type of managed object.
</xsd:documentation>
</xsd:annotation>
- <xsd:complexType />
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="default-managed-object"
+ type="tns:default-managed-object-type" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines a default managed object configuration which
+ should be automatically created when the parent
+ managed object is created.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
</xsd:element>
<xsd:element name="one-to-many">
<xsd:annotation>
@@ -676,6 +762,35 @@
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="default-managed-object" minOccurs="0"
+ maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines one or more default managed object
+ configurations which should be automatically created
+ when the parent managed object is created.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension
+ base="tns:default-managed-object-type">
+ <xsd:attribute name="name" type="xsd:string"
+ use="required">
+ <xsd:annotation>
+ <xsd:documentation>
+ Specifies the name that should be used to
+ identify this default managed object
+ instance.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
<xsd:attribute name="plural-name" type="tns:name-type"
use="optional">
<xsd:annotation>
diff --git a/opends/resource/admin/metaMO.xsl b/opends/resource/admin/metaMO.xsl
index 31341fd..cb23507 100644
--- a/opends/resource/admin/metaMO.xsl
+++ b/opends/resource/admin/metaMO.xsl
@@ -943,6 +943,41 @@
'CfgDefn.getInstance().get',
$java-property-name, 'PropertyDefinition());
')" />
</xsl:if>
+ <xsl:for-each select="*/adm:default-managed-object">
+ <xsl:variable name="dmo-java-name">
+ <xsl:call-template name="name-to-java">
+ <xsl:with-param name="value" select="@managed-object-name" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="' {
'" />
+ <xsl:value-of
+ select="concat(' DefaultManagedObject.Builder<',
+ $dmo-java-name, 'CfgClient, ',
+ $dmo-java-name, 'Cfg> dmoBuilder = new DefaultManagedObject.Builder<',
+ $dmo-java-name, 'CfgClient, ',
+ $dmo-java-name, 'Cfg>(',
+ $dmo-java-name, 'CfgDefn.getInstance());
')" />
+ <xsl:for-each select="adm:property">
+ <xsl:value-of
+ select="concat(' dmoBuilder.setPropertyValues("', @name, '"')" />
+ <xsl:for-each select="adm:value">
+ <xsl:value-of
+ select="concat(', "', normalize-space(), '"')" />
+ </xsl:for-each>
+ <xsl:value-of select="');
'" />
+ </xsl:for-each>
+ <xsl:choose>
+ <xsl:when test="@name">
+ <xsl:value-of
+ select="concat(' builder.setDefaultManagedObject("', @name, '", dmoBuilder.getInstance());
')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of
+ select="' builder.setDefaultManagedObject(dmoBuilder.getInstance());
'" />
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="' }
'" />
+ </xsl:for-each>
<xsl:if test="@advanced='true'">
<xsl:value-of
select="' builder.setOption(RelationOption.ADVANCED);
'" />
@@ -1788,6 +1823,31 @@
</xsl:element>
</xsl:for-each>
<xsl:if
+ test="$this-local-relations/*/adm:default-managed-object">
+ <import>org.opends.server.admin.DefaultManagedObject</import>
+ </xsl:if>
+ <xsl:for-each
+ select="$this-local-relations/*/adm:default-managed-object">
+ <xsl:variable name="java-class-name">
+ <xsl:call-template name="name-to-java">
+ <xsl:with-param name="value"
+ select="@managed-object-name" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:element name="import">
+ <xsl:value-of
+ select="concat(@managed-object-package, '.client.', $java-class-name, 'CfgClient')" />
+ </xsl:element>
+ <xsl:element name="import">
+ <xsl:value-of
+ select="concat(@managed-object-package, '.server.', $java-class-name, 'Cfg')" />
+ </xsl:element>
+ <xsl:element name="import">
+ <xsl:value-of
+ select="concat(@managed-object-package, '.meta.', $java-class-name, 'CfgDefn')" />
+ </xsl:element>
+ </xsl:for-each>
+ <xsl:if
test="$this-local-relations[@advanced='true' or @hidden='true']">
<import>org.opends.server.admin.RelationOption</import>
</xsl:if>
diff --git a/opends/resource/admin/preprocessor.xsl b/opends/resource/admin/preprocessor.xsl
index cb2f35c..5e5a57f 100644
--- a/opends/resource/admin/preprocessor.xsl
+++ b/opends/resource/admin/preprocessor.xsl
@@ -852,6 +852,34 @@
</xsl:copy>
</xsl:template>
<!--
+ Merge a default managed object.
+ -->
+ <xsl:template match="adm:default-managed-object" mode="merge-relation">
+ <xsl:param name="managed-object" select="/.." />
+ <xsl:copy>
+ <xsl:copy-of select="@*" />
+ <!--
+ Add missing attribute managed-object-name if it is not provided.
+ -->
+ <xsl:if test="not(@managed-object-name)">
+ <xsl:attribute name="managed-object-name">
+ <xsl:value-of select="$managed-object/@name" />
+ </xsl:attribute>
+ </xsl:if>
+ <!--
+ Add missing attribute managed-object-package if it is not provided.
+ -->
+ <xsl:if test="not(@managed-object-package)">
+ <xsl:attribute name="managed-object-package">
+ <xsl:value-of select="$managed-object/@package" />
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates mode="merge-relation">
+ <xsl:with-param name="managed-object" select="$managed-object" />
+ </xsl:apply-templates>
+ </xsl:copy>
+ </xsl:template>
+ <!--
Merge a one-to-many relation.
-->
<xsl:template match="adm:one-to-many" mode="merge-relation">
diff --git a/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java b/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
index 10fbd64..a4b5f79 100644
--- a/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
+++ b/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -749,8 +749,8 @@
/**
- * Initializes all of the property definitions associated with this
- * managed object definition.
+ * Initializes all of the components associated with this managed
+ * object definition.
*
* @throws Exception
* If this managed object definition could not be
@@ -762,6 +762,10 @@
pd.getDefaultBehaviorProvider().initialize();
}
+ for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) {
+ rd.initialize();
+ }
+
for (Constraint constraint : getAllConstraints()) {
constraint.initialize();
}
diff --git a/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java b/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
index d93c0ac..006504e 100644
--- a/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
+++ b/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
@@ -681,8 +681,9 @@
/**
* {@inheritDoc}
*/
- public Void visitInstantiable(InstantiableRelationDefinition<?, ?> rd,
- ManagedObject<?> p) {
+ public <CC extends ConfigurationClient, SS extends Configuration>
+ Void visitInstantiable(
+ InstantiableRelationDefinition<CC, SS> rd, ManagedObject<?> p) {
try {
for (String childName : p.listChildren(rd)) {
find(p.getChild(rd, childName));
@@ -702,8 +703,9 @@
/**
* {@inheritDoc}
*/
- public Void visitOptional(OptionalRelationDefinition<?, ?> rd,
- ManagedObject<?> p) {
+ public <CC extends ConfigurationClient, SS extends Configuration>
+ Void visitOptional(
+ OptionalRelationDefinition<CC, SS> rd, ManagedObject<?> p) {
try {
find(p.getChild(rd));
} catch (AuthorizationException e) {
@@ -721,8 +723,9 @@
/**
* {@inheritDoc}
*/
- public Void visitSingleton(SingletonRelationDefinition<?, ?> rd,
- ManagedObject<?> p) {
+ public <CC extends ConfigurationClient, SS extends Configuration>
+ Void visitSingleton(
+ SingletonRelationDefinition<CC, SS> rd, ManagedObject<?> p) {
try {
find(p.getChild(rd));
} catch (AuthorizationException e) {
diff --git a/opends/src/server/org/opends/server/admin/DefaultManagedObject.java b/opends/src/server/org/opends/server/admin/DefaultManagedObject.java
new file mode 100644
index 0000000..374657a
--- /dev/null
+++ b/opends/src/server/org/opends/server/admin/DefaultManagedObject.java
@@ -0,0 +1,200 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+
+
+/**
+ * A default managed object which should be created when a parent
+ * managed object is created. Default managed objects are associated
+ * with a {@link RelationDefinition}.
+ *
+ * @param <C>
+ * The type of client default managed object configuration.
+ * @param <S>
+ * The type of server default managed object configuration.
+ */
+public final class DefaultManagedObject
+ <C extends ConfigurationClient, S extends Configuration>
+ implements PropertyProvider {
+
+ /**
+ * An interface for incrementally constructing default managed
+ * objects.
+ *
+ * @param <C>
+ * The type of client default managed object configuration.
+ * @param <S>
+ * The type of server default managed object configuration.
+ */
+ public static final class Builder
+ <C extends ConfigurationClient, S extends Configuration> {
+
+ // The default managed object's definition.
+ private final ManagedObjectDefinition<C, S> definition;
+
+ // The string encoded default managed object's properties.
+ private final Map<String, List<String>> propertyStringValues =
+ new HashMap<String, List<String>>();
+
+
+
+ /**
+ * Creates a new default managed object builder.
+ *
+ * @param definition
+ * The default managed object's definition.
+ */
+ public Builder(ManagedObjectDefinition<C, S> definition) {
+ this.definition = definition;
+ }
+
+
+
+ /**
+ * Construct a default managed object based on the properties of
+ * this builder.
+ *
+ * @return Returns the new default managed object.
+ */
+ public DefaultManagedObject<C, S> getInstance() {
+ return new DefaultManagedObject<C, S>(definition, propertyStringValues);
+ }
+
+
+
+ /**
+ * Defines a property's values for the default managed object.
+ *
+ * @param name
+ * The name of the property.
+ * @param values
+ * One or more property values in the string
+ * representation.
+ */
+ public void setPropertyValues(String name, String... values) {
+ if (values == null || values.length == 0) {
+ throw new IllegalArgumentException(
+ "null or empty values specified for property " + name);
+ }
+
+ propertyStringValues.put(name, Arrays.asList(values));
+ }
+ }
+
+ // The default managed object's definition.
+ private final ManagedObjectDefinition<C, S> definition;
+
+ // The string encoded default managed object's properties.
+ private final Map<String, List<String>> propertyStringValues;
+
+
+
+ // Private constructor.
+ private DefaultManagedObject(ManagedObjectDefinition<C, S> definition,
+ Map<String, List<String>> propertyStringValues) {
+ this.definition = definition;
+ this.propertyStringValues = propertyStringValues;
+ }
+
+
+
+ /**
+ * Gets the managed object definition associated with this default
+ * managed object.
+ *
+ * @return Returns the managed object definition associated with
+ * this default managed object.
+ */
+ public ManagedObjectDefinition<C, S> getManagedObjectDefinition() {
+ return definition;
+ }
+
+
+
+ /**
+ * Gets a mutable copy of the set of property values for the
+ * specified property.
+ *
+ * @param <T>
+ * The type of the property to be retrieved.
+ * @param pd
+ * The property to be retrieved.
+ * @return Returns a newly allocated set containing a copy of the
+ * property's values. An empty set indicates that the
+ * property has no values defined and any default behavior
+ * is applicable.
+ * @throws IllegalArgumentException
+ * If the property definition is not associated with this
+ * managed object's definition.
+ */
+ public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> pd)
+ throws IllegalArgumentException {
+ // Validate the property definition.
+ definition.getPropertyDefinition(pd.getName());
+
+ // Do a defensive copy.
+ SortedSet<T> values = new TreeSet<T>(pd);
+ List<String> stringValues = propertyStringValues.get(pd.getName());
+ if (stringValues != null) {
+ for (String stringValue : stringValues) {
+ values.add(pd.decodeValue(stringValue));
+ }
+ }
+ return values;
+ }
+
+
+
+ /**
+ * Performs run-time initialization of properties.
+ *
+ * @throws Exception
+ * If this default managed object could not be
+ * initialized.
+ */
+ void initialize() throws Exception {
+ // FIXME: it would be nice if we could decode all property values
+ // at this point. However this is not possible on the server side
+ // since some properties will be determined to be invalid since
+ // the schema is not loaded.
+
+ // Validate provided property names.
+ for (String name : propertyStringValues.keySet()) {
+ definition.getPropertyDefinition(name);
+ }
+ }
+}
diff --git a/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java b/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java
index 229ca16..7097e52 100644
--- a/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/InstantiableRelationDefinition.java
@@ -32,7 +32,11 @@
import static org.opends.server.util.Validator.*;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
@@ -62,16 +66,21 @@
* The type of server managed object configuration that
* this relation definition refers to.
*/
- public static class Builder
+ public static final class Builder
<C extends ConfigurationClient, S extends Configuration>
extends AbstractBuilder<C, S, InstantiableRelationDefinition<C, S>> {
// The optional naming property definition.
- private PropertyDefinition<?> namingPropertyDefinition;
+ private PropertyDefinition<?> namingPropertyDefinition = null;
// The plural name of the relation.
private final String pluralName;
+ // The optional default managed objects associated with this
+ // instantiable relation definition.
+ private final Map<String, DefaultManagedObject<? extends C, ? extends S>>
+ defaultManagedObjects = new HashMap<String,
+ DefaultManagedObject<? extends C, ? extends S>>();
/**
@@ -96,6 +105,22 @@
/**
+ * Adds the named default managed object to this instantiable
+ * relation definition.
+ *
+ * @param name
+ * The name of the default managed object.
+ * @param defaultManagedObject
+ * The default managed object.
+ */
+ public void setDefaultManagedObject(String name,
+ DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
+ this.defaultManagedObjects.put(name, defaultManagedObject);
+ }
+
+
+
+ /**
* Sets the naming property for the instantiable relation
* definition.
*
@@ -104,7 +129,7 @@
* which should be used for naming, or <code>null</code>
* if this relation does not use a property for naming.
*/
- public final void setNamingProperty(
+ public void setNamingProperty(
PropertyDefinition<?> namingPropertyDefinition) {
ensureNotNull(namingPropertyDefinition);
this.namingPropertyDefinition = namingPropertyDefinition;
@@ -119,7 +144,7 @@
protected InstantiableRelationDefinition<C, S> buildInstance(
Common<C, S> common) {
return new InstantiableRelationDefinition<C, S>(common, pluralName,
- namingPropertyDefinition);
+ namingPropertyDefinition, defaultManagedObjects);
}
}
@@ -130,14 +155,23 @@
// The plural name of the relation.
private final String pluralName;
+ // The optional default managed objects associated with this
+ // instantiable relation definition.
+ private final Map<String, DefaultManagedObject<? extends C, ? extends S>>
+ defaultManagedObjects;
+
// Private constructor.
private InstantiableRelationDefinition(Common<C, S> common,
- String pluralName, PropertyDefinition<?> namingPropertyDefinition) {
+ String pluralName,
+ PropertyDefinition<?> namingPropertyDefinition,
+ Map<String, DefaultManagedObject<? extends C, ? extends S>>
+ defaultManagedObjects) {
super(common);
this.pluralName = pluralName;
this.namingPropertyDefinition = namingPropertyDefinition;
+ this.defaultManagedObjects = defaultManagedObjects;
}
@@ -153,6 +187,41 @@
/**
+ * Gets the named default managed object associated with this
+ * instantiable relation definition.
+ *
+ * @param name
+ * The name of the default managed object.
+ * @return Returns the named default managed object.
+ * @throws IllegalArgumentException
+ * If there is no default managed object associated with
+ * the provided name.
+ */
+ public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(
+ String name) throws IllegalArgumentException {
+ if (!defaultManagedObjects.containsKey(name)) {
+ throw new IllegalArgumentException(
+ "unrecognized default managed object \"" + name + "\"");
+ }
+ return defaultManagedObjects.get(name);
+ }
+
+
+
+ /**
+ * Gets the names of the default managed objects associated with
+ * this instantiable relation definition.
+ *
+ * @return Returns an unmodifiable set containing the names of the
+ * default managed object.
+ */
+ public Set<String> getDefaultManagedObjectNames() {
+ return Collections.unmodifiableSet(defaultManagedObjects.keySet());
+ }
+
+
+
+ /**
* Get the property of the child managed object definition which
* should be used for naming children.
*
@@ -161,7 +230,7 @@
* <code>null</code> if this relation does not use a
* property for naming.
*/
- public final PropertyDefinition<?> getNamingPropertyDefinition() {
+ public PropertyDefinition<?> getNamingPropertyDefinition() {
return namingPropertyDefinition;
}
@@ -172,7 +241,7 @@
*
* @return Returns the plural name of the relation.
*/
- public final String getPluralName() {
+ public String getPluralName() {
return pluralName;
}
@@ -185,7 +254,7 @@
* @return Returns the user friendly plural name of this relation
* definition in the default locale.
*/
- public final Message getUserFriendlyPluralName() {
+ public Message getUserFriendlyPluralName() {
return getUserFriendlyPluralName(Locale.getDefault());
}
@@ -200,7 +269,7 @@
* @return Returns the user friendly plural name of this relation
* definition in the specified locale.
*/
- public final Message getUserFriendlyPluralName(Locale locale) {
+ public Message getUserFriendlyPluralName(Locale locale) {
String property = "relation." + getName() + ".user-friendly-plural-name";
return ManagedObjectDefinitionI18NResource.getInstance().getMessage(
getParentDefinition(), property, locale);
@@ -212,7 +281,7 @@
* {@inheritDoc}
*/
@Override
- public final void toString(StringBuilder builder) {
+ public void toString(StringBuilder builder) {
builder.append("name=");
builder.append(getName());
builder.append(" type=composition parent=");
@@ -223,4 +292,16 @@
builder.append(getChildDefinition().getName());
builder.append(" minOccurs=0");
}
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void initialize() throws Exception {
+ for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) {
+ dmo.initialize();
+ }
+ }
}
diff --git a/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java b/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java
index 7a5a6c5..dbf0c18 100644
--- a/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/OptionalRelationDefinition.java
@@ -56,10 +56,17 @@
* The type of server managed object configuration that
* this relation definition refers to.
*/
- public static class Builder
+ public static final class Builder
<C extends ConfigurationClient, S extends Configuration>
extends AbstractBuilder<C, S, OptionalRelationDefinition<C, S>> {
+ // The optional default managed object associated with this
+ // optional relation.
+ private DefaultManagedObject<? extends C, ? extends S>
+ defaultManagedObject = null;
+
+
+
/**
* Creates a new builder which can be used to incrementally build
* an optional relation definition.
@@ -79,21 +86,46 @@
/**
+ * Sets the optional default managed object associated with this
+ * optional relation definition.
+ *
+ * @param defaultManagedObject
+ * The default managed object or <code>null</code> if
+ * there is no default managed object defined for this
+ * relation definition.
+ */
+ public void setDefaultManagedObject(
+ DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
+ this.defaultManagedObject = defaultManagedObject;
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
protected OptionalRelationDefinition<C, S> buildInstance(
Common<C, S> common) {
- return new OptionalRelationDefinition<C, S>(common);
+ return new OptionalRelationDefinition<C, S>(common, defaultManagedObject);
}
}
+ // The optional default managed object associated with this
+ // optional relation.
+ private final DefaultManagedObject<? extends C, ? extends S>
+ defaultManagedObject;
+
+
+
// Private constructor.
- private OptionalRelationDefinition(Common<C, S> common) {
+ private OptionalRelationDefinition(Common<C, S> common,
+ DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
super(common);
+ this.defaultManagedObject = defaultManagedObject;
}
@@ -109,10 +141,25 @@
/**
+ * Gets the optional default managed object associated with this
+ * optional relation definition.
+ *
+ * @return Returns the default managed object or <code>null</code>
+ * if there is no default managed object defined for this
+ * relation definition.
+ */
+ public DefaultManagedObject<? extends C, ? extends S>
+ getDefaultManagedObject() {
+ return defaultManagedObject;
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
- public final void toString(StringBuilder builder) {
+ public void toString(StringBuilder builder) {
builder.append("name=");
builder.append(getName());
builder.append(" type=composition parent=");
@@ -122,4 +169,16 @@
builder.append(" minOccurs=0 maxOccurs=1");
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void initialize() throws Exception {
+ if (defaultManagedObject != null) {
+ defaultManagedObject.initialize();
+ }
+ }
+
}
diff --git a/opends/src/server/org/opends/server/admin/RelationDefinition.java b/opends/src/server/org/opends/server/admin/RelationDefinition.java
index 0b7cfb3..80e982c 100644
--- a/opends/src/server/org/opends/server/admin/RelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/RelationDefinition.java
@@ -400,4 +400,18 @@
* should be appended.
*/
public abstract void toString(StringBuilder builder);
+
+
+
+ /**
+ * Performs any run-time initialization required by this relation
+ * definition. This may include resolving managed object paths and
+ * property names.
+ *
+ * @throws Exception
+ * If this relation definition could not be initialized.
+ */
+ protected void initialize() throws Exception {
+ // No implementation required.
+ }
}
diff --git a/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java b/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java
index 1b41411..e3db527 100644
--- a/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java
+++ b/opends/src/server/org/opends/server/admin/RelationDefinitionVisitor.java
@@ -52,38 +52,59 @@
/**
* Visit an instantiable relation definition.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
* @param rd
* The instantiable relation definition to visit.
* @param p
* A visitor specified parameter.
* @return Returns a visitor specified result.
*/
- R visitInstantiable(InstantiableRelationDefinition<?, ?> rd, P p);
+ <C extends ConfigurationClient, S extends Configuration> R visitInstantiable(
+ InstantiableRelationDefinition<C, S> rd, P p);
/**
* Visit an optional relation definition.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
* @param rd
* The optional relation definition to visit.
* @param p
* A visitor specified parameter.
* @return Returns a visitor specified result.
*/
- R visitOptional(OptionalRelationDefinition<?, ?> rd, P p);
+ <C extends ConfigurationClient, S extends Configuration> R visitOptional(
+ OptionalRelationDefinition<C, S> rd, P p);
/**
* Visit a singleton relation definition.
*
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
* @param rd
* The singleton relation definition to visit.
* @param p
* A visitor specified parameter.
* @return Returns a visitor specified result.
*/
- R visitSingleton(SingletonRelationDefinition<?, ?> rd, P p);
+ <C extends ConfigurationClient, S extends Configuration> R visitSingleton(
+ SingletonRelationDefinition<C, S> rd, P p);
}
diff --git a/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java b/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java
index a2eccaa..27a3b78 100644
--- a/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/SingletonRelationDefinition.java
@@ -56,10 +56,17 @@
* The type of server managed object configuration that
* this relation definition refers to.
*/
- public static class Builder
+ public static final class Builder
<C extends ConfigurationClient, S extends Configuration>
extends AbstractBuilder<C, S, SingletonRelationDefinition<C, S>> {
+ // The optional default managed object associated with this
+ // singleton relation.
+ private DefaultManagedObject<? extends C, ? extends S>
+ defaultManagedObject = null;
+
+
+
/**
* Creates a new builder which can be used to incrementally build
* an singleton relation definition.
@@ -79,21 +86,47 @@
/**
+ * Sets the optional default managed object associated with this
+ * singleton relation definition.
+ *
+ * @param defaultManagedObject
+ * The default managed object or <code>null</code> if
+ * there is no default managed object defined for this
+ * relation definition.
+ */
+ public void setDefaultManagedObject(
+ DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
+ this.defaultManagedObject = defaultManagedObject;
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
protected SingletonRelationDefinition<C, S> buildInstance(
Common<C, S> common) {
- return new SingletonRelationDefinition<C, S>(common);
+ return new SingletonRelationDefinition<C, S>(common,
+ defaultManagedObject);
}
}
+ // The optional default managed object associated with this
+ // singleton relation.
+ private final DefaultManagedObject<? extends C, ? extends S>
+ defaultManagedObject;
+
+
+
// Private constructor.
- private SingletonRelationDefinition(Common<C, S> common) {
+ private SingletonRelationDefinition(Common<C, S> common,
+ DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
super(common);
+ this.defaultManagedObject = defaultManagedObject;
}
@@ -109,10 +142,25 @@
/**
+ * Gets the optional default managed object associated with this
+ * singleton relation definition.
+ *
+ * @return Returns the default managed object or <code>null</code>
+ * if there is no default managed object defined for this
+ * relation definition.
+ */
+ public DefaultManagedObject<? extends C, ? extends S>
+ getDefaultManagedObject() {
+ return defaultManagedObject;
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
- public final void toString(StringBuilder builder) {
+ public void toString(StringBuilder builder) {
builder.append("name=");
builder.append(getName());
builder.append(" type=composition parent=");
@@ -122,4 +170,16 @@
builder.append(" minOccurs=1 maxOccurs=1");
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void initialize() throws Exception {
+ if (defaultManagedObject != null) {
+ defaultManagedObject.initialize();
+ }
+ }
+
}
diff --git a/opends/src/server/org/opends/server/admin/client/ManagementContext.java b/opends/src/server/org/opends/server/admin/client/ManagementContext.java
index 1849260..72d9bae 100644
--- a/opends/src/server/org/opends/server/admin/client/ManagementContext.java
+++ b/opends/src/server/org/opends/server/admin/client/ManagementContext.java
@@ -425,11 +425,10 @@
- /**
- * Close the associated management context.
- *
+ /**
+ * Closes this management context.
*/
- public void close() {
+ public final void close() {
this.getDriver().close();
}
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java b/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
index 8cd4c5b..65fbed3 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
@@ -243,6 +243,7 @@
}
+
/**
* {@inheritDoc}
*/
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
index 5e1f207..8a2592e 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
@@ -141,9 +141,9 @@
throws NamingException;
+
/**
- * Close the associated management context.
- *
+ * Closes the LDAP connection.
*/
public abstract void unbind();
}
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
index 7f790ec..48e8064 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -192,6 +192,16 @@
* {@inheritDoc}
*/
@Override
+ public void close() {
+ connection.unbind();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public <C extends ConfigurationClient, S extends Configuration>
ManagedObject<? extends C> getManagedObject(
ManagedObjectPath<C, S> path) throws DefinitionDecodingException,
@@ -408,15 +418,6 @@
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() {
- connection.unbind();
- }
-
-
/**
* {@inheritDoc}
diff --git a/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java b/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
index f7fc2a9..c9a729f 100644
--- a/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
@@ -42,6 +42,7 @@
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.Constraint;
import org.opends.server.admin.DefaultBehaviorException;
+import org.opends.server.admin.DefaultManagedObject;
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.IllegalPropertyValueException;
import org.opends.server.admin.IllegalPropertyValueStringException;
@@ -57,6 +58,7 @@
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.RelationDefinitionVisitor;
import org.opends.server.admin.SingletonRelationDefinition;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.ClientConstraintHandler;
@@ -82,6 +84,150 @@
public abstract class AbstractManagedObject<T extends ConfigurationClient>
implements ManagedObject<T> {
+ /**
+ * Creates any default managed objects associated with a relation
+ * definition.
+ */
+ private final class DefaultManagedObjectFactory implements
+ RelationDefinitionVisitor<Void, Void> {
+
+ // Possible exceptions.
+ private AuthorizationException ae = null;
+
+ private ManagedObjectAlreadyExistsException moaee = null;
+
+ private MissingMandatoryPropertiesException mmpe = null;
+
+ private ConcurrentModificationException cme = null;
+
+ private OperationRejectedException ore = null;
+
+ private CommunicationException ce = null;
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitInstantiable(
+ InstantiableRelationDefinition<C, S> rd, Void p) {
+ for (String name : rd.getDefaultManagedObjectNames()) {
+ DefaultManagedObject<? extends C, ? extends S> dmo = rd
+ .getDefaultManagedObject(name);
+ ManagedObjectDefinition<? extends C, ? extends S> d = dmo
+ .getManagedObjectDefinition();
+ ManagedObject<? extends C> child;
+ try {
+ child = createChild(rd, d, name, null);
+ } catch (IllegalManagedObjectNameException e) {
+ // This should not happen.
+ throw new RuntimeException(e);
+ }
+ createDefaultManagedObject(d, child, dmo);
+ }
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitOptional(
+ OptionalRelationDefinition<C, S> rd, Void p) {
+ if (rd.getDefaultManagedObject() != null) {
+ DefaultManagedObject<? extends C, ? extends S> dmo = rd
+ .getDefaultManagedObject();
+ ManagedObjectDefinition<? extends C, ? extends S> d = dmo
+ .getManagedObjectDefinition();
+ ManagedObject<? extends C> child = createChild(rd, d, null);
+ createDefaultManagedObject(d, child, dmo);
+ }
+ return null;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitSingleton(
+ SingletonRelationDefinition<C, S> rd, Void p) {
+ // Do nothing - not possible to create singletons
+ // dynamically.
+ return null;
+ }
+
+
+
+ // Create the child managed object.
+ private void createDefaultManagedObject(ManagedObjectDefinition<?, ?> d,
+ ManagedObject<?> child, DefaultManagedObject<?, ?> dmo) {
+ for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
+ setPropertyValues(child, pd, dmo);
+ }
+
+ try {
+ child.commit();
+ } catch (AuthorizationException e) {
+ ae = e;
+ } catch (ManagedObjectAlreadyExistsException e) {
+ moaee = e;
+ } catch (MissingMandatoryPropertiesException e) {
+ mmpe = e;
+ } catch (ConcurrentModificationException e) {
+ cme = e;
+ } catch (OperationRejectedException e) {
+ ore = e;
+ } catch (CommunicationException e) {
+ ce = e;
+ }
+ }
+
+
+
+ /**
+ * Creates the default managed objects associated with the
+ * provided relation definition.
+ *
+ * @param rd
+ * The relation definition.
+ */
+ private void createDefaultManagedObjects(RelationDefinition<?, ?> rd)
+ throws AuthorizationException, CommunicationException,
+ ConcurrentModificationException, MissingMandatoryPropertiesException,
+ ManagedObjectAlreadyExistsException, OperationRejectedException {
+ rd.accept(this, null);
+
+ if (ae != null) {
+ throw ae;
+ } else if (ce != null) {
+ throw ce;
+ } else if (cme != null) {
+ throw cme;
+ } else if (mmpe != null) {
+ throw mmpe;
+ } else if (moaee != null) {
+ throw moaee;
+ } else if (ore != null) {
+ throw ore;
+ }
+ }
+
+
+
+ // Set property values.
+ private <PD> void setPropertyValues(ManagedObject<?> mo,
+ PropertyDefinition<PD> pd, DefaultManagedObject<?, ?> dmo) {
+ mo.setPropertyValues(pd, dmo.getPropertyValues(pd));
+ }
+ }
+
+
+
// The managed object definition associated with this managed
// object.
private final ManagedObjectDefinition<T, ? extends Configuration> definition;
@@ -191,11 +337,22 @@
modifyExistingManagedObject();
} else {
addNewManagedObject();
- existsOnServer = true;
}
// Make all pending property values active.
properties.commit();
+
+ // If the managed object was created make sure that any default
+ // subordinate managed objects are also created.
+ if (!existsOnServer) {
+ DefaultManagedObjectFactory factory = new DefaultManagedObjectFactory();
+ for (RelationDefinition<?, ?> rd :
+ definition.getAllRelationDefinitions()) {
+ factory.createDefaultManagedObjects(rd);
+ }
+
+ existsOnServer = true;
+ }
}
diff --git a/opends/src/server/org/opends/server/admin/client/spi/Driver.java b/opends/src/server/org/opends/server/admin/client/spi/Driver.java
index c4ae4ea..32201bc 100644
--- a/opends/src/server/org/opends/server/admin/client/spi/Driver.java
+++ b/opends/src/server/org/opends/server/admin/client/spi/Driver.java
@@ -295,6 +295,16 @@
/**
+ * Closes any context associated with this management context
+ * driver.
+ */
+ public void close() {
+ // do nothing by default
+ }
+
+
+
+ /**
* Deletes the named instantiable child managed object from the
* named parent managed object.
*
@@ -656,13 +666,6 @@
CommunicationException;
- /**
- * Close the associated management context.
- *
- */
- public void close() {
- // do nothing by default
- }
/**
* Deletes the named managed object.
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java
index d9b00e1..82b1f12 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandlerFactory.java
@@ -62,8 +62,9 @@
/**
* {@inheritDoc}
*/
- public Void visitInstantiable(InstantiableRelationDefinition<?, ?> rd,
- ManagedObjectPath<?, ?> p) {
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitInstantiable(
+ InstantiableRelationDefinition<C, S> rd, ManagedObjectPath<?, ?> p) {
try {
// Create the sub-commands.
createHandlers.add(CreateSubCommandHandler.create(parser, p, rd));
@@ -87,8 +88,9 @@
/**
* {@inheritDoc}
*/
- public Void visitOptional(OptionalRelationDefinition<?, ?> rd,
- ManagedObjectPath<?, ?> p) {
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitOptional(
+ OptionalRelationDefinition<C, S> rd, ManagedObjectPath<?, ?> p) {
try {
// Create the sub-commands.
createHandlers.add(CreateSubCommandHandler.create(parser, p, rd));
@@ -112,8 +114,9 @@
/**
* {@inheritDoc}
*/
- public Void visitSingleton(SingletonRelationDefinition<?, ?> rd,
- ManagedObjectPath<?, ?> p) {
+ public <C extends ConfigurationClient, S extends Configuration>
+ Void visitSingleton(
+ SingletonRelationDefinition<C, S> rd, ManagedObjectPath<?, ?> p) {
try {
// Create the sub-commands.
getPropHandlers.add(GetPropSubCommandHandler.create(parser, p, rd));
--
Gitblit v1.10.0