From ace2bd4146fe55154c0d716f20d9cbff3a2297d3 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 27 Sep 2007 14:50:30 +0000
Subject: [PATCH] Improvements to aggregation support and foundation work for expressing arbitrary constraints within components.
---
opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java | 346 ++++++++++++++++++++------------------------------------
1 files changed, 125 insertions(+), 221 deletions(-)
diff --git a/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java b/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
index c1e7b96..b0a23b8 100644
--- a/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
+++ b/opends/src/server/org/opends/server/admin/AggregationPropertyDefinition.java
@@ -29,6 +29,7 @@
import static org.opends.messages.AdminMessages.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.Validator.*;
import java.util.Collection;
@@ -47,15 +48,21 @@
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.condition.Condition;
+import org.opends.server.admin.condition.Conditions;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ConfigurationDeleteListener;
import org.opends.server.admin.server.ServerConstraintHandler;
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.config.ConfigException;
+import org.opends.server.loggers.ErrorLogger;
+import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
+import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.ResultCode;
+import org.opends.server.util.StaticUtils;
@@ -126,16 +133,13 @@
// contains the aggregated managed objects.
private String rdName = null;
- // The optional names of boolean "enabled" properties in this
- // managed object. When all of the properties are true, the
- // enabled property in the aggregated managed object must also be
- // true.
- private List<String> sourceEnabledPropertyNames = new LinkedList<String>();
+ // The condition which is used to determine if a referenced
+ // managed object is enabled.
+ private Condition targetIsEnabledCondition = Conditions.TRUE;
- // The optional name of a boolean "enabled" property in the
- // aggregated managed object. This property must not be false
- // while the aggregated managed object is referenced.
- private String targetEnabledPropertyName = null;
+ // The condition which is used to determine whether or not
+ // referenced managed objects need to be enabled.
+ private Condition targetNeedsEnablingCondition = Conditions.TRUE;
@@ -148,27 +152,6 @@
/**
- * Registers a boolean "enabled" property in this managed object.
- * When all the registered properties are true, the enabled
- * property in the aggregated managed object must also be true.
- * <p>
- * By default no source properties are defined which indicates
- * that the target property must always be true. When there is one
- * or more source properties defined, a target property must also
- * be defined.
- *
- * @param sourceEnabledPropertyName
- * The optional boolean "enabled" property in this
- * managed object.
- */
- public final void addSourceEnabledPropertyName(
- String sourceEnabledPropertyName) {
- this.sourceEnabledPropertyNames.add(sourceEnabledPropertyName);
- }
-
-
-
- /**
* Sets the name of the managed object which is the parent of the
* aggregated managed objects.
* <p>
@@ -204,20 +187,31 @@
/**
- * Sets the optional boolean "enabled" property in the aggregated
- * managed object. This property must not be false while the
- * aggregated managed object is referenced.
- * <p>
- * By default no target property is defined. It must be defined,
- * if the source property is defined.
+ * Sets the condition which is used to determine if a referenced
+ * managed object is enabled. By default referenced managed
+ * objects are assumed to always be enabled.
*
- * @param targetEnabledPropertyName
- * The optional boolean "enabled" property in the
- * aggregated managed object.
+ * @param condition
+ * The condition which is used to determine if a
+ * referenced managed object is enabled.
*/
- public final void setTargetEnabledPropertyName(
- String targetEnabledPropertyName) {
- this.targetEnabledPropertyName = targetEnabledPropertyName;
+ public final void setTargetIsEnabledCondition(Condition condition) {
+ this.targetIsEnabledCondition = condition;
+ }
+
+
+
+ /**
+ * Sets the condition which is used to determine whether or not
+ * referenced managed objects need to be enabled. By default
+ * referenced managed objects must always be enabled.
+ *
+ * @param condition
+ * The condition which is used to determine whether or
+ * not referenced managed objects need to be enabled.
+ */
+ public final void setTargetNeedsEnablingCondition(Condition condition) {
+ this.targetNeedsEnablingCondition = condition;
}
@@ -240,18 +234,9 @@
throw new IllegalStateException("Relation definition undefined");
}
- // Make sure that if a source property is specified then a
- // target property is also specified.
- if (!sourceEnabledPropertyNames.isEmpty()
- && targetEnabledPropertyName == null) {
- throw new IllegalStateException(
- "One or more source properties defined but "
- + "target property is undefined");
- }
-
return new AggregationPropertyDefinition<C, S>(d, propertyName, options,
adminAction, defaultBehavior, parentPathString, rdName,
- sourceEnabledPropertyNames, targetEnabledPropertyName);
+ targetNeedsEnablingCondition, targetIsEnabledCondition);
}
}
@@ -287,18 +272,20 @@
* {@inheritDoc}
*/
public ConfigChangeResult applyConfigurationChange(S configuration) {
- PropertyProvider provider = configuration.properties();
- Collection<Boolean> values = provider
- .getPropertyValues(getTargetEnabledPropertyDefinition());
- if (values.iterator().next() == false) {
- // This should not happen - the
- // isConfigurationChangeAcceptable() call-back should have
- // trapped this.
- throw new IllegalStateException("Attempting to disable a referenced "
- + configuration.definition().getUserFriendlyName());
- } else {
- return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ ServerManagedObject<?> mo = configuration.managedObject();
+ try {
+ if (targetIsEnabledCondition.evaluate(mo)) {
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
+ } catch (ConfigException e) {
+ // This should not happen - ignore it and throw an exception
+ // anyway below.
}
+
+ // This should not happen - the previous call-back should have
+ // trapped this.
+ throw new IllegalStateException("Attempting to disable a referenced "
+ + configuration.definition().getUserFriendlyName());
}
@@ -310,14 +297,27 @@
List<Message> unacceptableReasons) {
// Always prevent the referenced component from being
// disabled.
- PropertyProvider provider = configuration.properties();
- Collection<Boolean> values = provider
- .getPropertyValues(getTargetEnabledPropertyDefinition());
- if (values.iterator().next() == false) {
+ ServerManagedObject<?> mo = configuration.managedObject();
+ try {
+ if (!targetIsEnabledCondition.evaluate(mo)) {
+ unacceptableReasons.add(message);
+ return false;
+ } else {
+ return true;
+ }
+ } catch (ConfigException e) {
+ // The condition could not be evaluated.
+ if (debugEnabled()) {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message = ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo
+ .getManagedObjectDefinition().getUserFriendlyName(), String
+ .valueOf(configuration.dn()), StaticUtils.getExceptionMessage(e));
+ ErrorLogger.logError(message);
unacceptableReasons.add(message);
return false;
}
- return true;
}
@@ -407,15 +407,14 @@
SortedSet<String> names = managedObject
.getPropertyValues(AggregationPropertyDefinition.this);
ServerManagementContext context = ServerManagementContext.getInstance();
- BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
- List<BooleanPropertyDefinition> spdlist =
- getSourceEnabledPropertyDefinitions();
Message thisUFN = managedObject.getManagedObjectDefinition()
.getUserFriendlyName();
String thisDN = managedObject.getDN().toString();
Message thatUFN = getRelationDefinition().getUserFriendlyName();
boolean isUsable = true;
+ boolean needsEnabling = targetNeedsEnablingCondition
+ .evaluate(managedObject);
for (String name : names) {
ManagedObjectPath<C, S> path = getChildPath(name);
String thatDN = path.toDN().toString();
@@ -425,35 +424,15 @@
getName(), thisUFN, thisDN, thatUFN, thatDN);
unacceptableReasons.add(msg);
isUsable = false;
- } else if (tpd != null) {
- // Check that the referenced component is enabled.
+ } else if (needsEnabling) {
+ // Check that the referenced component is enabled if
+ // required.
ServerManagedObject<? extends S> ref = context.getManagedObject(path);
-
- if (!spdlist.isEmpty()) {
- // Target must be enabled but only if the source
- // properties are enabled.
- boolean isRequired = true;
- for (BooleanPropertyDefinition spd : spdlist) {
- if (!managedObject.getPropertyValue(spd)) {
- isRequired = false;
- break;
- }
- }
-
- if (isRequired && !ref.getPropertyValue(tpd)) {
- Message msg = ERR_SERVER_REFINT_SOURCE_ENABLED_TARGET_DISABLED
- .get(name, getName(), thisUFN, thisDN, thatUFN, thatDN);
- unacceptableReasons.add(msg);
- isUsable = false;
- }
- } else {
- // Target must always be enabled.
- if (!ref.getPropertyValue(tpd)) {
- Message msg = ERR_SERVER_REFINT_TARGET_DISABLED.get(name,
- getName(), thisUFN, thisDN, thatUFN, thatDN);
- unacceptableReasons.add(msg);
- isUsable = false;
- }
+ if (!targetIsEnabledCondition.evaluate(ref)) {
+ Message msg = ERR_SERVER_REFINT_TARGET_DISABLED.get(name,
+ getName(), thisUFN, thisDN, thatUFN, thatDN);
+ unacceptableReasons.add(msg);
+ isUsable = false;
}
}
}
@@ -478,9 +457,6 @@
// Add change and delete listeners against all referenced
// components.
- BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
- List<BooleanPropertyDefinition> spdlist =
- getSourceEnabledPropertyDefinitions();
Message thisUFN = managedObject.getManagedObjectDefinition()
.getUserFriendlyName();
String thisDN = managedObject.getDN().toString();
@@ -488,18 +464,8 @@
// Referenced managed objects will only need a change listener
// if they have can be disabled.
- boolean needsChangeListeners;
- if (tpd != null) {
- needsChangeListeners = true;
- for (BooleanPropertyDefinition spd : spdlist) {
- if (!managedObject.getPropertyValue(spd)) {
- needsChangeListeners = false;
- break;
- }
- }
- } else {
- needsChangeListeners = false;
- }
+ boolean needsChangeListeners = targetNeedsEnablingCondition
+ .evaluate(managedObject);
// Delete listeners need to be registered against the parent
// entry of the referenced components.
@@ -611,18 +577,12 @@
throws AuthorizationException, CommunicationException {
// If all of this managed object's "enabled" properties are true
// then any referenced managed objects must also be enabled.
- boolean needsEnabling = true;
- for (BooleanPropertyDefinition spd :
- getSourceEnabledPropertyDefinitions()) {
- if (!managedObject.getPropertyValue(spd)) {
- needsEnabling = false;
- }
- }
+ boolean needsEnabling = targetNeedsEnablingCondition.evaluate(context,
+ managedObject);
// Check the referenced managed objects exist and, if required,
// are enabled.
boolean isAcceptable = true;
- BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
Message ufn = getRelationDefinition().getUserFriendlyName();
for (String name : managedObject
.getPropertyValues(AggregationPropertyDefinition.this)) {
@@ -653,8 +613,8 @@
}
// Make sure the reference managed object is enabled.
- if (tpd != null && needsEnabling) {
- if (!ref.getPropertyValue(tpd)) {
+ if (needsEnabling) {
+ if (!targetIsEnabledCondition.evaluate(context, ref)) {
Message msg = ERR_CLIENT_REFINT_TARGET_DISABLED.get(ufn, name,
getName());
unacceptableReasons.add(msg);
@@ -849,15 +809,7 @@
throws AuthorizationException, CommunicationException {
// If the modified managed object is disabled and there are some
// active references then refuse the change.
- BooleanPropertyDefinition tpd = getTargetEnabledPropertyDefinition();
-
- // The referenced managed object cannot be disabled: always ok.
- if (tpd == null) {
- return true;
- }
-
- // The referenced managed object is enabled: always ok.
- if (managedObject.getPropertyValue(tpd)) {
+ if (targetIsEnabledCondition.evaluate(context, managedObject)) {
return true;
}
@@ -866,16 +818,7 @@
boolean isAcceptable = true;
for (ManagedObject<?> mo : findReferences(context, managedObject
.getManagedObjectPath().getName())) {
- boolean needsEnabling = true;
- for (BooleanPropertyDefinition spd :
- getSourceEnabledPropertyDefinitions()) {
- if (!mo.getPropertyValue(spd)) {
- needsEnabling = false;
- break;
- }
- }
-
- if (needsEnabling) {
+ if (targetNeedsEnablingCondition.evaluate(context, mo)) {
String name = mo.getManagedObjectPath().getName();
if (name == null) {
Message msg = ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME.get(
@@ -910,6 +853,11 @@
}
}
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
/**
@@ -937,14 +885,14 @@
// The active server-side referential integrity change listeners
// associated with this property.
private final Map<DN, List<ReferentialIntegrityChangeListener>>
- changeListeners =
- new HashMap<DN, List<ReferentialIntegrityChangeListener>>();
+ changeListeners = new HashMap<DN,
+ List<ReferentialIntegrityChangeListener>>();
// The active server-side referential integrity delete listeners
// associated with this property.
private final Map<DN, List<ReferentialIntegrityDeleteListener>>
- deleteListeners =
- new HashMap<DN, List<ReferentialIntegrityDeleteListener>>();
+ deleteListeners = new HashMap<DN,
+ List<ReferentialIntegrityDeleteListener>>();
// The name of the managed object which is the parent of the
// aggregated managed objects.
@@ -962,22 +910,13 @@
// aggregated managed objects.
private InstantiableRelationDefinition<C, S> relationDefinition;
- // The decoded source property definitions.
- private List<BooleanPropertyDefinition> sourceEnabledProperties;
+ // The condition which is used to determine if a referenced managed
+ // object is enabled.
+ private final Condition targetIsEnabledCondition;
- // The optional names of boolean "enabled" properties in this
- // managed object. When all of the properties are true or if there
- // are none defined, the enabled property in the aggregated managed
- // object must also be true.
- private final List<String> sourceEnabledPropertyNames;
-
- // The decoded target property definition.
- private BooleanPropertyDefinition targetEnabledProperty;
-
- // The optional name of a boolean "enabled" property in the
- // aggregated managed object. This property must not be false
- // while the aggregated managed object is referenced.
- private final String targetEnabledPropertyName;
+ // The condition which is used to determine whether or not
+ // referenced managed objects need to be enabled.
+ private final Condition targetNeedsEnablingCondition;
@@ -986,14 +925,14 @@
AbstractManagedObjectDefinition<?, ?> d, String propertyName,
EnumSet<PropertyOption> options, AdministratorAction adminAction,
DefaultBehaviorProvider<String> defaultBehavior, String parentPathString,
- String rdName, List<String> sourceEnabledPropertyNames,
- String targetEnabledPropertyName) {
+ String rdName, Condition targetNeedsEnablingCondition,
+ Condition targetIsEnabledCondition) {
super(d, String.class, propertyName, options, adminAction, defaultBehavior);
this.parentPathString = parentPathString;
this.rdName = rdName;
- this.sourceEnabledPropertyNames = sourceEnabledPropertyNames;
- this.targetEnabledPropertyName = targetEnabledPropertyName;
+ this.targetNeedsEnablingCondition = targetNeedsEnablingCondition;
+ this.targetIsEnabledCondition = targetIsEnabledCondition;
}
@@ -1115,32 +1054,27 @@
/**
- * Gets the optional boolean "enabled" properties in this managed
- * object. When these properties are all true or if there are no
- * properties, the enabled property in the aggregated managed object
- * must also be true.
+ * Gets the condition which is used to determine if a referenced
+ * managed object is enabled.
*
- * @return Returns the optional boolean "enabled" properties in this
- * managed object, which may be empty.
+ * @return Returns the condition which is used to determine if a
+ * referenced managed object is enabled.
*/
- public final List<BooleanPropertyDefinition>
- getSourceEnabledPropertyDefinitions() {
- return sourceEnabledProperties;
+ public final Condition getTargetIsEnabledCondition() {
+ return targetIsEnabledCondition;
}
/**
- * Gets the optional boolean "enabled" property in the aggregated
- * managed object. This property must not be false while the
- * aggregated managed object is referenced.
+ * Gets the condition which is used to determine whether or not
+ * referenced managed objects need to be enabled.
*
- * @return Returns the optional boolean "enabled" property in the
- * aggregated managed object, or <code>null</code> if none
- * is defined.
+ * @return Returns the condition which is used to determine whether
+ * or not referenced managed objects need to be enabled.
*/
- public final BooleanPropertyDefinition getTargetEnabledPropertyDefinition() {
- return targetEnabledProperty;
+ public final Condition getTargetNeedsEnablingCondition() {
+ return targetNeedsEnablingCondition;
}
@@ -1175,22 +1109,11 @@
builder.append(" relationDefinition=");
builder.append(relationDefinition.getName());
- builder.append(" sourceEnabledPropertyName=[");
- boolean isFirst = true;
- for (String name : sourceEnabledPropertyNames) {
- if (!isFirst) {
- builder.append(", ");
- } else {
- isFirst = false;
- }
- builder.append(name);
- }
- builder.append(']');
+ builder.append(" targetNeedsEnablingCondition=");
+ builder.append(String.valueOf(targetNeedsEnablingCondition));
- if (targetEnabledPropertyName != null) {
- builder.append(" targetEnabledPropertyName=");
- builder.append(targetEnabledPropertyName);
- }
+ builder.append(" targetIsEnabledCondition=");
+ builder.append(String.valueOf(targetIsEnabledCondition));
}
@@ -1224,28 +1147,9 @@
RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName);
relationDefinition = (InstantiableRelationDefinition<C, S>) rd;
- // Now decode the property definitions.
- AbstractManagedObjectDefinition<?, ?> d = getManagedObjectDefinition();
- sourceEnabledProperties = new LinkedList<BooleanPropertyDefinition>();
- for (String name : sourceEnabledPropertyNames) {
- PropertyDefinition<?> pd = d.getPropertyDefinition(name);
-
- // Runtime cast is required to workaround a
- // bug in JDK versions prior to 1.5.0_08.
- sourceEnabledProperties.add(BooleanPropertyDefinition.class.cast(pd));
- }
-
- d = relationDefinition.getChildDefinition();
- if (targetEnabledPropertyName == null) {
- targetEnabledProperty = null;
- } else {
- PropertyDefinition<?> pd = d
- .getPropertyDefinition(targetEnabledPropertyName);
-
- // Runtime cast is required to workaround a
- // bug in JDK versions prior to 1.5.0_08.
- targetEnabledProperty = BooleanPropertyDefinition.class.cast(pd);
- }
+ // Now decode the conditions.
+ targetNeedsEnablingCondition.initialize(getManagedObjectDefinition());
+ targetIsEnabledCondition.initialize(rd.getChildDefinition());
// Register a client-side constraint with the referenced
// definition. This will be used to enforce referential integrity
@@ -1271,7 +1175,7 @@
};
- d.registerConstraint(constraint);
+ rd.getChildDefinition().registerConstraint(constraint);
}
}
--
Gitblit v1.10.0