Fix for issue 2446 part #1.
Add support to the admin framework for specifying one or more "default" managed objects which should be created automatically when a parent managed object is created. The XML mark-up is provided as part of the parent managed object's relation definition as follows (the sample is taken from the LocalDBBackend XML definition):
<adm:relation name="local-db-index">
<adm:one-to-many naming-property="attribute">
<adm:default-managed-object name="aci">
<adm:property name="index-type">
<adm:value>presence</adm:value>
</adm:property>
<adm:property name="attribute">
<adm:value>aci</adm:value>
</adm:property>
</adm:default-managed-object>
<adm:default-managed-object name="entryUUID">
<adm:property name="index-type">
<adm:value>equality</adm:value>
</adm:property>
<adm:property name="attribute">
<adm:value>entryUUID</adm:value>
</adm:property>
</adm:default-managed-object>
<adm:default-managed-object name="objectClass">
<adm:property name="index-type">
<adm:value>equality</adm:value>
</adm:property>
<adm:property name="attribute">
<adm:value>objectClass</adm:value>
</adm:property>
</adm:default-managed-object>
</adm:one-to-many>
The functionality is implemented on the client-side API in a generic manner so that it is independent of the underlying driver implementation (so the default indexes would be created if we had an offline direct to file driver as well).
1 files added
17 files modified
| | |
| | | </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> |
| | |
| | | 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> |
| | |
| | | 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> |
| | |
| | | </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> |
| | |
| | | '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);
'" /> |
| | |
| | | </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> |
| | |
| | | </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"> |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | pd.getDefaultBehaviorProvider().initialize(); |
| | | } |
| | | |
| | | for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) { |
| | | rd.initialize(); |
| | | } |
| | | |
| | | for (Constraint constraint : getAllConstraints()) { |
| | | constraint.initialize(); |
| | | } |
| | |
| | | /** |
| | | * {@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)); |
| | |
| | | /** |
| | | * {@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) { |
| | |
| | | /** |
| | | * {@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) { |
| New file |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | 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; |
| | | |
| | | |
| | | |
| | |
| | | * 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>>(); |
| | | |
| | | |
| | | /** |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | * 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; |
| | |
| | | protected InstantiableRelationDefinition<C, S> buildInstance( |
| | | Common<C, S> common) { |
| | | return new InstantiableRelationDefinition<C, S>(common, pluralName, |
| | | namingPropertyDefinition); |
| | | namingPropertyDefinition, defaultManagedObjects); |
| | | } |
| | | |
| | | } |
| | |
| | | // 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; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | * <code>null</code> if this relation does not use a |
| | | * property for naming. |
| | | */ |
| | | public final PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | public PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | return namingPropertyDefinition; |
| | | } |
| | | |
| | |
| | | * |
| | | * @return Returns the plural name of the relation. |
| | | */ |
| | | public final String getPluralName() { |
| | | public String getPluralName() { |
| | | return pluralName; |
| | | } |
| | | |
| | |
| | | * @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()); |
| | | } |
| | | |
| | |
| | | * @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); |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final void toString(StringBuilder builder) { |
| | | public void toString(StringBuilder builder) { |
| | | builder.append("name="); |
| | | builder.append(getName()); |
| | | builder.append(" type=composition parent="); |
| | |
| | | builder.append(getChildDefinition().getName()); |
| | | builder.append(" minOccurs=0"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) { |
| | | dmo.initialize(); |
| | | } |
| | | } |
| | | } |
| | |
| | | * 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. |
| | |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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="); |
| | |
| | | builder.append(" minOccurs=0 maxOccurs=1"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | if (defaultManagedObject != null) { |
| | | defaultManagedObject.initialize(); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | * 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. |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 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); |
| | | |
| | | } |
| | |
| | | * 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. |
| | |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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="); |
| | |
| | | builder.append(" minOccurs=1 maxOccurs=1"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | if (defaultManagedObject != null) { |
| | | defaultManagedObject.initialize(); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Close the associated management context. |
| | | * |
| | | /** |
| | | * Closes this management context. |
| | | */ |
| | | public void close() { |
| | | public final void close() { |
| | | this.getDriver().close(); |
| | | } |
| | | |
| | |
| | | throws NamingException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Close the associated management context. |
| | | * |
| | | * Closes the LDAP connection. |
| | | */ |
| | | public abstract void unbind(); |
| | | } |
| | |
| | | * {@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, |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void close() { |
| | | connection.unbind(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | CommunicationException; |
| | | |
| | | |
| | | /** |
| | | * Close the associated management context. |
| | | * |
| | | */ |
| | | public void close() { |
| | | // do nothing by default |
| | | } |
| | | |
| | | /** |
| | | * Deletes the named managed object. |
| | |
| | | /** |
| | | * {@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)); |
| | |
| | | /** |
| | | * {@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)); |
| | |
| | | /** |
| | | * {@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)); |