From e538344449d345daa6e5ecb9b05ceba5427408e9 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Wed, 04 Dec 2013 14:13:59 +0000
Subject: [PATCH] OpenDJ 3 : config framework
---
opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java | 1576 ++++++++++++++++++++++++++-------------------------------
1 files changed, 722 insertions(+), 854 deletions(-)
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java b/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java
index e982e4d..90f94ec 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java
@@ -27,11 +27,7 @@
package org.opends.server.admin.server;
-
-
import static com.forgerock.opendj.ldap.AdminMessages.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import static org.opends.server.util.StaticUtils.*;
import java.util.ArrayList;
import java.util.Collection;
@@ -76,911 +72,783 @@
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.DefinitionDecodingException.Reason;
-import org.opends.server.admin.std.meta.RootCfgDefn;
-import org.opends.server.admin.std.server.RootCfg;
-import org.opends.server.api.AttributeValueDecoder;
-import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
+import org.forgerock.opendj.admin.meta.RootCfgDefn;
+import org.forgerock.opendj.admin.server.RootCfg;
import org.forgerock.opendj.ldap.DN;
-import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
-
-
/**
* Server management connection context.
*/
public final class ServerManagementContext {
- /**
- * A default behavior visitor used for retrieving the default values
- * of a property.
- *
- * @param <T>
- * The type of the property.
- */
- private class DefaultValueFinder<T> implements
- DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
+ /**
+ * A default behavior visitor used for retrieving the default values of a
+ * property.
+ *
+ * @param <T>
+ * The type of the property.
+ */
+ private class DefaultValueFinder<T> implements DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
- // Any exception that occurred whilst retrieving inherited default
- // values.
- private DefaultBehaviorException exception = null;
+ // Any exception that occurred whilst retrieving inherited default
+ // values.
+ private DefaultBehaviorException exception = null;
- // Optional new configuration entry which does not yet exist in
- // the configuration back-end.
- private final ConfigEntry newConfigEntry;
+ // Optional new configuration entry which does not yet exist in
+ // the configuration back-end.
+ private final ConfigEntry newConfigEntry;
- // The path of the managed object containing the next property.
- private ManagedObjectPath<?, ?> nextPath = null;
+ // The path of the managed object containing the next property.
+ private ManagedObjectPath<?, ?> nextPath = null;
- // The next property whose default values were required.
- private PropertyDefinition<T> nextProperty = null;
+ // The next property whose default values were required.
+ private PropertyDefinition<T> nextProperty = null;
+ // Private constructor.
+ private DefaultValueFinder(ConfigEntry newConfigEntry) {
+ this.newConfigEntry = newConfigEntry;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<T> visitAbsoluteInherited(AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) {
+ try {
+ return getInheritedProperty(d.getManagedObjectPath(), d.getManagedObjectDefinition(),
+ d.getPropertyName());
+ } catch (DefaultBehaviorException e) {
+ exception = e;
+ return Collections.emptySet();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) {
+ return Collections.emptySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d, Void p) {
+ Collection<String> stringValues = d.getDefaultValues();
+ List<T> values = new ArrayList<T>(stringValues.size());
+
+ for (String stringValue : stringValues) {
+ try {
+ values.add(nextProperty.decodeValue(stringValue));
+ } catch (IllegalPropertyValueStringException e) {
+ exception = new DefaultBehaviorException(nextProperty, e);
+ break;
+ }
+ }
+
+ return values;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<T> visitRelativeInherited(RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
+ try {
+ return getInheritedProperty(d.getManagedObjectPath(nextPath), d.getManagedObjectDefinition(),
+ d.getPropertyName());
+ } catch (DefaultBehaviorException e) {
+ exception = e;
+ return Collections.emptySet();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d, Void p) {
+ return Collections.emptySet();
+ }
+
+ // Find the default values for the next path/property.
+ private Collection<T> find(ManagedObjectPath<?, ?> p, PropertyDefinition<T> pd) throws DefaultBehaviorException {
+ nextPath = p;
+ nextProperty = pd;
+
+ Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(this, null);
+
+ if (exception != null) {
+ throw exception;
+ }
+
+ if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+ throw new DefaultBehaviorException(pd, new PropertyIsSingleValuedException(pd));
+ }
+
+ return values;
+ }
+
+ // Get an inherited property value.
+ @SuppressWarnings("unchecked")
+ private Collection<T> getInheritedProperty(ManagedObjectPath target, AbstractManagedObjectDefinition<?, ?> d,
+ String propertyName) throws DefaultBehaviorException {
+ // First check that the requested type of managed object
+ // corresponds to the path.
+ AbstractManagedObjectDefinition<?, ?> supr = target.getManagedObjectDefinition();
+ if (!supr.isParentOf(d)) {
+ throw new DefaultBehaviorException(nextProperty, new DefinitionDecodingException(supr,
+ Reason.WRONG_TYPE_INFORMATION));
+ }
+
+ // Save the current property in case of recursion.
+ PropertyDefinition<T> pd1 = nextProperty;
+
+ try {
+ // Get the actual managed object definition.
+ DN dn = DNBuilder.create(target);
+ ConfigEntry configEntry;
+ if (newConfigEntry != null && newConfigEntry.getDN().equals(dn)) {
+ configEntry = newConfigEntry;
+ } else {
+ configEntry = getManagedObjectConfigEntry(dn);
+ }
+
+ DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
+ ManagedObjectDefinition<?, ?> mod = d.resolveManagedObjectDefinition(resolver);
+
+ PropertyDefinition<T> pd2;
+ try {
+ PropertyDefinition<?> pdTmp = mod.getPropertyDefinition(propertyName);
+ pd2 = pd1.getClass().cast(pdTmp);
+ } catch (IllegalArgumentException e) {
+ throw new PropertyNotFoundException(propertyName);
+ } catch (ClassCastException e) {
+ // FIXME: would be nice to throw a better exception here.
+ throw new PropertyNotFoundException(propertyName);
+ }
+
+ List<AttributeValue> values = getAttribute(mod, pd2, configEntry);
+ if (values.isEmpty()) {
+ // Recursively retrieve this property's default values.
+ Collection<T> tmp = find(target, pd2);
+ Collection<T> pvalues = new ArrayList<T>(tmp.size());
+ for (T value : tmp) {
+ pd1.validateValue(value);
+ pvalues.add(value);
+ }
+ return pvalues;
+ } else {
+ Collection<T> pvalues = new ArrayList<T>(values.size());
+ for (AttributeValue value : values) {
+ pvalues.add(ValueDecoder.decode(pd1, value));
+ }
+ return pvalues;
+ }
+ } catch (DefinitionDecodingException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (PropertyNotFoundException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (IllegalPropertyValueException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (IllegalPropertyValueStringException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (ConfigException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ }
+ }
+ }
+
+ /**
+ * A definition resolver that determines the managed object definition from
+ * the object classes of a ConfigEntry.
+ */
+ private class MyDefinitionResolver implements DefinitionResolver {
+
+ // The config entry.
+ private final ConfigEntry entry;
+
+ // Private constructor.
+ private MyDefinitionResolver(ConfigEntry entry) {
+ this.entry = entry;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
+ String oc = LDAPProfile.getInstance().getObjectClass(d);
+ return entry.hasObjectClass(oc);
+ }
+ }
+
+ /**
+ * A visitor which is used to decode property LDAP values.
+ */
+ private static final class ValueDecoder extends PropertyDefinitionVisitor<Object, String> {
+
+ /**
+ * Decodes the provided property LDAP value.
+ *
+ * @param <PD>
+ * The type of the property.
+ * @param pd
+ * The property definition.
+ * @param value
+ * The LDAP string representation.
+ * @return Returns the decoded LDAP value.
+ * @throws IllegalPropertyValueStringException
+ * If the property value could not be decoded because it was
+ * invalid.
+ */
+ public static <PD> PD decode(PropertyDefinition<PD> pd, AttributeValue value)
+ throws IllegalPropertyValueStringException {
+ String s = value.getValue().toString();
+ return pd.castValue(pd.accept(new ValueDecoder(), s));
+ }
+
+ // Prevent instantiation.
+ private ValueDecoder() {
+ // No implementation required.
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration> Object visitAggregation(
+ AggregationPropertyDefinition<C, S> d, String p) {
+ // Aggregations values are stored as full DNs in LDAP, but
+ // just their common name is exposed in the admin framework.
+ try {
+ Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d.getRelationDefinition(), p);
+ return reference.getName();
+ } catch (IllegalArgumentException e) {
+ throw new IllegalPropertyValueStringException(d, p);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> Object visitUnknown(PropertyDefinition<T> d, String p) throws UnknownPropertyDefinitionException {
+ // By default the property definition's decoder will do.
+ return d.decodeValue(p);
+ }
+ }
+
+ // Singleton instance.
+ private final static ServerManagementContext INSTANCE = new ServerManagementContext();
+
+ /**
+ * The root server managed object.
+ */
+ private static final ServerManagedObject<RootCfg> ROOT = new ServerManagedObject<RootCfg>(
+ ManagedObjectPath.emptyPath(), RootCfgDefn.getInstance(),
+ Collections.<PropertyDefinition<?>, SortedSet<?>> emptyMap(), null);
+
+ /**
+ * Get the single server-side management context.
+ *
+ * @return Returns the single server-side management context.
+ */
+ public static ServerManagementContext getInstance() {
+ return INSTANCE;
+ }
// Private constructor.
- private DefaultValueFinder(ConfigEntry newConfigEntry) {
- this.newConfigEntry = newConfigEntry;
+ private ServerManagementContext() {
+ // No implementation required.
}
-
-
/**
- * {@inheritDoc}
+ * Gets the named managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the path
+ * definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the path
+ * definition refers to.
+ * @param path
+ * The path of the managed object.
+ * @return Returns the named managed object.
+ * @throws ConfigException
+ * If the named managed object could not be found or if it could
+ * not be decoded.
*/
- public Collection<T> visitAbsoluteInherited(
- AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) {
- try {
- return getInheritedProperty(d.getManagedObjectPath(), d
- .getManagedObjectDefinition(), d.getPropertyName());
- } catch (DefaultBehaviorException e) {
- exception = e;
- return Collections.emptySet();
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) {
- return Collections.emptySet();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d,
- Void p) {
- Collection<String> stringValues = d.getDefaultValues();
- List<T> values = new ArrayList<T>(stringValues.size());
-
- for (String stringValue : stringValues) {
- try {
- values.add(nextProperty.decodeValue(stringValue));
- } catch (IllegalPropertyValueStringException e) {
- exception = new DefaultBehaviorException(nextProperty, e);
- break;
- }
- }
-
- return values;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public Collection<T> visitRelativeInherited(
- RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
- try {
- return getInheritedProperty(d.getManagedObjectPath(nextPath), d
- .getManagedObjectDefinition(), d.getPropertyName());
- } catch (DefaultBehaviorException e) {
- exception = e;
- return Collections.emptySet();
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d,
- Void p) {
- return Collections.emptySet();
- }
-
-
-
- // Find the default values for the next path/property.
- private Collection<T> find(ManagedObjectPath<?, ?> p,
- PropertyDefinition<T> pd) throws DefaultBehaviorException {
- nextPath = p;
- nextProperty = pd;
-
- Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(
- this, null);
-
- if (exception != null) {
- throw exception;
- }
-
- if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
- throw new DefaultBehaviorException(pd,
- new PropertyIsSingleValuedException(pd));
- }
-
- return values;
- }
-
-
-
- // Get an inherited property value.
@SuppressWarnings("unchecked")
- private Collection<T> getInheritedProperty(ManagedObjectPath target,
- AbstractManagedObjectDefinition<?, ?> d, String propertyName)
- throws DefaultBehaviorException {
- // First check that the requested type of managed object
- // corresponds to the path.
- AbstractManagedObjectDefinition<?, ?> supr = target
- .getManagedObjectDefinition();
- if (!supr.isParentOf(d)) {
- throw new DefaultBehaviorException(
- nextProperty, new DefinitionDecodingException(supr,
- Reason.WRONG_TYPE_INFORMATION));
- }
-
- // Save the current property in case of recursion.
- PropertyDefinition<T> pd1 = nextProperty;
-
- try {
- // Get the actual managed object definition.
- DN dn = DNBuilder.create(target);
- ConfigEntry configEntry;
- if (newConfigEntry != null && newConfigEntry.getDN().equals(dn)) {
- configEntry = newConfigEntry;
- } else {
- configEntry = getManagedObjectConfigEntry(dn);
+ public <C extends ConfigurationClient, S extends Configuration> ServerManagedObject<? extends S> getManagedObject(
+ ManagedObjectPath<C, S> path) throws ConfigException {
+ // Be careful to handle the root configuration.
+ if (path.isEmpty()) {
+ return (ServerManagedObject<S>) getRootConfigurationManagedObject();
}
+ // Get the configuration entry.
+ DN targetDN = DNBuilder.create(path);
+ ConfigEntry configEntry = getManagedObjectConfigEntry(targetDN);
+ try {
+ ServerManagedObject<? extends S> managedObject;
+ managedObject = decode(path, configEntry);
+
+ // Enforce any constraints.
+ managedObject.ensureIsUsable();
+
+ return managedObject;
+ } catch (DefinitionDecodingException e) {
+ throw ConfigExceptionFactory.getInstance().createDecodingExceptionAdaptor(targetDN, e);
+ } catch (ServerManagedObjectDecodingException e) {
+ throw ConfigExceptionFactory.getInstance().createDecodingExceptionAdaptor(e);
+ } catch (ConstraintViolationException e) {
+ throw ConfigExceptionFactory.getInstance().createDecodingExceptionAdaptor(e);
+ }
+ }
+
+ /**
+ * Gets the effective value of a property in the named managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the path
+ * definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the path
+ * definition refers to.
+ * @param <PD>
+ * The type of the property to be retrieved.
+ * @param path
+ * The path of the managed object containing the property.
+ * @param pd
+ * The property to be retrieved.
+ * @return Returns the property's effective value, or <code>null</code> if
+ * there are no values defined.
+ * @throws IllegalArgumentException
+ * If the property definition is not associated with the
+ * referenced managed object's definition.
+ * @throws PropertyException
+ * If the managed object was found but the requested property
+ * could not be decoded.
+ * @throws ConfigException
+ * If the named managed object could not be found or if it could
+ * not be decoded.
+ */
+ public <C extends ConfigurationClient, S extends Configuration, PD> PD getPropertyValue(
+ ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) throws IllegalArgumentException, ConfigException,
+ PropertyException {
+ SortedSet<PD> values = getPropertyValues(path, pd);
+ if (values.isEmpty()) {
+ return null;
+ } else {
+ return values.first();
+ }
+ }
+
+ /**
+ * Gets the effective values of a property in the named managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the path
+ * definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the path
+ * definition refers to.
+ * @param <PD>
+ * The type of the property to be retrieved.
+ * @param path
+ * The path of the managed object containing the property.
+ * @param pd
+ * The property to be retrieved.
+ * @return Returns the property's effective values, or an empty set if there
+ * are no values defined.
+ * @throws IllegalArgumentException
+ * If the property definition is not associated with the
+ * referenced managed object's definition.
+ * @throws PropertyException
+ * If the managed object was found but the requested property
+ * could not be decoded.
+ * @throws ConfigException
+ * If the named managed object could not be found or if it could
+ * not be decoded.
+ */
+ @SuppressWarnings("unchecked")
+ public <C extends ConfigurationClient, S extends Configuration, PD> SortedSet<PD> getPropertyValues(
+ ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) throws IllegalArgumentException, ConfigException,
+ PropertyException {
+ // Check that the requested property is from the definition
+ // associated with the path.
+ AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
+ PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
+ if (tmp != pd) {
+ throw new IllegalArgumentException("The property " + pd.getName() + " is not associated with a "
+ + d.getName());
+ }
+
+ // Determine the exact type of managed object referenced by the
+ // path.
+ DN dn = DNBuilder.create(path);
+ ConfigEntry configEntry = getManagedObjectConfigEntry(dn);
+
DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
- ManagedObjectDefinition<?, ?> mod = d
- .resolveManagedObjectDefinition(resolver);
+ ManagedObjectDefinition<? extends C, ? extends S> mod;
- PropertyDefinition<T> pd2;
try {
- PropertyDefinition<?> pdTmp = mod.getPropertyDefinition(propertyName);
- pd2 = pd1.getClass().cast(pdTmp);
- } catch (IllegalArgumentException e) {
- throw new PropertyNotFoundException(propertyName);
- } catch (ClassCastException e) {
- // FIXME: would be nice to throw a better exception here.
- throw new PropertyNotFoundException(propertyName);
+ mod = d.resolveManagedObjectDefinition(resolver);
+ } catch (DefinitionDecodingException e) {
+ throw ConfigExceptionFactory.getInstance().createDecodingExceptionAdaptor(dn, e);
}
- List<AttributeValue> values = getAttribute(mod, pd2, configEntry);
- if (values.isEmpty()) {
- // Recursively retrieve this property's default values.
- Collection<T> tmp = find(target, pd2);
- Collection<T> pvalues = new ArrayList<T>(tmp.size());
- for (T value : tmp) {
- pd1.validateValue(value);
- pvalues.add(value);
- }
- return pvalues;
- } else {
- Collection<T> pvalues = new ArrayList<T>(values.size());
- for (AttributeValue value : values) {
- pvalues.add(ValueDecoder.decode(pd1, value));
- }
- return pvalues;
- }
- } catch (DefinitionDecodingException e) {
- throw new DefaultBehaviorException(pd1, e);
- } catch (PropertyNotFoundException e) {
- throw new DefaultBehaviorException(pd1, e);
- } catch (IllegalPropertyValueException e) {
- throw new DefaultBehaviorException(pd1, e);
- } catch (IllegalPropertyValueStringException e) {
- throw new DefaultBehaviorException(pd1, e);
- } catch (ConfigException e) {
- throw new DefaultBehaviorException(pd1, e);
- }
+ // Make sure we use the correct property definition, the
+ // provided one might have been overridden in the resolved
+ // definition.
+ pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
+
+ List<AttributeValue> values = getAttribute(mod, pd, configEntry);
+ return decodeProperty(path.asSubType(mod), pd, values, null);
}
- }
-
-
-
- /**
- * A definition resolver that determines the managed object
- * definition from the object classes of a ConfigEntry.
- */
- private class MyDefinitionResolver implements DefinitionResolver {
-
- // The config entry.
- private final ConfigEntry entry;
-
-
-
- // Private constructor.
- private MyDefinitionResolver(ConfigEntry entry) {
- this.entry = entry;
- }
-
-
/**
- * {@inheritDoc}
- */
- public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
- String oc = LDAPProfile.getInstance().getObjectClass(d);
- return entry.hasObjectClass(oc);
- }
- }
-
-
-
- /**
- * A visitor which is used to decode property LDAP values.
- */
- private static final class ValueDecoder extends
- PropertyDefinitionVisitor<Object, String> {
-
- /**
- * Decodes the provided property LDAP value.
+ * Get the root configuration manager associated with this management
+ * context.
*
- * @param <PD>
- * The type of the property.
- * @param pd
- * The property definition.
- * @param value
- * The LDAP string representation.
- * @return Returns the decoded LDAP value.
- * @throws IllegalPropertyValueStringException
- * If the property value could not be decoded because it
- * was invalid.
+ * @return Returns the root configuration manager associated with this
+ * management context.
*/
- public static <PD> PD decode(PropertyDefinition<PD> pd,
- AttributeValue value) throws IllegalPropertyValueStringException {
- String s = value.getValue().toString();
- return pd.castValue(pd.accept(new ValueDecoder(), s));
+ public RootCfg getRootConfiguration() {
+ return getRootConfigurationManagedObject().getConfiguration();
}
-
-
- // Prevent instantiation.
- private ValueDecoder() {
- // No implementation required.
- }
-
-
-
/**
- * {@inheritDoc}
+ * Get the root configuration server managed object associated with this
+ * management context.
+ *
+ * @return Returns the root configuration server managed object associated
+ * with this management context.
*/
- @Override
- public <C extends ConfigurationClient, S extends Configuration>
- Object visitAggregation(AggregationPropertyDefinition<C, S> d, String p) {
- // Aggregations values are stored as full DNs in LDAP, but
- // just their common name is exposed in the admin framework.
- try {
- Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d
- .getRelationDefinition(), p);
- return reference.getName();
- } catch (IllegalArgumentException e) {
- throw new IllegalPropertyValueStringException(d, p);
- }
+ public ServerManagedObject<RootCfg> getRootConfigurationManagedObject() {
+ return ROOT;
}
-
-
/**
- * {@inheritDoc}
+ * Lists the child managed objects of the named parent managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The instantiable relation definition.
+ * @return Returns the names of the child managed objects.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the parent
+ * managed object's definition.
*/
- @Override
- public <T> Object visitUnknown(PropertyDefinition<T> d, String p)
- throws UnknownPropertyDefinitionException {
- // By default the property definition's decoder will do.
- return d.decodeValue(p);
- }
- }
+ public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd) throws IllegalArgumentException {
+ validateRelationDefinition(parent, rd);
-
-
- // Singleton instance.
- private final static ServerManagementContext INSTANCE =
- new ServerManagementContext();
-
- /**
- * The root server managed object.
- */
- private static final ServerManagedObject<RootCfg> ROOT =
- new ServerManagedObject<RootCfg>(
- ManagedObjectPath.emptyPath(), RootCfgDefn.getInstance(), Collections
- .<PropertyDefinition<?>, SortedSet<?>> emptyMap(), null);
-
- /**
- * The tracer object for the debug logger.
- */
- private static final DebugTracer TRACER = getTracer();
-
-
-
- /**
- * Get the single server-side management context.
- *
- * @return Returns the single server-side management context.
- */
- public static ServerManagementContext getInstance() {
- return INSTANCE;
- }
-
-
-
- // Private constructor.
- private ServerManagementContext() {
- // No implementation required.
- }
-
-
-
- /**
- * Gets the named managed object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * path definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * path definition refers to.
- * @param path
- * The path of the managed object.
- * @return Returns the named managed object.
- * @throws ConfigException
- * If the named managed object could not be found or if it
- * could not be decoded.
- */
- @SuppressWarnings("unchecked")
- public <C extends ConfigurationClient, S extends Configuration>
- ServerManagedObject<? extends S> getManagedObject(
- ManagedObjectPath<C, S> path) throws ConfigException {
- // Be careful to handle the root configuration.
- if (path.isEmpty()) {
- return (ServerManagedObject<S>) getRootConfigurationManagedObject();
- }
-
- // Get the configuration entry.
- DN targetDN = DNBuilder.create(path);
- ConfigEntry configEntry = getManagedObjectConfigEntry(targetDN);
- try {
- ServerManagedObject<? extends S> managedObject;
- managedObject = decode(path, configEntry);
-
- // Enforce any constraints.
- managedObject.ensureIsUsable();
-
- return managedObject;
- } catch (DefinitionDecodingException e) {
- throw ConfigExceptionFactory.getInstance()
- .createDecodingExceptionAdaptor(targetDN, e);
- } catch (ServerManagedObjectDecodingException e) {
- throw ConfigExceptionFactory.getInstance()
- .createDecodingExceptionAdaptor(e);
- } catch (ConstraintViolationException e) {
- throw ConfigExceptionFactory.getInstance()
- .createDecodingExceptionAdaptor(e);
- }
- }
-
-
-
- /**
- * Gets the effective value of a property in the named managed
- * object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * path definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * path definition refers to.
- * @param <PD>
- * The type of the property to be retrieved.
- * @param path
- * The path of the managed object containing the property.
- * @param pd
- * The property to be retrieved.
- * @return Returns the property's effective value, or
- * <code>null</code> if there are no values defined.
- * @throws IllegalArgumentException
- * If the property definition is not associated with the
- * referenced managed object's definition.
- * @throws PropertyException
- * If the managed object was found but the requested
- * property could not be decoded.
- * @throws ConfigException
- * If the named managed object could not be found or if it
- * could not be decoded.
- */
- public <C extends ConfigurationClient, S extends Configuration, PD>
- PD getPropertyValue(ManagedObjectPath<C, S> path,
- PropertyDefinition<PD> pd) throws IllegalArgumentException,
- ConfigException, PropertyException {
- SortedSet<PD> values = getPropertyValues(path, pd);
- if (values.isEmpty()) {
- return null;
- } else {
- return values.first();
- }
- }
-
-
-
- /**
- * Gets the effective values of a property in the named managed
- * object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * path definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * path definition refers to.
- * @param <PD>
- * The type of the property to be retrieved.
- * @param path
- * The path of the managed object containing the property.
- * @param pd
- * The property to be retrieved.
- * @return Returns the property's effective values, or an empty set
- * if there are no values defined.
- * @throws IllegalArgumentException
- * If the property definition is not associated with the
- * referenced managed object's definition.
- * @throws PropertyException
- * If the managed object was found but the requested
- * property could not be decoded.
- * @throws ConfigException
- * If the named managed object could not be found or if it
- * could not be decoded.
- */
- @SuppressWarnings("unchecked")
- public <C extends ConfigurationClient, S extends Configuration, PD>
- SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path,
- PropertyDefinition<PD> pd) throws IllegalArgumentException,
- ConfigException, PropertyException {
- // Check that the requested property is from the definition
- // associated with the path.
- AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
- PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
- if (tmp != pd) {
- throw new IllegalArgumentException("The property " + pd.getName()
- + " is not associated with a " + d.getName());
- }
-
- // Determine the exact type of managed object referenced by the
- // path.
- DN dn = DNBuilder.create(path);
- ConfigEntry configEntry = getManagedObjectConfigEntry(dn);
-
- DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
- ManagedObjectDefinition<? extends C, ? extends S> mod;
-
- try {
- mod = d.resolveManagedObjectDefinition(resolver);
- } catch (DefinitionDecodingException e) {
- throw ConfigExceptionFactory.getInstance()
- .createDecodingExceptionAdaptor(dn, e);
- }
-
- // Make sure we use the correct property definition, the
- // provided one might have been overridden in the resolved
- // definition.
- pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
-
- List<AttributeValue> values = getAttribute(mod, pd, configEntry);
- return decodeProperty(path.asSubType(mod), pd, values, null);
- }
-
-
-
- /**
- * Get the root configuration manager associated with this
- * management context.
- *
- * @return Returns the root configuration manager associated with
- * this management context.
- */
- public RootCfg getRootConfiguration() {
- return getRootConfigurationManagedObject().getConfiguration();
- }
-
-
-
- /**
- * Get the root configuration server managed object associated with
- * this management context.
- *
- * @return Returns the root configuration server managed object
- * associated with this management context.
- */
- public ServerManagedObject<RootCfg> getRootConfigurationManagedObject() {
- return ROOT;
- }
-
-
-
- /**
- * Lists the child managed objects of the named parent managed
- * object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * relation definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * relation definition refers to.
- * @param parent
- * The path of the parent managed object.
- * @param rd
- * The instantiable relation definition.
- * @return Returns the names of the child managed objects.
- * @throws IllegalArgumentException
- * If the relation definition is not associated with the
- * parent managed object's definition.
- */
- public <C extends ConfigurationClient, S extends Configuration>
- String[] listManagedObjects(
- ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd)
- throws IllegalArgumentException {
- validateRelationDefinition(parent, rd);
-
- // Get the target entry.
- DN targetDN = DNBuilder.create(parent, rd);
- ConfigEntry configEntry;
- try {
- configEntry = DirectoryServer.getConfigEntry(targetDN);
- } catch (ConfigException e) {
- return new String[0];
- }
-
- if (configEntry == null) {
- return new String[0];
- }
-
- // Retrieve the children.
- Set<DN> children = configEntry.getChildren().keySet();
- ArrayList<String> names = new ArrayList<String>(children.size());
- for (DN child : children) {
- // Assume that RDNs are single-valued and can be trimmed.
- AttributeValue av = child.getRDN().getAttributeValue(0);
- names.add(av.getValue().toString().trim());
- }
-
- return names.toArray(new String[names.size()]);
- }
-
-
-
- /**
- * Lists the child managed objects of the named parent managed
- * object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * relation definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * relation definition refers to.
- * @param parent
- * The path of the parent managed object.
- * @param rd
- * The set relation definition.
- * @return Returns the names of the child managed objects.
- * @throws IllegalArgumentException
- * If the relation definition is not associated with the
- * parent managed object's definition.
- */
- public <C extends ConfigurationClient, S extends Configuration>
- String[] listManagedObjects(
- ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd)
- throws IllegalArgumentException {
- validateRelationDefinition(parent, rd);
-
- // Get the target entry.
- DN targetDN = DNBuilder.create(parent, rd);
- ConfigEntry configEntry;
- try {
- configEntry = DirectoryServer.getConfigEntry(targetDN);
- } catch (ConfigException e) {
- return new String[0];
- }
-
- if (configEntry == null) {
- return new String[0];
- }
-
- // Retrieve the children.
- Set<DN> children = configEntry.getChildren().keySet();
- ArrayList<String> names = new ArrayList<String>(children.size());
- for (DN child : children) {
- // Assume that RDNs are single-valued and can be trimmed.
- AttributeValue av = child.getRDN().getAttributeValue(0);
- names.add(av.toString().trim());
- }
-
- return names.toArray(new String[names.size()]);
- }
-
-
-
- /**
- * Determines whether or not the named managed object exists.
- *
- * @param path
- * The path of the named managed object.
- * @return Returns <code>true</code> if the named managed object
- * exists, <code>false</code> otherwise.
- */
- public boolean managedObjectExists(ManagedObjectPath<?, ?> path) {
- // Get the configuration entry.
- DN targetDN = DNBuilder.create(path);
- try {
- return (getManagedObjectConfigEntry(targetDN) != null);
- } catch (ConfigException e) {
- // Assume it doesn't exist.
- return false;
- }
- }
-
-
-
- /**
- * Decodes a configuration entry into the required type of server
- * managed object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * path definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * path definition refers to.
- * @param path
- * The location of the server managed object.
- * @param configEntry
- * The configuration entry that should be decoded.
- * @return Returns the new server-side managed object from the
- * provided definition and configuration entry.
- * @throws DefinitionDecodingException
- * If the managed object's type could not be determined.
- * @throws ServerManagedObjectDecodingException
- * If one or more of the managed object's properties could
- * not be decoded.
- */
- <C extends ConfigurationClient, S extends Configuration>
- ServerManagedObject<? extends S> decode(
- ManagedObjectPath<C, S> path, ConfigEntry configEntry)
- throws DefinitionDecodingException, ServerManagedObjectDecodingException {
- return decode(path, configEntry, null);
- }
-
-
-
- /**
- * Decodes a configuration entry into the required type of server
- * managed object.
- *
- * @param <C>
- * The type of client managed object configuration that the
- * path definition refers to.
- * @param <S>
- * The type of server managed object configuration that the
- * path definition refers to.
- * @param path
- * The location of the server managed object.
- * @param configEntry
- * The configuration entry that should be decoded.
- * @param newConfigEntry
- * Optional new configuration that does not exist yet in
- * the configuration back-end. This will be used for
- * resolving inherited default values.
- * @return Returns the new server-side managed object from the
- * provided definition and configuration entry.
- * @throws DefinitionDecodingException
- * If the managed object's type could not be determined.
- * @throws ServerManagedObjectDecodingException
- * If one or more of the managed object's properties could
- * not be decoded.
- */
- <C extends ConfigurationClient, S extends Configuration>
- ServerManagedObject<? extends S> decode(
- ManagedObjectPath<C, S> path, ConfigEntry configEntry,
- ConfigEntry newConfigEntry) throws DefinitionDecodingException,
- ServerManagedObjectDecodingException {
- // First determine the correct definition to use for the entry.
- // This could either be the provided definition, or one of its
- // sub-definitions.
- DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
- AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
- ManagedObjectDefinition<? extends C, ? extends S> mod = d
- .resolveManagedObjectDefinition(resolver);
-
- // Build the managed object's properties.
- List<PropertyException> exceptions = new LinkedList<PropertyException>();
- Map<PropertyDefinition<?>, SortedSet<?>> properties =
- new HashMap<PropertyDefinition<?>, SortedSet<?>>();
- for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
- List<AttributeValue> values = getAttribute(mod, pd, configEntry);
- try {
- SortedSet<?> pvalues = decodeProperty(path, pd, values, newConfigEntry);
- properties.put(pd, pvalues);
- } catch (PropertyException e) {
- exceptions.add(e);
- }
- }
-
- // If there were no decoding problems then return the managed
- // object, otherwise throw an operations exception.
- ServerManagedObject<? extends S> mo = decodeAux(path, mod, properties,
- configEntry);
- if (exceptions.isEmpty()) {
- return mo;
- } else {
- throw new ServerManagedObjectDecodingException(mo, exceptions);
- }
- }
-
-
-
- // Decode helper method required to avoid generics warning.
- private <C extends ConfigurationClient, S extends Configuration>
- ServerManagedObject<S> decodeAux(
- ManagedObjectPath<? super C, ? super S> path,
- ManagedObjectDefinition<C, S> d,
- Map<PropertyDefinition<?>, SortedSet<?>> properties,
- ConfigEntry configEntry) {
- ManagedObjectPath<C, S> newPath = path.asSubType(d);
- return new ServerManagedObject<S>(newPath, d, properties, configEntry);
- }
-
-
-
- // Create a property using the provided string values.
- private <T> SortedSet<T> decodeProperty(ManagedObjectPath<?, ?> path,
- PropertyDefinition<T> pd, List<AttributeValue> values,
- ConfigEntry newConfigEntry) throws PropertyException {
- PropertyException exception = null;
- SortedSet<T> pvalues = new TreeSet<T>(pd);
-
- if (!values.isEmpty()) {
- // The property has values defined for it.
- for (AttributeValue value : values) {
+ // Get the target entry.
+ DN targetDN = DNBuilder.create(parent, rd);
+ ConfigEntry configEntry;
try {
- pvalues.add(ValueDecoder.decode(pd, value));
- } catch (IllegalPropertyValueStringException e) {
- exception = e;
+ configEntry = DirectoryServer.getConfigEntry(targetDN);
+ } catch (ConfigException e) {
+ return new String[0];
}
- }
- } else {
- // No values defined so get the defaults.
- try {
- pvalues.addAll(getDefaultValues(path, pd, newConfigEntry));
- } catch (DefaultBehaviorException e) {
- exception = e;
- }
+
+ if (configEntry == null) {
+ return new String[0];
+ }
+
+ // Retrieve the children.
+ Set<DN> children = configEntry.getChildren().keySet();
+ ArrayList<String> names = new ArrayList<String>(children.size());
+ for (DN child : children) {
+ // Assume that RDNs are single-valued and can be trimmed.
+ AttributeValue av = child.rdn().getAttributeValue(0);
+ names.add(av.getValue().toString().trim());
+ }
+
+ return names.toArray(new String[names.size()]);
}
- if (pvalues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
- // This exception takes precedence over previous exceptions.
- exception = new PropertyIsSingleValuedException(pd);
- T value = pvalues.first();
- pvalues.clear();
- pvalues.add(value);
+ /**
+ * Lists the child managed objects of the named parent managed object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param parent
+ * The path of the parent managed object.
+ * @param rd
+ * The set relation definition.
+ * @return Returns the names of the child managed objects.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the parent
+ * managed object's definition.
+ */
+ public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd) throws IllegalArgumentException {
+ validateRelationDefinition(parent, rd);
+
+ // Get the target entry.
+ DN targetDN = DNBuilder.create(parent, rd);
+ ConfigEntry configEntry;
+ try {
+ configEntry = DirectoryServer.getConfigEntry(targetDN);
+ } catch (ConfigException e) {
+ return new String[0];
+ }
+
+ if (configEntry == null) {
+ return new String[0];
+ }
+
+ // Retrieve the children.
+ Set<DN> children = configEntry.getChildren().keySet();
+ ArrayList<String> names = new ArrayList<String>(children.size());
+ for (DN child : children) {
+ // Assume that RDNs are single-valued and can be trimmed.
+ AttributeValue av = child.rdn().getAttributeValue(0);
+ names.add(av.toString().trim());
+ }
+
+ return names.toArray(new String[names.size()]);
}
- if (pvalues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
- // The values maybe empty because of a previous exception.
- if (exception == null) {
- exception = new PropertyIsMandatoryException(pd);
- }
+ /**
+ * Determines whether or not the named managed object exists.
+ *
+ * @param path
+ * The path of the named managed object.
+ * @return Returns <code>true</code> if the named managed object exists,
+ * <code>false</code> otherwise.
+ */
+ public boolean managedObjectExists(ManagedObjectPath<?, ?> path) {
+ // Get the configuration entry.
+ DN targetDN = DNBuilder.create(path);
+ try {
+ return (getManagedObjectConfigEntry(targetDN) != null);
+ } catch (ConfigException e) {
+ // Assume it doesn't exist.
+ return false;
+ }
}
- if (exception != null) {
- throw exception;
- } else {
- return pvalues;
- }
- }
-
-
-
- // Gets the attribute associated with a property from a ConfigEntry.
- private List<AttributeValue> getAttribute(ManagedObjectDefinition<?, ?> d,
- PropertyDefinition<?> pd, ConfigEntry configEntry) {
- // TODO: we create a default attribute type if it is
- // undefined. We should log a warning here if this is the case
- // since the attribute should have been defined.
- String attrID = LDAPProfile.getInstance().getAttributeName(d, pd);
- AttributeType type = DirectoryServer.getAttributeType(attrID, true);
- AttributeValueDecoder<AttributeValue> decoder =
- new AttributeValueDecoder<AttributeValue>() {
-
- public AttributeValue decode(AttributeValue value)
- throws DirectoryException {
- return value;
- }
- };
-
- List<AttributeValue> values = new LinkedList<AttributeValue>();
- try {
- configEntry.getEntry().getAttributeValues(type, decoder, values);
- } catch (DirectoryException e) {
- // Should not happen.
- throw new RuntimeException(e);
- }
- return values;
- }
-
-
-
- // Get the default values for the specified property.
- private <T> Collection<T> getDefaultValues(ManagedObjectPath<?, ?> p,
- PropertyDefinition<T> pd, ConfigEntry newConfigEntry)
- throws DefaultBehaviorException {
- DefaultValueFinder<T> v = new DefaultValueFinder<T>(newConfigEntry);
- return v.find(p, pd);
- }
-
-
-
- // Gets a config entry required for a managed object and throws a
- // config exception on failure.
- private ConfigEntry getManagedObjectConfigEntry(
- DN dn) throws ConfigException {
- ConfigEntry configEntry;
- try {
- configEntry = DirectoryServer.getConfigEntry(dn);
- } catch (ConfigException e) {
- if (debugEnabled()) {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- LocalizableMessage message = ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT.get(
- String.valueOf(dn), stackTraceToSingleLineString(e));
- throw new ConfigException(message, e);
+ /**
+ * Decodes a configuration entry into the required type of server managed
+ * object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the path
+ * definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the path
+ * definition refers to.
+ * @param path
+ * The location of the server managed object.
+ * @param configEntry
+ * The configuration entry that should be decoded.
+ * @return Returns the new server-side managed object from the provided
+ * definition and configuration entry.
+ * @throws DefinitionDecodingException
+ * If the managed object's type could not be determined.
+ * @throws ServerManagedObjectDecodingException
+ * If one or more of the managed object's properties could not
+ * be decoded.
+ */
+ <C extends ConfigurationClient, S extends Configuration> ServerManagedObject<? extends S> decode(
+ ManagedObjectPath<C, S> path, ConfigEntry configEntry) throws DefinitionDecodingException,
+ ServerManagedObjectDecodingException {
+ return decode(path, configEntry, null);
}
- // The configuration handler is free to return null indicating
- // that the entry does not exist.
- if (configEntry == null) {
- LocalizableMessage message = ERR_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST
- .get(String.valueOf(dn));
- throw new ConfigException(message);
+ /**
+ * Decodes a configuration entry into the required type of server managed
+ * object.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the path
+ * definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the path
+ * definition refers to.
+ * @param path
+ * The location of the server managed object.
+ * @param configEntry
+ * The configuration entry that should be decoded.
+ * @param newConfigEntry
+ * Optional new configuration that does not exist yet in the
+ * configuration back-end. This will be used for resolving
+ * inherited default values.
+ * @return Returns the new server-side managed object from the provided
+ * definition and configuration entry.
+ * @throws DefinitionDecodingException
+ * If the managed object's type could not be determined.
+ * @throws ServerManagedObjectDecodingException
+ * If one or more of the managed object's properties could not
+ * be decoded.
+ */
+ <C extends ConfigurationClient, S extends Configuration> ServerManagedObject<? extends S> decode(
+ ManagedObjectPath<C, S> path, ConfigEntry configEntry, ConfigEntry newConfigEntry)
+ throws DefinitionDecodingException, ServerManagedObjectDecodingException {
+ // First determine the correct definition to use for the entry.
+ // This could either be the provided definition, or one of its
+ // sub-definitions.
+ DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
+ AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
+ ManagedObjectDefinition<? extends C, ? extends S> mod = d.resolveManagedObjectDefinition(resolver);
+
+ // Build the managed object's properties.
+ List<PropertyException> exceptions = new LinkedList<PropertyException>();
+ Map<PropertyDefinition<?>, SortedSet<?>> properties = new HashMap<PropertyDefinition<?>, SortedSet<?>>();
+ for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
+ List<AttributeValue> values = getAttribute(mod, pd, configEntry);
+ try {
+ SortedSet<?> pvalues = decodeProperty(path, pd, values, newConfigEntry);
+ properties.put(pd, pvalues);
+ } catch (PropertyException e) {
+ exceptions.add(e);
+ }
+ }
+
+ // If there were no decoding problems then return the managed
+ // object, otherwise throw an operations exception.
+ ServerManagedObject<? extends S> mo = decodeAux(path, mod, properties, configEntry);
+ if (exceptions.isEmpty()) {
+ return mo;
+ } else {
+ throw new ServerManagedObjectDecodingException(mo, exceptions);
+ }
}
- return configEntry;
- }
-
-
-
- // Validate that a relation definition belongs to the path.
- private void validateRelationDefinition(ManagedObjectPath<?, ?> path,
- RelationDefinition<?, ?> rd) throws IllegalArgumentException {
- AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
- RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
- if (tmp != rd) {
- throw new IllegalArgumentException("The relation " + rd.getName()
- + " is not associated with a " + d.getName());
+ // Decode helper method required to avoid generics warning.
+ private <C extends ConfigurationClient, S extends Configuration> ServerManagedObject<S> decodeAux(
+ ManagedObjectPath<? super C, ? super S> path, ManagedObjectDefinition<C, S> d,
+ Map<PropertyDefinition<?>, SortedSet<?>> properties, ConfigEntry configEntry) {
+ ManagedObjectPath<C, S> newPath = path.asSubType(d);
+ return new ServerManagedObject<S>(newPath, d, properties, configEntry);
}
- }
+
+ // Create a property using the provided string values.
+ private <T> SortedSet<T> decodeProperty(ManagedObjectPath<?, ?> path, PropertyDefinition<T> pd,
+ List<AttributeValue> values, ConfigEntry newConfigEntry) throws PropertyException {
+ PropertyException exception = null;
+ SortedSet<T> pvalues = new TreeSet<T>(pd);
+
+ if (!values.isEmpty()) {
+ // The property has values defined for it.
+ for (AttributeValue value : values) {
+ try {
+ pvalues.add(ValueDecoder.decode(pd, value));
+ } catch (IllegalPropertyValueStringException e) {
+ exception = e;
+ }
+ }
+ } else {
+ // No values defined so get the defaults.
+ try {
+ pvalues.addAll(getDefaultValues(path, pd, newConfigEntry));
+ } catch (DefaultBehaviorException e) {
+ exception = e;
+ }
+ }
+
+ if (pvalues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+ // This exception takes precedence over previous exceptions.
+ exception = new PropertyIsSingleValuedException(pd);
+ T value = pvalues.first();
+ pvalues.clear();
+ pvalues.add(value);
+ }
+
+ if (pvalues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
+ // The values maybe empty because of a previous exception.
+ if (exception == null) {
+ exception = new PropertyIsMandatoryException(pd);
+ }
+ }
+
+ if (exception != null) {
+ throw exception;
+ } else {
+ return pvalues;
+ }
+ }
+
+ // Gets the attribute associated with a property from a ConfigEntry.
+ private List<AttributeValue> getAttribute(ManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd,
+ ConfigEntry configEntry) {
+ // TODO: we create a default attribute type if it is
+ // undefined. We should log a warning here if this is the case
+ // since the attribute should have been defined.
+ String attrID = LDAPProfile.getInstance().getAttributeName(d, pd);
+ AttributeType type = DirectoryServer.getAttributeType(attrID, true);
+ AttributeValueDecoder<AttributeValue> decoder = new AttributeValueDecoder<AttributeValue>() {
+
+ public AttributeValue decode(AttributeValue value) throws DirectoryException {
+ return value;
+ }
+ };
+
+ List<AttributeValue> values = new LinkedList<AttributeValue>();
+ try {
+ configEntry.getEntry().getAttributeValues(type, decoder, values);
+ } catch (DirectoryException e) {
+ // Should not happen.
+ throw new RuntimeException(e);
+ }
+ return values;
+ }
+
+ // Get the default values for the specified property.
+ private <T> Collection<T> getDefaultValues(ManagedObjectPath<?, ?> p, PropertyDefinition<T> pd,
+ ConfigEntry newConfigEntry) throws DefaultBehaviorException {
+ DefaultValueFinder<T> v = new DefaultValueFinder<T>(newConfigEntry);
+ return v.find(p, pd);
+ }
+
+ // Gets a config entry required for a managed object and throws a
+ // config exception on failure.
+ private ConfigEntry getManagedObjectConfigEntry(DN dn) throws ConfigException {
+ ConfigEntry configEntry;
+ try {
+ configEntry = DirectoryServer.getConfigEntry(dn);
+ } catch (ConfigException e) {
+ if (debugEnabled()) {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ LocalizableMessage message = ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT.get(String.valueOf(dn),
+ stackTraceToSingleLineString(e));
+ throw new ConfigException(message, e);
+ }
+
+ // The configuration handler is free to return null indicating
+ // that the entry does not exist.
+ if (configEntry == null) {
+ LocalizableMessage message = ERR_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST.get(String.valueOf(dn));
+ throw new ConfigException(message);
+ }
+
+ return configEntry;
+ }
+
+ // Validate that a relation definition belongs to the path.
+ private void validateRelationDefinition(ManagedObjectPath<?, ?> path, RelationDefinition<?, ?> rd)
+ throws IllegalArgumentException {
+ AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
+ RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
+ if (tmp != rd) {
+ throw new IllegalArgumentException("The relation " + rd.getName() + " is not associated with a "
+ + d.getName());
+ }
+ }
}
--
Gitblit v1.10.0