/*
|
* 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 org.opends.messages.Message;
|
|
|
|
import static org.opends.server.util.Validator.*;
|
|
import java.util.EnumSet;
|
import java.util.Locale;
|
import java.util.MissingResourceException;
|
import java.util.Set;
|
|
|
|
/**
|
* 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.
|
* </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.
|
* <p>
|
* 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".
|
* </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.
|
* @param <S>
|
* The type of server managed object configuration that this
|
* relation definition refers to.
|
*/
|
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>> {
|
|
// 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 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 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 Message getSynopsis() {
|
return getSynopsis(Locale.getDefault());
|
}
|
|
|
|
/**
|
* 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);
|
}
|