| | |
| | | */ |
| | | |
| | | package org.opends.server.admin; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | | import static org.opends.server.util.Validator.*; |
| | | import static com.forgerock.opendj.util.Validator.*; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.Locale; |
| | | import java.util.MissingResourceException; |
| | | import java.util.Set; |
| | | |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Relation definitions define relationships between types of managed |
| | | * objects. In addition they define the ownership model: |
| | | * Relation definitions define relationships between types of managed objects. |
| | | * In addition they define the ownership model: |
| | | * <ul> |
| | | * <li>composition - referenced managed objects are owned by the |
| | | * parent managed object and are deleted when the parent is deleted |
| | | * <li>aggregation - referenced managed objects are not owned by the |
| | | * parent managed object. Instead they are shared by other managed |
| | | * objects. |
| | | * <li>composition - referenced managed objects are owned by the parent managed |
| | | * object and are deleted when the parent is deleted |
| | | * <li>aggregation - referenced managed objects are not owned by the parent |
| | | * managed object. Instead they are shared by other managed objects. |
| | | * </ul> |
| | | * Relations define how clients interact with the configuration. For |
| | | * example, clients manage aggregated managed objects in a shared |
| | | * location and attach them to parent managed objects. Composed |
| | | * managed objects, on the other hand, would be created directly |
| | | * beneath the parent managed object and destroyed with it too. |
| | | * Relations define how clients interact with the configuration. For example, |
| | | * clients manage aggregated managed objects in a shared location and attach |
| | | * them to parent managed objects. Composed managed objects, on the other hand, |
| | | * would be created directly beneath the parent managed object and destroyed |
| | | * with it too. |
| | | * <p> |
| | | * Within the server, listeners can choose to request notification of |
| | | * managed objects being added or removed from relations. |
| | | * Within the server, listeners can choose to request notification of managed |
| | | * objects being added or removed from relations. |
| | | * <p> |
| | | * In LDAP, compositions are represented as follows: |
| | | * <ul> |
| | | * <li>singleton relations (one to one): a referenced managed object |
| | | * is represented using a child entry directly beneath the parent |
| | | * <li>optional relations (one to zero or one): a referenced managed |
| | | * object is represented using a child entry directly beneath the |
| | | * parent |
| | | * <li>instantiable relations (one to many): the relation is |
| | | * represented using a child entry directly beneath the parent. |
| | | * Referenced managed objects are represented using child entries of |
| | | * this "relation entry" and are named by the user |
| | | * <li>set relations (one to many): the relation is |
| | | * represented using a child entry directly beneath the parent. |
| | | * Referenced managed objects are represented using child entries of |
| | | * this "relation entry" whose name is the type of the managed object. |
| | | * </ul> |
| | | * Whereas, aggregations are represented by storing the DNs of the |
| | | * referenced managed objects in an attribute of the aggregating |
| | | * <li>singleton relations (one to one): a referenced managed object is |
| | | * represented using a child entry directly beneath the parent |
| | | * <li>optional relations (one to zero or one): a referenced managed object is |
| | | * represented using a child entry directly beneath the parent |
| | | * <li>instantiable relations (one to many): the relation is represented using a |
| | | * child entry directly beneath the parent. Referenced managed objects are |
| | | * represented using child entries of this "relation entry" and are named by the |
| | | * user |
| | | * <li>set relations (one to many): the relation is represented using a child |
| | | * entry directly beneath the parent. Referenced managed objects are represented |
| | | * using child entries of this "relation entry" whose name is the type of the |
| | | * managed object. |
| | | * </ul> |
| | | * Whereas, aggregations are represented by storing the DNs of the referenced |
| | | * managed objects in an attribute of the aggregating managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * The type of client managed object configuration that this relation |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | * The type of server managed object configuration that this relation |
| | | * definition refers to. |
| | | */ |
| | | public abstract class RelationDefinition |
| | | <C extends ConfigurationClient, S extends Configuration> { |
| | | public abstract class RelationDefinition<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing relation definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this relation definition refers to. |
| | | * @param <D> |
| | | * The type of relation definition constructed by this |
| | | * builder. |
| | | */ |
| | | protected abstract static class AbstractBuilder |
| | | <C extends ConfigurationClient, S extends Configuration, |
| | | D extends RelationDefinition<C, S>> { |
| | | /** |
| | | * An interface for incrementally constructing relation definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <D> |
| | | * The type of relation definition constructed by this builder. |
| | | */ |
| | | protected abstract static class AbstractBuilder<C extends ConfigurationClient, S extends Configuration, D extends RelationDefinition<C, S>> { |
| | | |
| | | // Common fields. |
| | | private final Common<C, S> common; |
| | | |
| | | /** |
| | | * Create a property definition builder. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> pd, String name, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | this.common = new Common<C, S>(pd, name, cd); |
| | | } |
| | | |
| | | /** |
| | | * Construct a relation definition based on the properties of this |
| | | * builder. |
| | | * |
| | | * @return The new relation definition. |
| | | */ |
| | | public final D getInstance() { |
| | | return buildInstance(common); |
| | | } |
| | | |
| | | /** |
| | | * Add a relation definition option. |
| | | * |
| | | * @param option |
| | | * The relation option. |
| | | */ |
| | | public final void setOption(RelationOption option) { |
| | | ensureNotNull(option); |
| | | common.options.add(option); |
| | | } |
| | | |
| | | /** |
| | | * Build a relation definition based on the properties of this builder. |
| | | * |
| | | * @param common |
| | | * The common fields of the new relation definition. |
| | | * @return The new relation definition. |
| | | */ |
| | | protected abstract D buildInstance(Common<C, S> common); |
| | | } |
| | | |
| | | /** |
| | | * Opaque structure containing fields common to all relation definition |
| | | * types. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | */ |
| | | protected static final class Common<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | // The definition of the child managed object. |
| | | private final AbstractManagedObjectDefinition<C, S> cd; |
| | | |
| | | // The name of the relation. |
| | | private final String name; |
| | | |
| | | // Options applicable to this definition. |
| | | private final Set<RelationOption> options; |
| | | |
| | | // The definition of the parent managed object. |
| | | private final AbstractManagedObjectDefinition<?, ?> pd; |
| | | |
| | | // Private constructor. |
| | | private Common(AbstractManagedObjectDefinition<?, ?> pd, String name, AbstractManagedObjectDefinition<C, S> cd) { |
| | | this.name = name; |
| | | this.pd = pd; |
| | | this.cd = cd; |
| | | this.options = EnumSet.noneOf(RelationOption.class); |
| | | } |
| | | } |
| | | |
| | | // Common fields. |
| | | private final Common<C, S> common; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create a property definition builder. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> pd, |
| | | String name, AbstractManagedObjectDefinition<C, S> cd) { |
| | | this.common = new Common<C, S>(pd, name, cd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Construct a relation definition based on the properties of this |
| | | * builder. |
| | | * |
| | | * @return The new relation definition. |
| | | */ |
| | | public final D getInstance() { |
| | | return buildInstance(common); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Add a relation definition option. |
| | | * |
| | | * @param option |
| | | * The relation option. |
| | | */ |
| | | public final void setOption(RelationOption option) { |
| | | ensureNotNull(option); |
| | | common.options.add(option); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Build a relation definition based on the properties of this |
| | | * builder. |
| | | * Create a new managed object relation definition with the specified common |
| | | * fields. |
| | | * |
| | | * @param common |
| | | * The common fields of the new relation definition. |
| | | * @return The new relation definition. |
| | | * The common fields of the new relation definition. |
| | | */ |
| | | protected abstract D buildInstance(Common<C, S> common); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Opaque structure containing fields common to all relation |
| | | * definition types. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that |
| | | * this relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that |
| | | * this relation definition refers to. |
| | | */ |
| | | protected static final class Common |
| | | <C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | // The definition of the child managed object. |
| | | private final AbstractManagedObjectDefinition<C, S> cd; |
| | | |
| | | // The name of the relation. |
| | | private final String name; |
| | | |
| | | // Options applicable to this definition. |
| | | private final Set<RelationOption> options; |
| | | |
| | | // The definition of the parent managed object. |
| | | private final AbstractManagedObjectDefinition<?, ?> pd; |
| | | |
| | | |
| | | |
| | | // Private constructor. |
| | | private Common(AbstractManagedObjectDefinition<?, ?> pd, String name, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | this.name = name; |
| | | this.pd = pd; |
| | | this.cd = cd; |
| | | this.options = EnumSet.noneOf(RelationOption.class); |
| | | protected RelationDefinition(Common<C, S> common) { |
| | | this.common = common; |
| | | } |
| | | } |
| | | |
| | | // Common fields. |
| | | private final Common<C, S> common; |
| | | /** |
| | | * Apply a visitor to this relation definition. |
| | | * |
| | | * @param <R> |
| | | * The return type of the visitor's methods. |
| | | * @param <P> |
| | | * The type of the additional parameters to the visitor's |
| | | * methods. |
| | | * @param v |
| | | * The relation definition visitor. |
| | | * @param p |
| | | * Optional additional visitor parameter. |
| | | * @return Returns a result as specified by the visitor. |
| | | */ |
| | | public abstract <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create a new managed object relation definition with the |
| | | * specified common fields. |
| | | * |
| | | * @param common |
| | | * The common fields of the new relation definition. |
| | | */ |
| | | protected RelationDefinition(Common<C, S> common) { |
| | | this.common = common; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Apply a visitor to this relation definition. |
| | | * |
| | | * @param <R> |
| | | * The return type of the visitor's methods. |
| | | * @param <P> |
| | | * The type of the additional parameters to the visitor's |
| | | * methods. |
| | | * @param v |
| | | * The relation definition visitor. |
| | | * @param p |
| | | * Optional additional visitor parameter. |
| | | * @return Returns a result as specified by the visitor. |
| | | */ |
| | | public abstract <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get the definition of the child managed object. |
| | | * |
| | | * @return Returns the definition of the child managed object. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<C, S> getChildDefinition() { |
| | | return common.cd; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the optional description of this relation definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the description of this relation definition in |
| | | * the default locale, or <code>null</code> if there is no |
| | | * description. |
| | | */ |
| | | public final Message getDescription() { |
| | | return getDescription(Locale.getDefault()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the optional description of this relation definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the description of this relation definition in |
| | | * the specified locale, or <code>null</code> if there is |
| | | * no description. |
| | | */ |
| | | public final Message getDescription(Locale locale) { |
| | | try { |
| | | String property = "relation." + common.name + ".description"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage( |
| | | getParentDefinition(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | /** |
| | | * Get the definition of the child managed object. |
| | | * |
| | | * @return Returns the definition of the child managed object. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<C, S> getChildDefinition() { |
| | | return common.cd; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this relation definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the description of this relation definition in the |
| | | * default locale, or <code>null</code> if there is no description. |
| | | */ |
| | | public final LocalizableMessage getDescription() { |
| | | return getDescription(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this relation definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the description of this relation definition in the |
| | | * specified locale, or <code>null</code> if there is no |
| | | * description. |
| | | */ |
| | | public final LocalizableMessage getDescription(Locale locale) { |
| | | try { |
| | | String property = "relation." + common.name + ".description"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance() |
| | | .getMessage(getParentDefinition(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the relation. |
| | | * |
| | | * @return Returns the name of the relation. |
| | | */ |
| | | public final String getName() { |
| | | return common.name; |
| | | } |
| | | /** |
| | | * Get the name of the relation. |
| | | * |
| | | * @return Returns the name of the relation. |
| | | */ |
| | | public final String getName() { |
| | | return common.name; |
| | | } |
| | | |
| | | /** |
| | | * Get the definition of the parent managed object. |
| | | * |
| | | * @return Returns the definition of the parent managed object. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<?, ?> getParentDefinition() { |
| | | return common.pd; |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this relation definition in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this relation definition in the default |
| | | * locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Get the definition of the parent managed object. |
| | | * |
| | | * @return Returns the definition of the parent managed object. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<?, ?> getParentDefinition() { |
| | | return common.pd; |
| | | } |
| | | /** |
| | | * Gets the synopsis of this relation definition in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this relation definition in the specified |
| | | * locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | String property = "relation." + common.name + ".synopsis"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of this relation definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the user friendly name of this relation definition in the |
| | | * default locale. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyName() { |
| | | return getUserFriendlyName(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of this relation definition in the specified |
| | | * locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly name of this relation definition in the |
| | | * specified locale. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyName(Locale locale) { |
| | | String property = "relation." + common.name + ".user-friendly-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this relation definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the synopsis of this relation definition in the |
| | | * default locale. |
| | | */ |
| | | public final Message getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | /** |
| | | * Check if the specified option is set for this relation definition. |
| | | * |
| | | * @param option |
| | | * The option to test. |
| | | * @return Returns <code>true</code> if the option is set, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public final boolean hasOption(RelationOption option) { |
| | | return common.options.contains(option); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | toString(builder); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Append a string representation of the managed object relation to the |
| | | * provided string builder. |
| | | * |
| | | * @param builder |
| | | * The string builder where the string representation should be |
| | | * appended. |
| | | */ |
| | | public abstract void toString(StringBuilder builder); |
| | | |
| | | /** |
| | | * Gets the synopsis of this relation definition in the specified |
| | | * locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this relation definition in the |
| | | * specified locale. |
| | | */ |
| | | public final Message getSynopsis(Locale locale) { |
| | | String property = "relation." + common.name + ".synopsis"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage( |
| | | getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the user friendly name of this relation definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the user friendly name of this relation |
| | | * definition in the default locale. |
| | | */ |
| | | public final Message getUserFriendlyName() { |
| | | return getUserFriendlyName(Locale.getDefault()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the user friendly name of this relation definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly name of this relation |
| | | * definition in the specified locale. |
| | | */ |
| | | public final Message getUserFriendlyName(Locale locale) { |
| | | String property = "relation." + common.name + ".user-friendly-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage( |
| | | getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Check if the specified option is set for this relation |
| | | * definition. |
| | | * |
| | | * @param option |
| | | * The option to test. |
| | | * @return Returns <code>true</code> if the option is set, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public final boolean hasOption(RelationOption option) { |
| | | return common.options.contains(option); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | toString(builder); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Append a string representation of the managed object relation to |
| | | * the provided string builder. |
| | | * |
| | | * @param builder |
| | | * The string builder where the string representation |
| | | * 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. |
| | | } |
| | | /** |
| | | * 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. |
| | | } |
| | | } |