/*
|
* 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 legal-notices/CDDLv1_0.txt
|
* or http://forgerock.org/license/CDDLv1.0.html.
|
* 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 legal-notices/CDDLv1_0.txt.
|
* 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.
|
* Portions Copyright 2014-2015 ForgeRock AS
|
*/
|
|
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.forgerock.i18n.LocalizableMessage;
|
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 LocalizableMessage 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 LocalizableMessage 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 LocalizableMessage 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 LocalizableMessage 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 LocalizableMessage 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 LocalizableMessage getUserFriendlyName(Locale locale)
|
throws UnsupportedOperationException {
|
// TODO: have admin framework getMessage return a LocalizableMessage
|
return LocalizableMessage.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 LocalizableMessage 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 LocalizableMessage 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;
|
}
|
}
|