Fix issues 1943 (unable to create je-index), 1996 (exception when creating components with empty names), and 1998 (exception when creating components with blank names).
This change allows one-to-many relations to use a property of the referenced component for naming the component. For example, a je-index has an attribute called "index-attribute" which is the attribute type indexed by the index. There is no need for the je-indexes to have a naming attribute since the value of the "index-attribute" property is sufficient. With this change it is possible to specify a "naming property" for one-to-many relations. In the case of je-indexes, the je-backend je-index relation is now defined as follows:
<adm:relation name="je-index">
<adm:one-to-many naming-property="index-attribute"/>
<adm:profile name="ldap">
<ldap:rdn-sequence>
cn=Index
</ldap:rdn-sequence>
</adm:profile>
<adm:profile name="cli">
<cli:relation>
<cli:default-property name="index-type" />
</cli:relation>
</adm:profile>
</adm:relation>
Note that the one-to-many element now has a "naming-property" attribute which identifies the je-index property which should be used for naming. Also note that the LDAP profile no longer needs a naming-attribute element, since the naming attribute will be the one associated with the index-attribute property.
1 files added
27 files modified
| | |
| | | <xsd:documentation> |
| | | Defines which LDAP attribute should be used to name child |
| | | managed objects referenced by a relation. When not specified, |
| | | "cn" is used by default. |
| | | "cn" is used by default. When the relation uses a naming |
| | | property this element is not required, instead the LDAP |
| | | attribute associated with the naming property will be used. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:element> |
| | |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | <xsd:attribute name="naming-property" type="tns:name-type" |
| | | use="optional"> |
| | | <xsd:annotation> |
| | | <xsd:documentation> |
| | | Specifies the name of a property in the referenced |
| | | managed object which should be used for naming |
| | | instances. For example, an attribute index managed |
| | | object could be named according to the attribute that |
| | | it indexes. If present, the naming property must |
| | | reference a single-valued, mandatory, read-only |
| | | property. If it is not present, the administration |
| | | framework will use the default naming mechanism. |
| | | </xsd:documentation> |
| | | </xsd:annotation> |
| | | </xsd:attribute> |
| | | </xsd:complexType> |
| | | </xsd:element> |
| | | </xsd:choice> |
| | |
| | | '{@link DefaultBehaviorException}s that occurred whilst ', |
| | | 'attempting to determine the default values of the ', $ufn, |
| | | '. This argument can be <code>null<code>.
', |
| | | '@return Returns a new ', $ufn,' configuration instance.
')" /> |
| | | '@return Returns a new ', $ufn,' configuration instance.
', |
| | | '@throws IllegalManagedObjectNameException
', |
| | | ' If the name of the new ', $ufn,' is invalid.
')" /> |
| | | </xsl:call-template> |
| | | <xsl:value-of |
| | | select="concat(' <C extends ', $java-class-name,'CfgClient> C create', $java-relation-name, '(
', |
| | | ' ManagedObjectDefinition<C, ?> d, String name, Collection<DefaultBehaviorException> exceptions);
')" /> |
| | | ' ManagedObjectDefinition<C, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
')" /> |
| | | <xsl:text>
</xsl:text> |
| | | <xsl:text>
</xsl:text> |
| | | <xsl:text>
</xsl:text> |
| | |
| | | org.opends.server.admin.client.OperationRejectedException |
| | | </import> |
| | | </xsl:if> |
| | | <xsl:if test="$this-local-relations/adm:one-to-many"> |
| | | <import> |
| | | org.opends.server.admin.client.IllegalManagedObjectNameException |
| | | </import> |
| | | </xsl:if> |
| | | <xsl:choose> |
| | | <xsl:when test="$this/@extends"> |
| | | <xsl:if test="$parent-package != $this-package"> |
| | |
| | | <xsl:choose> |
| | | <xsl:when |
| | | test="adm:profile[@name='ldap']/ldap:naming-attribute"> |
| | | <xsl:if test="not(adm:one-to-many)"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('Naming attribute specified for relation ', |
| | | @name, ' in managed object definition ', |
| | | $this-name, ' which is not a one-to-many relation.')" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:if test="adm:one-to-many/@naming-property"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('Naming attribute specified for one-to-many relation ', |
| | | @name, ' in managed object definition ', |
| | | $this-name, ' which uses a naming property.')" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:value-of |
| | | select="concat('naming-attribute.', |
| | | normalize-space(@name), |
| | |
| | | select="concat('"', adm:one-to-many/@plural-name, '", ')" /> |
| | | </xsl:if> |
| | | <xsl:value-of |
| | | select="concat($java-managed-object-name, 'CfgDefn.getInstance());
')" /> |
| | | select="concat($java-managed-object-name, 'CfgDefn.getInstance()')" /> |
| | | <xsl:if test="adm:one-to-many"> |
| | | <xsl:value-of select="', '" /> |
| | | <xsl:choose> |
| | | <xsl:when test="adm:one-to-many/@naming-property"> |
| | | <xsl:variable name="java-property-name"> |
| | | <xsl:call-template name="name-to-java"> |
| | | <xsl:with-param name="value" |
| | | select="adm:one-to-many/@naming-property" /> |
| | | </xsl:call-template> |
| | | </xsl:variable> |
| | | <xsl:value-of |
| | | select="concat($java-managed-object-name, |
| | | 'CfgDefn.getInstance().get', |
| | | $java-property-name, 'PropertyDefinition()')" /> |
| | | </xsl:when> |
| | | <xsl:otherwise> |
| | | <xsl:value-of select="'null'" /> |
| | | </xsl:otherwise> |
| | | </xsl:choose> |
| | | </xsl:if> |
| | | <xsl:value-of select="');
'" /> |
| | | <xsl:value-of |
| | | select="concat(' INSTANCE.registerRelationDefinition(RD_', $java-relation-name,');
')" /> |
| | | <xsl:value-of select="' }
'" /> |
| | |
| | | ' * {@inheritDoc}
', |
| | | ' */
', |
| | | ' public <M extends ', $java-class-name, 'CfgClient> M create', $java-relation-name, '(
', |
| | | ' ManagedObjectDefinition<M, ?> d, String name, Collection<DefaultBehaviorException> exceptions) {
', |
| | | ' ManagedObjectDefinition<M, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
', |
| | | ' return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, name, exceptions).getConfiguration();
', |
| | | ' }
')" /> |
| | | <xsl:text>
</xsl:text> |
| | |
| | | <xsl:if test="$this-all-relations/adm:one-to-many"> |
| | | <import>java.util.Collection</import> |
| | | <import> |
| | | org.opends.server.admin.client.IllegalManagedObjectNameException |
| | | </import> |
| | | <import> |
| | | org.opends.server.admin.DefaultBehaviorException |
| | | </import> |
| | | <import> |
| | |
| | | --> |
| | | <xsl:template match="adm:one-to-many" mode="merge-relation"> |
| | | <xsl:param name="managed-object" select="/.." /> |
| | | <!-- |
| | | Make sure that if this relation uses a naming property that the |
| | | naming property exists, is single-valued, mandatory, and read-only. |
| | | --> |
| | | <xsl:if test="@naming-property"> |
| | | <xsl:variable name="naming-property-name" |
| | | select="@naming-property" /> |
| | | |
| | | <!-- |
| | | FIXME: this does not cope with the situation where the property |
| | | is inherited, referenced, or overridden. |
| | | --> |
| | | <xsl:variable name="naming-property" |
| | | select="$managed-object/adm:property[@name=$naming-property-name]" /> |
| | | <xsl:if test="not($naming-property)"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('Relation ', ../@name, |
| | | ' references an unknown naming property ', |
| | | $naming-property-name, ' in ', |
| | | $managed-object/@name, '.')" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:if test="not($naming-property/@read-only='true')"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('Relation ', ../@name, |
| | | ' references the naming property ', |
| | | $naming-property-name, ' in ', |
| | | $managed-object/@name, ' which is not read-only. ', |
| | | 'Naming properties must be read-only.')" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:if test="not($naming-property/@mandatory='true')"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('Relation ', ../@name, |
| | | ' references the naming property ', |
| | | $naming-property-name, ' in ', |
| | | $managed-object/@name, ' which is not mandatory. ', |
| | | 'Naming properties must be mandatory.')" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | <xsl:if test="$naming-property/@multi-valued='true'"> |
| | | <xsl:message terminate="yes"> |
| | | <xsl:value-of |
| | | select="concat('Relation ', ../@name, |
| | | ' references the naming property ', |
| | | $naming-property-name, ' in ', |
| | | $managed-object/@name, ' which is multi-valued. ', |
| | | 'Naming properties must be single-valued.')" /> |
| | | </xsl:message> |
| | | </xsl:if> |
| | | </xsl:if> |
| | | <xsl:copy> |
| | | <xsl:copy-of select="@*" /> |
| | | <!-- |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="backend-id" |
| | | mandatory="true" |
| | | <adm:property name="backend-id" mandatory="true" read-only="true" |
| | | multi-valued="false"> |
| | | <adm:synopsis> |
| | | Provides a name that will be used to identify the associated backend. |
| | | Provides a name that will be used to identify the associated |
| | | backend. |
| | | </adm:synopsis> |
| | | <adm:description> |
| | | The name must be unique among all backends in the server. |
| | | </adm:description> |
| | | <adm:requires-admin-action> |
| | | <adm:other> |
| | | <adm:synopsis> |
| | | The backend ID may not be altered after the backend is created in |
| | | the server. |
| | | </adm:synopsis> |
| | | </adm:other> |
| | | </adm:requires-admin-action> |
| | | <adm:syntax> |
| | | <adm:string /> |
| | | </adm:syntax> |
| | |
| | | </ldap:object-class> |
| | | </adm:profile> |
| | | <adm:relation name="je-index"> |
| | | <adm:one-to-many /> |
| | | <adm:one-to-many naming-property="index-attribute"/> |
| | | <adm:profile name="ldap"> |
| | | <ldap:rdn-sequence> |
| | | cn=Index |
| | | </ldap:rdn-sequence> |
| | | <ldap:naming-attribute> |
| | | ds-cfg-index-attribute |
| | | </ldap:naming-attribute> |
| | | </adm:profile> |
| | | <adm:profile name="cli"> |
| | | <cli:relation> |
| | |
| | | </adm:profile> |
| | | </adm:relation> |
| | | <adm:relation name="backend"> |
| | | <adm:one-to-many /> |
| | | <adm:one-to-many naming-property="backend-id"/> |
| | | <adm:profile name="ldap"> |
| | | <ldap:rdn-sequence>cn=Backends,cn=config</ldap:rdn-sequence> |
| | | <ldap:naming-attribute>ds-cfg-backend-id</ldap:naming-attribute> |
| | | </adm:profile> |
| | | <adm:profile name="cli"> |
| | | <cli:relation> |
| | |
| | | |
| | | package org.opends.server.admin; |
| | | |
| | | |
| | | |
| | | import java.util.Locale; |
| | | |
| | | |
| | |
| | | <C extends ConfigurationClient, S extends Configuration> |
| | | extends RelationDefinition<C, S> { |
| | | |
| | | // The optional naming property definition. |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | // The plural name of the relation. |
| | | private final String pluralName; |
| | | |
| | |
| | | * The plural name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | * @param namingPropertyDefinition |
| | | * The property of the child managed object definition |
| | | * which should be used for naming, or <code>null</code> |
| | | * if this relation does not use a property for naming. |
| | | */ |
| | | public InstantiableRelationDefinition( |
| | | AbstractManagedObjectDefinition<?, ?> pd, String name, String pluralName, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | AbstractManagedObjectDefinition<C, S> cd, |
| | | PropertyDefinition<?> namingPropertyDefinition) { |
| | | super(pd, name, cd); |
| | | this.pluralName = pluralName; |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitInstantiable(this, p); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the property of the child managed object definition which |
| | | * should be used for naming children. |
| | | * |
| | | * @return Returns the property of the child managed object |
| | | * definition which should be used for naming, or |
| | | * <code>null</code> if this relation does not use a |
| | | * property for naming. |
| | | */ |
| | | public final PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | return namingPropertyDefinition; |
| | | } |
| | | |
| | | |
| | |
| | | * definition in the specified locale. |
| | | */ |
| | | public final String getUserFriendlyPluralName(Locale locale) { |
| | | String property = "relation." + getName() |
| | | + ".user-friendly-plural-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance() |
| | | .getMessage(getParentDefinition(), property, locale); |
| | | String property = "relation." + getName() + ".user-friendly-plural-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage( |
| | | getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | |
| | |
| | | builder.append(getParentDefinition().getName()); |
| | | builder.append(" child="); |
| | | builder.append(getChildDefinition().getName()); |
| | | builder.append(" child="); |
| | | builder.append(getChildDefinition().getName()); |
| | | builder.append(" minOccurs=0"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitInstantiable(this, p); |
| | | } |
| | | } |
| | |
| | | * if the property definition is not handled by this LDAP |
| | | * profile wrapper. |
| | | */ |
| | | public String getAttributeName(ManagedObjectDefinition<?, ?> d, |
| | | public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, |
| | | PropertyDefinition<?> pd) { |
| | | return null; |
| | | } |
| | |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public String getAttributeName(ManagedObjectDefinition<?, ?> d, |
| | | public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, |
| | | PropertyDefinition<?> pd) throws MissingResourceException { |
| | | for (Wrapper profile : profiles) { |
| | | String attributeName = profile.getAttributeName(d, pd); |
| | |
| | | */ |
| | | public String getInstantiableRelationChildRDNType( |
| | | InstantiableRelationDefinition<?, ?> r) throws MissingResourceException { |
| | | for (Wrapper profile : profiles) { |
| | | String rdnType = profile.getInstantiableRelationChildRDNType(r); |
| | | if (rdnType != null) { |
| | | return rdnType; |
| | | if (r.getNamingPropertyDefinition() != null) { |
| | | // Use the attribute associated with the naming property. |
| | | return getAttributeName(r.getChildDefinition(), r |
| | | .getNamingPropertyDefinition()); |
| | | } else { |
| | | for (Wrapper profile : profiles) { |
| | | String rdnType = profile.getInstantiableRelationChildRDNType(r); |
| | | if (rdnType != null) { |
| | | return rdnType; |
| | | } |
| | | } |
| | | return resource.getString(r.getParentDefinition(), "naming-attribute." |
| | | + r.getName()); |
| | | } |
| | | return resource.getString(r.getParentDefinition(), "naming-attribute." |
| | | + r.getName()); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new managed object path which has the same structure as |
| | | * this path except that the final path element is renamed. The |
| | | * final path element must comprise of an instantiable relation. |
| | | * |
| | | * @param newName |
| | | * The new name of the final path element. |
| | | * @return Returns a new managed object path which has the same |
| | | * structure as this path except that the final path element |
| | | * is renamed. |
| | | * @throws IllegalStateException |
| | | * If this managed object path is empty or if its final |
| | | * path element does not comprise of an instantiable |
| | | * relation. |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public ManagedObjectPath<C, S> rename(String newName) |
| | | throws IllegalStateException { |
| | | if (elements.size() == 0) { |
| | | throw new IllegalStateException("Cannot rename an empty path"); |
| | | } |
| | | |
| | | if (r instanceof InstantiableRelationDefinition) { |
| | | InstantiableRelationDefinition<? super C, ? super S> ir = |
| | | (InstantiableRelationDefinition<? super C, ? super S>) r; |
| | | return parent().child(ir, d, newName); |
| | | } else { |
| | | throw new IllegalStateException("Not an instantiable relation"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Serialize this managed object path using the provided |
| | | * serialization strategy. |
| | | * <p> |
| 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.client; |
| | | |
| | | |
| | | |
| | | import org.opends.server.admin.IllegalPropertyValueStringException; |
| | | import org.opends.server.admin.OperationsException; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyDefinitionUsageBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Thrown when an attempt is made to create a new managed object with |
| | | * an illegal name. |
| | | * <p> |
| | | * This exception can occur when a new managed object is given a name |
| | | * which is either an empty string, a string containing just |
| | | * white-spaces, or a string which is invalid according to the managed |
| | | * object's naming property (if it has one). |
| | | */ |
| | | public class IllegalManagedObjectNameException extends OperationsException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 7491748228684293291L; |
| | | |
| | | // The illegal name. |
| | | private final String illegalName; |
| | | |
| | | // The naming property definition if applicable. |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create a new illegal name exception and no naming property |
| | | * definition. |
| | | * |
| | | * @param illegalName |
| | | * The illegal managed object name. |
| | | */ |
| | | public IllegalManagedObjectNameException(String illegalName) { |
| | | this(illegalName, null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create a new illegal name exception and a naming property |
| | | * definition. |
| | | * |
| | | * @param illegalName |
| | | * The illegal managed object name. |
| | | * @param namingPropertyDefinition |
| | | * The naming property definition. |
| | | */ |
| | | public IllegalManagedObjectNameException(String illegalName, |
| | | PropertyDefinition<?> namingPropertyDefinition) { |
| | | this.illegalName = illegalName; |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the illegal managed object name. |
| | | * |
| | | * @return Returns the illegal managed object name. |
| | | */ |
| | | public String getIllegalName() { |
| | | return illegalName; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the naming property definition if applicable. |
| | | * |
| | | * @return Returns naming property definition, or <code>null</code> |
| | | * if none was specified. |
| | | */ |
| | | public PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | return namingPropertyDefinition; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getMessage() { |
| | | if (illegalName.length() == 0) { |
| | | return "Empty managed object names are not permitted"; |
| | | } else if (illegalName.trim().length() == 0) { |
| | | return "Blank managed object names are not permitted"; |
| | | } else if (namingPropertyDefinition != null) { |
| | | try { |
| | | namingPropertyDefinition.decodeValue(illegalName); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | String msg = "The managed object name \"%s\" is not a valid value " |
| | | + "for the naming property \"%s\", which must have the following " |
| | | + "syntax: %s"; |
| | | PropertyDefinitionUsageBuilder builder = |
| | | new PropertyDefinitionUsageBuilder(true); |
| | | return String.format(msg, illegalName, namingPropertyDefinition |
| | | .getName(), builder.getUsage(namingPropertyDefinition)); |
| | | } |
| | | } |
| | | |
| | | return "The managed object name \"" + illegalName + "\" is not permitted"; |
| | | } |
| | | |
| | | } |
| | |
| | | * values. |
| | | * @return Returns a new child managed object bound to the specified |
| | | * instantiable relation. |
| | | * @throws IllegalManagedObjectNameException |
| | | * If the name of the child managed object is invalid. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | |
| | | <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild( |
| | | InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d, |
| | | String name, Collection<DefaultBehaviorException> exceptions) |
| | | throws IllegalArgumentException; |
| | | throws IllegalManagedObjectNameException, IllegalArgumentException; |
| | | |
| | | |
| | | |
| | |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.IllegalManagedObjectNameException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagedObjectDecodingException; |
| | | import org.opends.server.admin.client.MissingMandatoryPropertiesException; |
| | |
| | | static ManagedObject<RootCfgClient> getRootManagedObject( |
| | | LDAPManagementContext context) { |
| | | return new LDAPManagedObject<RootCfgClient>(context, RootCfgDefn |
| | | .getInstance(), ManagedObjectPath.emptyPath(), new PropertySet(), true); |
| | | .getInstance(), ManagedObjectPath.emptyPath(), new PropertySet(), true, |
| | | null); |
| | | } |
| | | |
| | | |
| | |
| | | // committed). |
| | | private boolean existsOnServer; |
| | | |
| | | // Optional naming property definition. |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | // The path associated with this managed object. |
| | | private final ManagedObjectPath<?, ?> path; |
| | | private ManagedObjectPath<?, ?> path; |
| | | |
| | | // The managed object's properties. |
| | | private final PropertySet properties; |
| | |
| | | // Create an new LDAP managed object with the provided JNDI context. |
| | | private LDAPManagedObject(LDAPManagementContext context, |
| | | ManagedObjectDefinition<C, ?> d, ManagedObjectPath path, |
| | | PropertySet properties, boolean existsOnServer) { |
| | | PropertySet properties, boolean existsOnServer, |
| | | PropertyDefinition<?> namingPropertyDefinition) { |
| | | this.definition = d; |
| | | this.context = context; |
| | | this.path = path; |
| | | this.properties = properties; |
| | | this.existsOnServer = existsOnServer; |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | } |
| | | |
| | | |
| | |
| | | ManagedObject<N> createChild( |
| | | InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d, |
| | | String name, Collection<DefaultBehaviorException> exceptions) |
| | | throws IllegalArgumentException { |
| | | throws IllegalManagedObjectNameException, IllegalArgumentException { |
| | | validateRelationDefinition(r); |
| | | |
| | | // Empty names are not allowed. |
| | | if (name.trim().length() == 0) { |
| | | throw new IllegalManagedObjectNameException(name); |
| | | } |
| | | |
| | | // If the relation uses a naming property definition then it must |
| | | // be a valid value. |
| | | PropertyDefinition<?> pd = r.getNamingPropertyDefinition(); |
| | | if (pd != null) { |
| | | try { |
| | | pd.decodeValue(name); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | throw new IllegalManagedObjectNameException(name, pd); |
| | | } |
| | | } |
| | | |
| | | ManagedObjectPath childPath = path.child(r, name); |
| | | return createNewManagedObject(d, childPath, exceptions); |
| | | return createNewManagedObject(d, childPath, pd, name, exceptions); |
| | | } |
| | | |
| | | |
| | |
| | | throws IllegalArgumentException { |
| | | validateRelationDefinition(r); |
| | | ManagedObjectPath childPath = path.child(r); |
| | | return createNewManagedObject(d, childPath, exceptions); |
| | | return createNewManagedObject(d, childPath, null, null, exceptions); |
| | | } |
| | | |
| | | |
| | |
| | | public <T> void setPropertyValue(PropertyDefinition<T> d, T value) |
| | | throws IllegalPropertyValueException, PropertyIsReadOnlyException, |
| | | PropertyIsMandatoryException, IllegalArgumentException { |
| | | if (d.hasOption(PropertyOption.MONITORING)) { |
| | | throw new PropertyIsReadOnlyException(d); |
| | | if (value == null) { |
| | | setPropertyValues(d, Collections.<T> emptySet()); |
| | | } else { |
| | | setPropertyValues(d, Collections.singleton(value)); |
| | | } |
| | | |
| | | if (existsOnServer && d.hasOption(PropertyOption.READ_ONLY)) { |
| | | throw new PropertyIsReadOnlyException(d); |
| | | } |
| | | |
| | | properties.setPropertyValue(d, value); |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | |
| | | properties.setPropertyValues(d, values); |
| | | |
| | | // If this is a naming property then update the name. |
| | | if (d.equals(namingPropertyDefinition)) { |
| | | // The property must be single-valued and mandatory. |
| | | String newName = d.encodeValue(values.iterator().next()); |
| | | path = path.rename(newName); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Adapts a naming exception to an appropriate admin client |
| | | // exception. |
| | | private void adaptNamingException(NamingException ne) |
| | |
| | | } |
| | | attributes.put(oc); |
| | | |
| | | // Create the naming attribute. |
| | | Rdn rdn = dn.getRdn(dn.size() - 1); |
| | | attributes.put(rdn.getType(), rdn.getValue().toString()); |
| | | // Create the naming attribute if there is not naming property. |
| | | if (namingPropertyDefinition == null) { |
| | | Rdn rdn = dn.getRdn(dn.size() - 1); |
| | | attributes.put(rdn.getType(), rdn.getValue().toString()); |
| | | } |
| | | |
| | | // Create the remaining attributes. |
| | | for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) { |
| | |
| | | ManagedObject<M> createExistingManagedObject( |
| | | ManagedObjectDefinition<M, ?> d, ManagedObjectPath p, |
| | | PropertySet properties) { |
| | | return new LDAPManagedObject<M>(context, d, p, properties, true); |
| | | RelationDefinition<?, ?> rd = p.getRelationDefinition(); |
| | | PropertyDefinition<?> pd = null; |
| | | if (rd instanceof InstantiableRelationDefinition) { |
| | | InstantiableRelationDefinition<?, ?> ird = |
| | | (InstantiableRelationDefinition) rd; |
| | | pd = ird.getNamingPropertyDefinition(); |
| | | } |
| | | return new LDAPManagedObject<M>(context, d, p, properties, true, pd); |
| | | } |
| | | |
| | | |
| | | |
| | | // Creates a new managed object with no active values, just default |
| | | // values. |
| | | private <M extends ConfigurationClient> |
| | | private <M extends ConfigurationClient, T> |
| | | ManagedObject<M> createNewManagedObject( |
| | | ManagedObjectDefinition<M, ?> d, ManagedObjectPath p, |
| | | PropertyDefinition<T> namingPropertyDefinition, String name, |
| | | Collection<DefaultBehaviorException> exceptions) { |
| | | PropertySet childProperties = new PropertySet(); |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | |
| | | } |
| | | } |
| | | |
| | | return new LDAPManagedObject<M>(context, d, p, childProperties, false); |
| | | // Set the naming property if there is one. |
| | | if (namingPropertyDefinition != null) { |
| | | T value = namingPropertyDefinition.decodeValue(name); |
| | | childProperties.setPropertyValue(namingPropertyDefinition, value); |
| | | } |
| | | |
| | | return new LDAPManagedObject<M>(context, d, p, childProperties, false, |
| | | namingPropertyDefinition); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the user |
| | | * attempts create a new managed object having a name which is |
| | | * invalid according to the managed object's naming property. This |
| | | * takes three arguments which are the illegal name, the user |
| | | * friendly name of the associated managed object, and the syntax. |
| | | */ |
| | | public static final int MSGID_DSCFG_ERROR_ILLEGAL_NAME_SYNTAX = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1204; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the user |
| | | * attempts create a new managed object having an empty name. This |
| | | * takes a single argument which is the user friendly plural name of |
| | | * the associated managed object. |
| | | */ |
| | | public static final int MSGID_DSCFG_ERROR_ILLEGAL_NAME_EMPTY = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1205; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the user |
| | | * attempts create a new managed object having a blank name. This |
| | | * takes a single argument which is the user friendly plural name of |
| | | * the associated managed object. |
| | | */ |
| | | public static final int MSGID_DSCFG_ERROR_ILLEGAL_NAME_BLANK = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1206; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the user |
| | | * attempts create a new managed object having a name which is |
| | | * invalid for an unspecified reason. This takes two arguments which |
| | | * are the illegal name and the user friendly name of the associated |
| | | * managed object. |
| | | */ |
| | | public static final int MSGID_DSCFG_ERROR_ILLEGAL_NAME_UNKNOWN = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1207; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used as the |
| | | * description of the a naming argument in create-xxx sub-commands |
| | | * which do not have a naming property. This takes a single argument |
| | | * which is the user friendly name for the type of managed objects |
| | | * being named. |
| | | */ |
| | | public static final int MSGID_DSCFG_DESCRIPTION_NAME_CREATE = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1208; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used as the |
| | | * description of the a naming argument in create-xxx sub-commands |
| | | * which do have a naming property. This takes three arguments which |
| | | * are the user friendly name for the type of managed objects being |
| | | * named, the name of the naming property, and the naming property's |
| | | * synopsis. |
| | | */ |
| | | public static final int MSGID_DSCFG_DESCRIPTION_NAME_CREATE_EXT = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1209; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the user |
| | | * attempts set a value for the naming property when creating a new |
| | | * managed object. This takes two arguments, which are the the name |
| | | * of the naming property, and the user friendly name of the type of |
| | | * managed object being created. |
| | | */ |
| | | public static final int MSGID_DSCFG_ERROR_UNABLE_TO_SET_NAMING_PROPERTY = |
| | | CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1210; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Associates a set of generic messages with the message IDs defined in this |
| | | * class. |
| | | */ |
| | |
| | | registerMessage(MSGID_DSCFG_DESCRIPTION_NAME, |
| | | "The name of the %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_DESCRIPTION_NAME_CREATE, |
| | | "The name of the new %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_DESCRIPTION_NAME_CREATE_EXT, |
| | | "The name of the new %s which will also be used as the " + |
| | | "value of the \"%s\" property: %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_DESCRIPTION_HELP_TYPE, |
| | | "The type(s) of components whose properties should be " + |
| | | "described"); |
| | |
| | | "The %s property \"%s\" is mandatory cannot be reset. " + |
| | | "Use the \"%s\" option to specify a new value"); |
| | | |
| | | registerMessage(MSGID_DSCFG_ERROR_UNABLE_TO_SET_NAMING_PROPERTY, |
| | | "The property \"%s\" cannot be set as it is defined " + |
| | | "implicitly by the name of the %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_ERROR_PROPERTY_SINGLE_VALUED, |
| | | "It is not possible to specify multiple values for the " + |
| | | "%s property \"%s\" as it is single-valued"); |
| | |
| | | "The inherited default value(s) of the %s property " + |
| | | "\"%s\" could not be determined"); |
| | | |
| | | registerMessage(MSGID_DSCFG_ERROR_ILLEGAL_NAME_EMPTY, |
| | | "Empty names are not permitted for %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_ERROR_ILLEGAL_NAME_BLANK, |
| | | "Blank names are not permitted for %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_ERROR_ILLEGAL_NAME_SYNTAX, |
| | | "The name \"%s\" is not a valid name for the %s " + |
| | | "which has the following syntax: %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_ERROR_ILLEGAL_NAME_UNKNOWN, |
| | | "The name \"%s\" is not a valid name for the %s"); |
| | | |
| | | registerMessage(MSGID_DSCFG_HEADING_MANAGED_OBJECT_NAME, |
| | | "Component"); |
| | | |
| | |
| | | import org.opends.server.admin.IllegalPropertyValueException; |
| | | import org.opends.server.admin.IllegalPropertyValueStringException; |
| | | import org.opends.server.admin.ManagedObjectDefinition; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyDefinitionUsageBuilder; |
| | | import org.opends.server.admin.PropertyException; |
| | | import org.opends.server.admin.PropertyIsMandatoryException; |
| | | import org.opends.server.admin.PropertyIsReadOnlyException; |
| | | import org.opends.server.admin.PropertyIsSingleValuedException; |
| | | import org.opends.server.admin.RelationDefinition; |
| | | import org.opends.server.admin.client.IllegalManagedObjectNameException; |
| | | import org.opends.server.admin.client.MissingMandatoryPropertiesException; |
| | | import org.opends.server.util.args.ArgumentException; |
| | | |
| | |
| | | final class ArgumentExceptionFactory { |
| | | |
| | | /** |
| | | * Creates an argument exception from an illegal managed object name |
| | | * exception. |
| | | * |
| | | * @param e |
| | | * The illegal managed object name exception. |
| | | * @param d |
| | | * The managed object definition. |
| | | * @return Returns an argument exception. |
| | | */ |
| | | public static ArgumentException adaptIllegalManagedObjectNameException( |
| | | IllegalManagedObjectNameException e, AbstractManagedObjectDefinition d) { |
| | | String illegalName = e.getIllegalName(); |
| | | PropertyDefinition<?> pd = e.getNamingPropertyDefinition(); |
| | | |
| | | if (illegalName.length() == 0) { |
| | | int msgID = MSGID_DSCFG_ERROR_ILLEGAL_NAME_EMPTY; |
| | | String message = getMessage(msgID, d.getUserFriendlyPluralName()); |
| | | return new ArgumentException(msgID, message); |
| | | } else if (illegalName.trim().length() == 0) { |
| | | int msgID = MSGID_DSCFG_ERROR_ILLEGAL_NAME_BLANK; |
| | | String message = getMessage(msgID, d.getUserFriendlyPluralName()); |
| | | return new ArgumentException(msgID, message); |
| | | } else if (pd != null) { |
| | | try { |
| | | pd.decodeValue(illegalName); |
| | | } catch (IllegalPropertyValueStringException e1) { |
| | | PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder( |
| | | true); |
| | | String syntax = b.getUsage(pd); |
| | | |
| | | int msgID = MSGID_DSCFG_ERROR_ILLEGAL_NAME_SYNTAX; |
| | | String message = getMessage(msgID, illegalName, |
| | | d.getUserFriendlyName(), pd.getName(), syntax); |
| | | return new ArgumentException(msgID, message); |
| | | } |
| | | } |
| | | |
| | | int msgID = MSGID_DSCFG_ERROR_ILLEGAL_NAME_UNKNOWN; |
| | | String message = getMessage(msgID, illegalName, d.getUserFriendlyName()); |
| | | return new ArgumentException(msgID, message); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates an argument exception from a missing mandatory properties |
| | | * exception. |
| | | * |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates an argument exception which should be used when an |
| | | * attempt is made to set the naming property for a managed object |
| | | * during creation. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param pd |
| | | * The naming property definition. |
| | | * @return Returns an argument exception. |
| | | */ |
| | | public static ArgumentException unableToSetNamingProperty( |
| | | AbstractManagedObjectDefinition d, PropertyDefinition<?> pd) { |
| | | int msgID = MSGID_DSCFG_ERROR_UNABLE_TO_SET_NAMING_PROPERTY; |
| | | String message = getMessage(msgID, pd.getName(), d.getUserFriendlyName()); |
| | | return new ArgumentException(msgID, message); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates an argument exception which should be used when the bind |
| | | * password could not be read from the standard input. |
| | | * |
| | |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.IllegalManagedObjectNameException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagedObjectDecodingException; |
| | | import org.opends.server.admin.client.ManagementContext; |
| | |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param namingPropertyDefinition |
| | | * The naming property definition if there is one. |
| | | * @param args |
| | | * The property value arguments. |
| | | * @throws ArgumentException |
| | | * If the property value arguments could not be parsed. |
| | | */ |
| | | public MyPropertyProvider(ManagedObjectDefinition<?, ?> d, |
| | | List<String> args) throws ArgumentException { |
| | | PropertyDefinition<?> namingPropertyDefinition, List<String> args) |
| | | throws ArgumentException { |
| | | for (String s : args) { |
| | | // Parse the property "property:value". |
| | | int sep = s.indexOf(':'); |
| | |
| | | throw ArgumentExceptionFactory.unknownProperty(d, propertyName); |
| | | } |
| | | |
| | | // Make sure that the user is not attempting to set the naming |
| | | // property. |
| | | if (pd.equals(namingPropertyDefinition)) { |
| | | throw ArgumentExceptionFactory.unableToSetNamingProperty(d, pd); |
| | | } |
| | | |
| | | // Add the value. |
| | | addPropertyValue(d, pd, value); |
| | | } |
| | |
| | | public static <C extends ConfigurationClient> CreateSubCommandHandler create( |
| | | SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p, |
| | | InstantiableRelationDefinition<C, ?> r) throws ArgumentException { |
| | | return new CreateSubCommandHandler<C>(parser, p, r, p.child(r, "DUMMY")); |
| | | return new CreateSubCommandHandler<C>(parser, p, r, r |
| | | .getNamingPropertyDefinition(), p.child(r, "DUMMY")); |
| | | } |
| | | |
| | | |
| | |
| | | public static <C extends ConfigurationClient> CreateSubCommandHandler create( |
| | | SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p, |
| | | OptionalRelationDefinition<C, ?> r) throws ArgumentException { |
| | | return new CreateSubCommandHandler<C>(parser, p, r, p.child(r)); |
| | | return new CreateSubCommandHandler<C>(parser, p, r, null, p.child(r)); |
| | | } |
| | | |
| | | // The sub-commands naming arguments. |
| | | private final List<StringArgument> namingArgs; |
| | | |
| | | // The optional naming property definition. |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | // The path of the parent managed object. |
| | | private final ManagedObjectPath<?, ?> path; |
| | | |
| | |
| | | // Common constructor. |
| | | private CreateSubCommandHandler(SubCommandArgumentParser parser, |
| | | ManagedObjectPath<?, ?> p, RelationDefinition<C, ?> r, |
| | | ManagedObjectPath<?, ?> c) throws ArgumentException { |
| | | PropertyDefinition<?> pd, ManagedObjectPath<?, ?> c) |
| | | throws ArgumentException { |
| | | this.path = p; |
| | | this.relation = r; |
| | | this.namingPropertyDefinition = pd; |
| | | |
| | | // Create the sub-command. |
| | | String name = "create-" + r.getName(); |
| | |
| | | this.types = getSubTypes(r.getChildDefinition()); |
| | | |
| | | // Create the naming arguments. |
| | | this.namingArgs = createNamingArgs(subCommand, c); |
| | | this.namingArgs = createNamingArgs(subCommand, c, true); |
| | | |
| | | // Create the --property argument which is used to specify |
| | | // property values. |
| | |
| | | |
| | | // Encode the provided properties. |
| | | List<String> propertyArgs = propertySetArgument.getValues(); |
| | | MyPropertyProvider provider = new MyPropertyProvider(d, propertyArgs); |
| | | MyPropertyProvider provider = new MyPropertyProvider(d, |
| | | namingPropertyDefinition, propertyArgs); |
| | | |
| | | // Add the child managed object. |
| | | ManagementContext context = app.getManagementContext(); |
| | |
| | | InstantiableRelationDefinition<C, ?> irelation = |
| | | (InstantiableRelationDefinition<C, ?>) relation; |
| | | String name = names.get(names.size() - 1); |
| | | child = parent.createChild(irelation, d, name, exceptions); |
| | | try { |
| | | child = parent.createChild(irelation, d, name, exceptions); |
| | | } catch (IllegalManagedObjectNameException e) { |
| | | throw ArgumentExceptionFactory |
| | | .adaptIllegalManagedObjectNameException(e, d); |
| | | } |
| | | } else { |
| | | OptionalRelationDefinition<C, ?> orelation = |
| | | (OptionalRelationDefinition<C, ?>) relation; |
| | |
| | | descriptionID, ufpn); |
| | | |
| | | // Create the naming arguments. |
| | | this.namingArgs = createNamingArgs(subCommand, c); |
| | | this.namingArgs = createNamingArgs(subCommand, c, false); |
| | | |
| | | // Create the --force argument which is used to force deletion. |
| | | this.forceArgument = new BooleanArgument(OPTION_DSCFG_LONG_FORCE, |
| | |
| | | descriptionID, r.getChildDefinition().getUserFriendlyName()); |
| | | |
| | | // Create the naming arguments. |
| | | this.namingArgs = createNamingArgs(subCommand, path); |
| | | this.namingArgs = createNamingArgs(subCommand, path, false); |
| | | |
| | | // Register common arguments. |
| | | registerPropertyNameArgument(this.subCommand); |
| | |
| | | descriptionID, rufn); |
| | | |
| | | // Create the naming arguments. |
| | | this.namingArgs = createNamingArgs(subCommand, path); |
| | | this.namingArgs = createNamingArgs(subCommand, path, false); |
| | | |
| | | // Register arguments. |
| | | registerPropertyNameArgument(this.subCommand); |
| | |
| | | descriptionID, r.getChildDefinition().getUserFriendlyName()); |
| | | |
| | | // Create the naming arguments. |
| | | this.namingArgs = createNamingArgs(subCommand, path); |
| | | this.namingArgs = createNamingArgs(subCommand, path, false); |
| | | |
| | | // Create the --set argument. |
| | | this.propertySetArgument = new StringArgument(OPTION_DSCFG_LONG_SET, |
| | |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.ManagedObjectPathSerializer; |
| | | import org.opends.server.admin.OptionalRelationDefinition; |
| | | import org.opends.server.admin.PropertyDefinition; |
| | | import org.opends.server.admin.PropertyDefinitionUsageBuilder; |
| | | import org.opends.server.admin.SingletonRelationDefinition; |
| | | import org.opends.server.admin.SizeUnit; |
| | | import org.opends.server.admin.Tag; |
| | |
| | | * The sub-command. |
| | | * @param path |
| | | * The managed object path. |
| | | * @param isCreate |
| | | * Indicates whether the sub-command is a create-xxx |
| | | * sub-command, in which case the final path element will |
| | | * have different usage information. |
| | | * @return Returns the naming arguments. |
| | | * @throws ArgumentException |
| | | * If one or more naming arguments could not be |
| | | * registered. |
| | | */ |
| | | public static List<StringArgument> create(SubCommand subCommand, |
| | | ManagedObjectPath<?, ?> path) throws ArgumentException { |
| | | NamingArgumentBuilder builder = new NamingArgumentBuilder(subCommand); |
| | | ManagedObjectPath<?, ?> path, boolean isCreate) |
| | | throws ArgumentException { |
| | | NamingArgumentBuilder builder = new NamingArgumentBuilder(subCommand, |
| | | path.size(), isCreate); |
| | | path.serialize(builder); |
| | | |
| | | if (builder.e != null) { |
| | |
| | | // The sub-command. |
| | | private final SubCommand subCommand; |
| | | |
| | | // Indicates whether the sub-command is a create-xxx |
| | | // sub-command, in which case the final path element will |
| | | // have different usage information. |
| | | private final boolean isCreate; |
| | | |
| | | // The number of path elements to expect. |
| | | private int sz; |
| | | |
| | | |
| | | /** |
| | | * Creates a new naming argument builder. |
| | | * |
| | | * @param subCommand |
| | | * Add the naming arguments to this sub-command. |
| | | */ |
| | | public NamingArgumentBuilder(SubCommand subCommand) { |
| | | |
| | | // Private constructor. |
| | | private NamingArgumentBuilder(SubCommand subCommand, int sz, |
| | | boolean isCreate) { |
| | | this.subCommand = subCommand; |
| | | this.sz = sz; |
| | | this.isCreate = isCreate; |
| | | } |
| | | |
| | | |
| | |
| | | void appendManagedObjectPathElement( |
| | | InstantiableRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d, String name) { |
| | | sz--; |
| | | |
| | | // Use the last word in the managed object name as the argument |
| | | // prefix. |
| | | StringBuilder builder = new StringBuilder(); |
| | |
| | | } |
| | | builder.append("-name"); |
| | | String argName = builder.toString(); |
| | | StringArgument arg; |
| | | |
| | | try { |
| | | StringArgument arg = new StringArgument(argName, null, argName, true, |
| | | true, "{NAME}", MSGID_DSCFG_DESCRIPTION_NAME, d |
| | | .getUserFriendlyName()); |
| | | if (isCreate && sz == 0) { |
| | | // The final path element in create-xxx sub-commands should |
| | | // have a different usage. |
| | | PropertyDefinition<?> pd = r.getNamingPropertyDefinition(); |
| | | |
| | | if (pd != null) { |
| | | // Use syntax and description from naming property. |
| | | PropertyDefinitionUsageBuilder b = |
| | | new PropertyDefinitionUsageBuilder(false); |
| | | String usage = "{" + b.getUsage(pd) + "}"; |
| | | arg = new StringArgument(argName, null, argName, true, true, usage, |
| | | MSGID_DSCFG_DESCRIPTION_NAME_CREATE_EXT, d |
| | | .getUserFriendlyName(), pd.getName(), pd.getSynopsis()); |
| | | } else { |
| | | arg = new StringArgument(argName, null, argName, true, true, |
| | | "{NAME}", MSGID_DSCFG_DESCRIPTION_NAME_CREATE, d |
| | | .getUserFriendlyName()); |
| | | } |
| | | } else { |
| | | // A normal naming argument. |
| | | arg = new StringArgument(argName, null, argName, true, true, |
| | | "{NAME}", MSGID_DSCFG_DESCRIPTION_NAME, d.getUserFriendlyName()); |
| | | } |
| | | subCommand.addArgument(arg); |
| | | arguments.add(arg); |
| | | } catch (ArgumentException e) { |
| | |
| | | void appendManagedObjectPathElement( |
| | | OptionalRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | // No implementation required. |
| | | sz--; |
| | | } |
| | | |
| | | |
| | |
| | | void appendManagedObjectPathElement( |
| | | SingletonRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | // No implementation required. |
| | | sz--; |
| | | } |
| | | |
| | | } |
| | |
| | | * The sub-command. |
| | | * @param p |
| | | * The managed object path. |
| | | * @param isCreate |
| | | * Indicates whether the sub-command is a create-xxx |
| | | * sub-command, in which case the final path element will |
| | | * have different usage information. |
| | | * @return Returns the naming arguments. |
| | | * @throws ArgumentException |
| | | * If one or more naming arguments could not be |
| | | * registered. |
| | | */ |
| | | protected final List<StringArgument> createNamingArgs(SubCommand subCommand, |
| | | ManagedObjectPath<?, ?> p) throws ArgumentException { |
| | | return NamingArgumentBuilder.create(subCommand, p); |
| | | ManagedObjectPath<?, ?> p, boolean isCreate) throws ArgumentException { |
| | | return NamingArgumentBuilder.create(subCommand, p, isCreate); |
| | | } |
| | | |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getAttributeName(ManagedObjectDefinition<?, ?> d, |
| | | public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, |
| | | PropertyDefinition<?> pd) { |
| | | if (d == TestParentCfgDefn.getInstance()) { |
| | | TestParentCfgDefn td = TestParentCfgDefn.getInstance(); |
| | |
| | | static { |
| | | RD_TEST_ONE_TO_MANY_PARENT = new InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg>( |
| | | RootCfgDefn.getInstance(), "test-one-to-many-parent", |
| | | "test-one-to-many-parents", TestParentCfgDefn.getInstance()); |
| | | "test-one-to-many-parents", TestParentCfgDefn.getInstance(), null); |
| | | } |
| | | |
| | | // Create a one-to-many relation for test-parent components. |
| | |
| | | RD_TEST_ONE_TO_ZERO_OR_ONE_PARENT = new OptionalRelationDefinition<TestParentCfgClient, TestParentCfg>( |
| | | RootCfgDefn.getInstance(), "test-one-to-zero-or-one-parent", |
| | | TestParentCfgDefn.getInstance()); |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.IllegalManagedObjectNameException; |
| | | import org.opends.server.admin.client.ManagedObjectDecodingException; |
| | | import org.opends.server.admin.client.OperationRejectedException; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | |
| | | * attempting to determine the default values of the |
| | | * Test Child. This argument can be <code>null<code>. |
| | | * @return Returns a new Test Child configuration instance. |
| | | * @throws IllegalManagedObjectNameException |
| | | * If the name is invalid. |
| | | */ |
| | | <C extends TestChildCfgClient> C createTestChild( |
| | | ManagedObjectDefinition<C, ?> d, String name, Collection<DefaultBehaviorException> exceptions); |
| | | ManagedObjectDefinition<C, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException; |
| | | |
| | | |
| | | |
| | |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.IllegalManagedObjectNameException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagedObjectDecodingException; |
| | | import org.opends.server.admin.client.MissingMandatoryPropertiesException; |
| | |
| | | // Build the "test-children" relation definition. |
| | | static { |
| | | RD_TEST_CHILDREN = new InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg>( |
| | | INSTANCE, "multiple-children", "test-children", TestChildCfgDefn.getInstance()); |
| | | INSTANCE, "multiple-children", "test-children", TestChildCfgDefn.getInstance(), null); |
| | | INSTANCE.registerRelationDefinition(RD_TEST_CHILDREN); |
| | | } |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public <M extends TestChildCfgClient> M createTestChild( |
| | | ManagedObjectDefinition<M, ?> d, String name, Collection<DefaultBehaviorException> exceptions) { |
| | | ManagedObjectDefinition<M, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException { |
| | | return impl.createChild(INSTANCE.getTestChildrenRelationDefinition(), d, name, exceptions).getConfiguration(); |
| | | } |
| | | |
| | |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ConcurrentModificationException; |
| | | import org.opends.server.admin.client.IllegalManagedObjectNameException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagedObjectDecodingException; |
| | | import org.opends.server.admin.client.ManagementContext; |
| | |
| | | String name) throws ManagedObjectDecodingException, |
| | | AuthorizationException, ManagedObjectAlreadyExistsException, |
| | | ConcurrentModificationException, OperationRejectedException, |
| | | CommunicationException { |
| | | CommunicationException, IllegalManagedObjectNameException { |
| | | ManagedObject<RootCfgClient> root = context |
| | | .getRootConfigurationManagedObject(); |
| | | return root.createChild(TestCfg.getTestOneToManyParentRelationDefinition(), |