/*
* 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
*
*
* Copyright 2007-2010 Sun Microsystems, Inc.
*/
package org.opends.server.admin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.Vector;
import org.opends.messages.Message;
import org.opends.server.admin.DefinitionDecodingException.Reason;
/**
* Defines the structure of an abstract managed object. Abstract managed objects
* cannot be instantiated.
* <p>
* Applications can query a managed object definition in order to determine the
* overall configuration model of an application.
*
* @param <C>
* The type of client managed object configuration that this definition
* represents.
* @param <S>
* The type of server managed object configuration that this definition
* represents.
*/
public abstract class AbstractManagedObjectDefinition
<C extends ConfigurationClient, S extends Configuration> {
// The name of the definition.
private final String name;
// The parent managed object definition if applicable.
private final AbstractManagedObjectDefinition<? super C, ? super S> parent;
// The set of constraints associated with this managed object
// definition.
private final Collection<Constraint> constraints;
// The set of property definitions applicable to this managed object
// definition.
private final Map<String, PropertyDefinition<?>> propertyDefinitions;
// The set of relation definitions applicable to this managed object
// definition.
private final Map<String, RelationDefinition<?, ?>> relationDefinitions;
// The set of relation definitions directly referencing this managed
// object definition.
private final Set<RelationDefinition<C, S>> reverseRelationDefinitions;
// The set of all property definitions associated with this managed
// object definition including inherited property definitions.
private final Map<String, PropertyDefinition<?>> allPropertyDefinitions;
// The set of all relation definitions associated with this managed
// object definition including inherited relation definitions.
private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions;
// The set of aggregation property definitions applicable to this
// managed object definition.
private final Map<String, AggregationPropertyDefinition<?, ?>>
aggregationPropertyDefinitions;
// The set of aggregation property definitions directly referencing this
// managed object definition.
private final Vector<AggregationPropertyDefinition<?, ?>>
reverseAggregationPropertyDefinitions;
// The set of all aggregation property definitions associated with this
// managed object definition including inherited relation definitions.
private final Map<String, AggregationPropertyDefinition<?, ?>>
allAggregationPropertyDefinitions;
// The set of tags associated with this managed object.
private final Set<Tag> allTags;
// Options applicable to this definition.
private final Set<ManagedObjectOption> options;
// The set of managed object definitions which inherit from this definition.
private final Map<String,
AbstractManagedObjectDefinition<? extends C, ? extends S>> children;
/**
* Create a new abstract managed object definition.
*
* @param name
* The name of the definition.
* @param parent
* The parent definition, or <code>null</code> if there
* is no parent (only the {@link TopCfgDefn} should have a
* <code>null</code> parent, unless the definition is
* being used for testing).
*/
protected AbstractManagedObjectDefinition(String name,
AbstractManagedObjectDefinition<? super C, ? super S> parent) {
this.name = name;
this.parent = parent;
this.constraints = new LinkedList<Constraint>();
this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
this.relationDefinitions = new HashMap<String, RelationDefinition<?,?>>();
this.reverseRelationDefinitions = new HashSet<RelationDefinition<C,S>>();
this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
this.allRelationDefinitions =
new HashMap<String, RelationDefinition<?, ?>>();
this.aggregationPropertyDefinitions =
new HashMap<String, AggregationPropertyDefinition<?,?>>();
this.reverseAggregationPropertyDefinitions =
new Vector<AggregationPropertyDefinition<?,?>>();
this.allAggregationPropertyDefinitions =
new HashMap<String, AggregationPropertyDefinition<?, ?>>();
this.allTags = new HashSet<Tag>();
this.options = EnumSet.noneOf(ManagedObjectOption.class);
this.children = new HashMap<String,
AbstractManagedObjectDefinition<? extends C, ? extends S>>();
// If we have a parent definition then inherit its features.
if (parent != null) {
registerInParent();
for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) {
allPropertyDefinitions.put(pd.getName(), pd);
}
for (RelationDefinition<?, ?> rd : parent.getAllRelationDefinitions()) {
allRelationDefinitions.put(rd.getName(), rd);
}
for (AggregationPropertyDefinition<?, ?> apd :
parent.getAllAggregationPropertyDefinitions()) {
allAggregationPropertyDefinitions.put(apd.getName(), apd);
}
// Tag inheritance is performed during preprocessing.
}
}
/**
* Get all the child managed object definitions which inherit from
* this managed object definition.
*
* @return Returns an unmodifiable collection containing all the
* subordinate managed object definitions which inherit from
* this managed object definition.
*/
public final Collection<AbstractManagedObjectDefinition
<? extends C, ? extends S>> getAllChildren() {
List<AbstractManagedObjectDefinition<? extends C, ? extends S>> list =
new ArrayList<AbstractManagedObjectDefinition<? extends C, ? extends S>>(
children.values());
for (AbstractManagedObjectDefinition<? extends C, ? extends S> child :
children.values()) {
list.addAll(child.getAllChildren());
}
return Collections.unmodifiableCollection(list);
}
/**
* Get all the constraints associated with this type of managed
* object. The returned collection will contain inherited
* constraints.
*
* @return Returns a collection containing all the constraints
* associated with this type of managed object. The caller
* is free to modify the collection if required.
*/
public final Collection<Constraint> getAllConstraints() {
// This method does not used a cached set of constraints because
// constraints may be updated after child definitions have been
// defined.
List<Constraint> allConstraints = new LinkedList<Constraint>();
if (parent != null) {
allConstraints.addAll(parent.getAllConstraints());
}
allConstraints.addAll(constraints);
return allConstraints;
}
/**
* Get all the property definitions associated with this type of
* managed object. The returned collection will contain inherited
* property definitions.
*
* @return Returns an unmodifiable collection containing all the
* property definitions associated with this type of managed
* object.
*/
public final Collection<PropertyDefinition<?>> getAllPropertyDefinitions() {
return Collections.unmodifiableCollection(allPropertyDefinitions.values());
}
/**
* Get all the relation definitions associated with this type of
* managed object. The returned collection will contain inherited
* relation definitions.
*
* @return Returns an unmodifiable collection containing all the
* relation definitions associated with this type of managed
* object.
*/
public final Collection<RelationDefinition<?, ?>>
getAllRelationDefinitions() {
return Collections.unmodifiableCollection(allRelationDefinitions.values());
}
/**
* Get all the relation definitions which refer to this managed
* object definition. The returned collection will contain relation
* definitions which refer to parents of this managed object
* definition.
*
* @return Returns a collection containing all the relation
* definitions which refer to this managed object
* definition. The caller is free to modify the collection
* if required.
*/
public final Collection<RelationDefinition<? super C, ? super S>>
getAllReverseRelationDefinitions() {
// This method does not used a cached set of relations because
// relations may be updated after child definitions have been
// defined.
List<RelationDefinition<? super C, ? super S>> rdlist =
new LinkedList<RelationDefinition<? super C, ? super S>>();
if (parent != null) {
rdlist.addAll(parent.getAllReverseRelationDefinitions());
}
rdlist.addAll(reverseRelationDefinitions);
return rdlist;
}
/**
* Get all the aggregation property definitions associated with this type of
* managed object. The returned collection will contain inherited
* aggregation property definitions.
*
* @return Returns an unmodifiable collection containing all the
* aggregation property definitions associated with this type of
* managed object.
*/
public final Collection<AggregationPropertyDefinition<?, ?>>
getAllAggregationPropertyDefinitions() {
return Collections.unmodifiableCollection(
allAggregationPropertyDefinitions.values());
}
/**
* Get all the aggregation property definitions which refer to this managed
* object definition. The returned collection will contain aggregation
* property definitions which refer to parents of this managed object
* definition.
*
* @return Returns a collection containing all the aggregation property
* definitions which refer to this managed object
* definition. The caller is free to modify the collection
* if required.
*/
public final Collection<AggregationPropertyDefinition<?, ?>>
getAllReverseAggregationPropertyDefinitions() {
// This method does not used a cached set of aggregation properties because
// aggregation properties may be updated after child definitions have been
// defined.
List<AggregationPropertyDefinition<?, ?>> apdlist =
new LinkedList<AggregationPropertyDefinition<?, ?>>();
if (parent != null) {
apdlist.addAll(parent.getAllReverseAggregationPropertyDefinitions());
}
apdlist.addAll(reverseAggregationPropertyDefinitions);
return apdlist;
}
/**
* Get all the tags associated with this type of managed object. The
* returned collection will contain inherited tags.
*
* @return Returns an unmodifiable collection containing all the
* tags associated with this type of managed object.
*/
public final Collection<Tag> getAllTags() {
return Collections.unmodifiableCollection(allTags);
}
/**
* Get the named child managed object definition which inherits from
* this managed object definition. This method will recursively
* search down through the inheritance hierarchy.
*
* @param name
* The name of the managed object definition sub-type.
* @return Returns the named child managed object definition which
* inherits from this managed object definition.
* @throws IllegalArgumentException
* If the specified managed object definition name was
* null or empty or if the requested subordinate managed
* object definition was not found.
*/
public final AbstractManagedObjectDefinition<? extends C, ? extends S>
getChild(String name) throws IllegalArgumentException {
if ((name == null) || (name.length() == 0)) {
throw new IllegalArgumentException("null or empty managed object name");
}
AbstractManagedObjectDefinition<? extends C, ? extends S> d = children
.get(name);
if (d == null) {
// Recursively search.
for (AbstractManagedObjectDefinition<? extends C, ? extends S> child :
children.values()) {
try {
d = child.getChild(name);
break;
} catch (IllegalArgumentException e) {
// Try the next child.
}
}
}
if (d == null) {
throw new IllegalArgumentException("child managed object definition \""
+ name + "\" not found");
}
return d;
}
/**
* Get the child managed object definitions which inherit directly
* from this managed object definition.
*
* @return Returns an unmodifiable collection containing the
* subordinate managed object definitions which inherit
* directly from this managed object definition.
*/
public final Collection<AbstractManagedObjectDefinition
<? extends C, ? extends S>> getChildren() {
return Collections.unmodifiableCollection(children.values());
}
/**
* Get the constraints defined by this managed object definition.
* The returned collection will not contain inherited constraints.
*
* @return Returns an unmodifiable collection containing the
* constraints defined by this managed object definition.
*/
public final Collection<Constraint> getConstraints() {
return Collections.unmodifiableCollection(constraints);
}
/**
* Gets the optional description of this managed object definition
* in the default locale.
*
* @return Returns the description of this managed object definition
* in the default locale, or <code>null</code> if there is
* no description.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getDescription() throws UnsupportedOperationException {
return getDescription(Locale.getDefault());
}
/**
* Gets the optional description of this managed object definition
* in the specified locale.
*
* @param locale
* The locale.
* @return Returns the description of this managed object definition
* in the specified locale, or <code>null</code> if there
* is no description.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getDescription(Locale locale)
throws UnsupportedOperationException {
try {
return ManagedObjectDefinitionI18NResource.getInstance()
.getMessage(this, "description", locale);
} catch (MissingResourceException e) {
return null;
}
}
/**
* Get the name of the definition.
*
* @return Returns the name of the definition.
*/
public final String getName() {
return name;
}
/**
* Get the parent managed object definition, if applicable.
*
* @return Returns the parent of this managed object definition, or
* <code>null</code> if this definition is the
* {@link TopCfgDefn}.
*/
public final AbstractManagedObjectDefinition<? super C,
? super S> getParent() {
return parent;
}
/**
* Get the specified property definition associated with this type
* of managed object. The search will include any inherited property
* definitions.
*
* @param name
* The name of the property definition to be retrieved.
* @return Returns the specified property definition associated with
* this type of managed object.
* @throws IllegalArgumentException
* If the specified property name was null or empty or if
* the requested property definition was not found.
*/
public final PropertyDefinition<?> getPropertyDefinition(String name)
throws IllegalArgumentException {
if ((name == null) || (name.length() == 0)) {
throw new IllegalArgumentException("null or empty property name");
}
PropertyDefinition<?> d = allPropertyDefinitions.get(name);
if (d == null) {
throw new IllegalArgumentException("property definition \"" + name
+ "\" not found");
}
return d;
}
/**
* Get the property definitions defined by this managed object
* definition. The returned collection will not contain inherited
* property definitions.
*
* @return Returns an unmodifiable collection containing the
* property definitions defined by this managed object
* definition.
*/
public final Collection<PropertyDefinition<?>> getPropertyDefinitions() {
return Collections.unmodifiableCollection(propertyDefinitions
.values());
}
/**
* Get the specified relation definition associated with this type
* of managed object.The search will include any inherited relation
* definitions.
*
* @param name
* The name of the relation definition to be retrieved.
* @return Returns the specified relation definition associated with
* this type of managed object.
* @throws IllegalArgumentException
* If the specified relation name was null or empty or if
* the requested relation definition was not found.
*/
public final RelationDefinition<?, ?> getRelationDefinition(String name)
throws IllegalArgumentException {
if ((name == null) || (name.length() == 0)) {
throw new IllegalArgumentException("null or empty relation name");
}
RelationDefinition<?, ?> d = allRelationDefinitions.get(name);
if (d == null) {
throw new IllegalArgumentException("relation definition \"" + name
+ "\" not found");
}
return d;
}
/**
* Get the relation definitions defined by this managed object
* definition. The returned collection will not contain inherited
* relation definitions.
*
* @return Returns an unmodifiable collection containing the
* relation definitions defined by this managed object
* definition.
*/
public final Collection<RelationDefinition<?,?>> getRelationDefinitions() {
return Collections.unmodifiableCollection(relationDefinitions.values());
}
/**
* Get the relation definitions which refer directly to this managed
* object definition. The returned collection will not contain
* relation definitions which refer to parents of this managed
* object definition.
*
* @return Returns an unmodifiable collection containing the
* relation definitions which refer directly to this managed
* object definition.
*/
public final Collection<RelationDefinition<C, S>>
getReverseRelationDefinitions() {
return Collections.unmodifiableCollection(reverseRelationDefinitions);
}
/**
* Get the specified aggregation property definition associated with this type
* of managed object.The search will include any inherited aggregation
* property definitions.
*
* @param name
* The name of the aggregation property definition to be retrieved.
* @return Returns the specified aggregation property definition associated
* with this type of managed object.
* @throws IllegalArgumentException
* If the specified aggregation property name was null or empty or
* if the requested aggregation property definition was not found.
*/
public final AggregationPropertyDefinition<?, ?>
getAggregationPropertyDefinition(String name)
throws IllegalArgumentException {
if ((name == null) || (name.length() == 0)) {
throw new IllegalArgumentException(
"null or empty aggregation property name");
}
AggregationPropertyDefinition<?, ?> d =
allAggregationPropertyDefinitions.get(name);
if (d == null) {
throw new IllegalArgumentException("aggregation property definition \""
+ name + "\" not found");
}
return d;
}
/**
* Get the aggregation property definitions defined by this managed object
* definition. The returned collection will not contain inherited
* aggregation property definitions.
*
* @return Returns an unmodifiable collection containing the
* aggregation property definitions defined by this managed object
* definition.
*/
public final Collection<AggregationPropertyDefinition<?, ?>>
getAggregationPropertyDefinitions() {
return Collections.unmodifiableCollection(
aggregationPropertyDefinitions.values());
}
/**
* Get the aggregation property definitions which refer directly to this
* managed object definition. The returned collection will not contain
* aggregation property definitions which refer to parents of this managed
* object definition.
*
* @return Returns an unmodifiable collection containing the
* aggregation property definitions which refer directly to this
* managed object definition.
*/
public final Collection<AggregationPropertyDefinition<?, ?>>
getReverseAggregationPropertyDefinitions() {
return Collections.unmodifiableCollection(
reverseAggregationPropertyDefinitions);
}
/**
* Gets the synopsis of this managed object definition in the
* default locale.
*
* @return Returns the synopsis of this managed object definition in
* the default locale.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getSynopsis() throws UnsupportedOperationException {
return getSynopsis(Locale.getDefault());
}
/**
* Gets the synopsis of this managed object definition in the
* specified locale.
*
* @param locale
* The locale.
* @return Returns the synopsis of this managed object definition in
* the specified locale.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getSynopsis(Locale locale)
throws UnsupportedOperationException {
return ManagedObjectDefinitionI18NResource.getInstance()
.getMessage(this, "synopsis", locale);
}
/**
* Gets the user friendly name of this managed object definition in
* the default locale.
*
* @return Returns the user friendly name of this managed object
* definition in the default locale.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getUserFriendlyName()
throws UnsupportedOperationException {
return getUserFriendlyName(Locale.getDefault());
}
/**
* Gets the user friendly name of this managed object definition in
* the specified locale.
*
* @param locale
* The locale.
* @return Returns the user friendly name of this managed object
* definition in the specified locale.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getUserFriendlyName(Locale locale)
throws UnsupportedOperationException {
// TODO: have admin framework getMessage return a Message
return Message.raw(ManagedObjectDefinitionI18NResource.getInstance()
.getMessage(this, "user-friendly-name", locale));
}
/**
* Gets the user friendly plural name of this managed object
* definition in the default locale.
*
* @return Returns the user friendly plural name of this managed
* object definition in the default locale.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getUserFriendlyPluralName()
throws UnsupportedOperationException {
return getUserFriendlyPluralName(Locale.getDefault());
}
/**
* Gets the user friendly plural name of this managed object
* definition in the specified locale.
*
* @param locale
* The locale.
* @return Returns the user friendly plural name of this managed
* object definition in the specified locale.
* @throws UnsupportedOperationException
* If this managed object definition is the
* {@link TopCfgDefn}.
*/
public final Message getUserFriendlyPluralName(Locale locale)
throws UnsupportedOperationException {
return ManagedObjectDefinitionI18NResource.getInstance()
.getMessage(this, "user-friendly-plural-name", locale);
}
/**
* Determine whether there are any child managed object definitions which
* inherit from this managed object definition.
*
* @return Returns <code>true</code> if this type of managed object has any
* child managed object definitions, <code>false</code> otherwise.
*/
public final boolean hasChildren() {
return !children.isEmpty();
}
/**
* Determines whether or not this managed object definition has the
* specified option.
*
* @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(ManagedObjectOption option) {
return options.contains(option);
}
/**
* Determines whether or not this managed object definition has the
* specified tag.
*
* @param t
* The tag definition.
* @return Returns <code>true</code> if this managed object
* definition has the specified tag.
*/
public final boolean hasTag(Tag t) {
return allTags.contains(t);
}
/**
* Determines whether or not this managed object definition is a
* sub-type of the provided managed object definition. This managed
* object definition is a sub-type of the provided managed object
* definition if they are both the same or if the provided managed
* object definition can be obtained by recursive invocations of the
* {@link #getParent()} method.
*
* @param d
* The managed object definition to be checked.
* @return Returns <code>true</code> if this managed object
* definition is a sub-type of the provided managed object
* definition.
*/
public final boolean isChildOf(AbstractManagedObjectDefinition<?, ?> d) {
AbstractManagedObjectDefinition<?, ?> i;
for (i = this; i != null; i = i.parent) {
if (i == d) {
return true;
}
}
return false;
}
/**
* Determines whether or not this managed object definition is a
* super-type of the provided managed object definition. This
* managed object definition is a super-type of the provided managed
* object definition if they are both the same or if the provided
* managed object definition is a member of the set of children
* returned from {@link #getAllChildren()}.
*
* @param d
* The managed object definition to be checked.
* @return Returns <code>true</code> if this managed object
* definition is a super-type of the provided managed object
* definition.
*/
public final boolean isParentOf(AbstractManagedObjectDefinition<?, ?> d) {
return d.isChildOf(this);
}
/**
* Determines whether or not this managed object definition is the
* {@link TopCfgDefn}.
*
* @return Returns <code>true</code> if this managed object
* definition is the {@link TopCfgDefn}.
*/
public final boolean isTop() {
return (this instanceof TopCfgDefn);
}
/**
* Finds a sub-type of this managed object definition which most closely
* corresponds to the matching criteria of the provided definition resolver.
*
* @param r
* The definition resolver.
* @return Returns the sub-type of this managed object definition which most
* closely corresponds to the matching criteria of the provided
* definition resolver.
* @throws DefinitionDecodingException
* If no matching sub-type could be found or if the resolved
* definition was abstract.
* @see DefinitionResolver
*/
@SuppressWarnings("unchecked")
public final ManagedObjectDefinition<? extends C, ? extends S>
resolveManagedObjectDefinition(
DefinitionResolver r) throws DefinitionDecodingException {
AbstractManagedObjectDefinition<? extends C, ? extends S> rd;
rd = resolveManagedObjectDefinitionAux(this, r);
if (rd == null) {
// Unable to resolve the definition.
throw new DefinitionDecodingException(this,
Reason.WRONG_TYPE_INFORMATION);
} else if (rd instanceof ManagedObjectDefinition) {
return (ManagedObjectDefinition<? extends C, ? extends S>) rd;
} else {
// Resolved definition was abstract.
throw new DefinitionDecodingException(this,
Reason.ABSTRACT_TYPE_INFORMATION);
}
}
/**
* {@inheritDoc}
*/
@Override
public final String toString() {
StringBuilder builder = new StringBuilder();
toString(builder);
return builder.toString();
}
/**
* Append a string representation of the managed object definition to the
* provided string builder.
*
* @param builder
* The string builder where the string representation should be
* appended.
*/
public final void toString(StringBuilder builder) {
builder.append(getName());
}
/**
* Initializes all of the components associated with this managed
* object definition.
*
* @throws Exception
* If this managed object definition could not be
* initialized.
*/
protected final void initialize() throws Exception {
for (PropertyDefinition<?> pd : getAllPropertyDefinitions()) {
pd.initialize();
pd.getDefaultBehaviorProvider().initialize();
}
for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) {
rd.initialize();
}
for (AggregationPropertyDefinition<?, ?> apd :
getAllAggregationPropertyDefinitions()) {
apd.initialize();
// Now register the aggregation property in the referenced managed object
// definition for reverse lookups.
registerReverseAggregationPropertyDefinition(apd);
}
for (Constraint constraint : getAllConstraints()) {
constraint.initialize();
}
}
/**
* Register a constraint with this managed object definition.
* <p>
* This method <b>must not</b> be called by applications.
*
* @param constraint
* The constraint to be registered.
*/
protected final void registerConstraint(Constraint constraint) {
constraints.add(constraint);
}
/**
* Register a property definition with this managed object definition,
* overriding any existing property definition with the same name.
* <p>
* This method <b>must not</b> be called by applications.
*
* @param d
* The property definition to be registered.
*/
protected final void registerPropertyDefinition(PropertyDefinition<?> d) {
String propName = d.getName();
propertyDefinitions.put(propName, d);
allPropertyDefinitions.put(propName, d);
if (d instanceof AggregationPropertyDefinition<?,?>) {
AggregationPropertyDefinition<?, ?> apd =
(AggregationPropertyDefinition<?, ?>) d;
aggregationPropertyDefinitions.put(propName, apd);
// The key must also contain the managed object name, since several MOs
// in an inheritance tree may aggregate the same aggregation property name
allAggregationPropertyDefinitions.put(
apd.getManagedObjectDefinition().getName() + ":" + propName, apd);
}
}
/**
* Register a relation definition with this managed object definition,
* overriding any existing relation definition with the same name.
* <p>
* This method <b>must not</b> be called by applications.
*
* @param d
* The relation definition to be registered.
*/
protected final void registerRelationDefinition(RelationDefinition<?, ?> d) {
// Register the relation in this managed object definition.
String relName = d.getName();
relationDefinitions.put(relName, d);
allRelationDefinitions.put(relName, d);
// Now register the relation in the referenced managed object
// definition for reverse lookups.
registerReverseRelationDefinition(d);
}
/**
* Register an option with this managed object definition.
* <p>
* This method <b>must not</b> be called by applications.
*
* @param option
* The option to be registered.
*/
protected final void registerOption(ManagedObjectOption option) {
options.add(option);
}
/**
* Register a tag with this managed object definition.
* <p>
* This method <b>must not</b> be called by applications.
*
* @param tag
* The tag to be registered.
*/
protected final void registerTag(Tag tag) {
allTags.add(tag);
}
/**
* Deregister a constraint from the managed object definition.
* <p>
* This method <b>must not</b> be called by applications and is
* only intended for internal testing.
*
* @param constraint
* The constraint to be deregistered.
*/
final void deregisterConstraint(Constraint constraint) {
if (!constraints.remove(constraint)) {
throw new RuntimeException("Failed to deregister a constraint");
}
}
/**
* Deregister a relation definition from the managed object
* definition.
* <p>
* This method <b>must not</b> be called by applications and is
* only intended for internal testing.
*
* @param d
* The relation definition to be deregistered.
*/
final void deregisterRelationDefinition(
RelationDefinition<?, ?> d) {
// Deregister the relation from this managed object definition.
String relName = d.getName();
relationDefinitions.remove(relName);
allRelationDefinitions.remove(relName);
// Now deregister the relation from the referenced managed object
// definition for reverse lookups.
d.getChildDefinition().reverseRelationDefinitions.remove(d);
}
/**
* Register this managed object definition in its parent.
* <p>
* This method <b>must not</b> be called by applications and is
* only intended for internal testing.
*/
final void registerInParent() {
if (parent != null) {
parent.children.put(name, this);
}
}
// Register a relation definition in the referenced managed object
// definition's reverse lookup table.
private <CC extends ConfigurationClient, SS extends Configuration>
void registerReverseRelationDefinition(RelationDefinition<CC, SS> rd) {
rd.getChildDefinition().reverseRelationDefinitions.add(rd);
}
// Register a aggregation property definition in the referenced managed object
// definition's reverse lookup table.
private void registerReverseAggregationPropertyDefinition(
AggregationPropertyDefinition<?, ?> apd) {
apd.getRelationDefinition().getChildDefinition().
reverseAggregationPropertyDefinitions.add(apd);
}
// Recursively descend definition hierarchy to find the best match definition.
private AbstractManagedObjectDefinition<? extends C, ? extends S>
resolveManagedObjectDefinitionAux(
AbstractManagedObjectDefinition<? extends C, ? extends S> d,
DefinitionResolver r) {
if (!r.matches(d)) {
return null;
}
for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : d
.getChildren()) {
AbstractManagedObjectDefinition<? extends C, ? extends S> rd =
resolveManagedObjectDefinitionAux(child, r);
if (rd != null) {
return rd;
}
}
return d;
}
}