From 02805157fa504b3dbf701a62280ca9aaf82183b5 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Wed, 05 Sep 2007 20:12:11 +0000
Subject: [PATCH] Partial fix for issue 1449: administration framework aggregation support
---
opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java | 144 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 112 insertions(+), 32 deletions(-)
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
index eaa99ab..668d495 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -49,6 +49,7 @@
import org.opends.messages.Message;
import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.DefaultBehaviorException;
@@ -61,11 +62,14 @@
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.PropertyDefinitionVisitor;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.PropertyIsMandatoryException;
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.Reference;
import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
@@ -84,6 +88,73 @@
*/
final class LDAPDriver extends Driver {
+ /**
+ * 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, Object value)
+ throws IllegalPropertyValueStringException {
+ String s = String.valueOf(value);
+ 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);
+ }
+ }
+
+
+
// The LDAP connection.
private final LDAPConnection connection;
@@ -151,20 +222,8 @@
for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
String attrID = profile.getAttributeName(mod, pd);
Attribute attribute = attributes.get(attrID);
- List<String> values = new LinkedList<String>();
-
- if (attribute != null && attribute.size() != 0) {
- NamingEnumeration<?> ldapValues = attribute.getAll();
- while (ldapValues.hasMore()) {
- Object obj = ldapValues.next();
- if (obj != null) {
- values.add(obj.toString());
- }
- }
- }
-
try {
- decodeProperty(newProperties, path, pd, values);
+ decodeProperty(newProperties, path, pd, attribute);
} catch (PropertyException e) {
exceptions.add(e);
}
@@ -193,12 +252,23 @@
/**
* {@inheritDoc}
*/
+ @SuppressWarnings("unchecked")
@Override
- public <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path,
+ public <C extends ConfigurationClient, S extends Configuration, PD>
+ SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path,
PropertyDefinition<PD> pd) throws IllegalArgumentException,
DefinitionDecodingException, AuthorizationException,
ManagedObjectNotFoundException, CommunicationException,
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());
+ }
+
if (!managedObjectExists(path)) {
throw new ManagedObjectNotFoundException();
}
@@ -206,26 +276,27 @@
try {
// Read the entry associated with the managed object.
LdapName dn = LDAPNameBuilder.create(path, profile);
- AbstractManagedObjectDefinition<?, ?> d = path
- .getManagedObjectDefinition();
- ManagedObjectDefinition<?, ?> mod = getEntryDefinition(d, dn);
+ ManagedObjectDefinition<? extends C, ? extends S> mod;
+ mod = getEntryDefinition(d, dn);
+
+ // 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());
String attrID = profile.getAttributeName(mod, pd);
Attributes attributes = connection.readEntry(dn, Collections
.singleton(attrID));
Attribute attribute = attributes.get(attrID);
+ // Decode the values.
SortedSet<PD> values = new TreeSet<PD>(pd);
- if (attribute == null || attribute.size() == 0) {
- // Use the property's default values.
- values.addAll(findDefaultValues(path, pd, false));
- } else {
- // Decode the values.
+ if (attribute != null) {
NamingEnumeration<?> ldapValues = attribute.getAll();
while (ldapValues.hasMore()) {
Object obj = ldapValues.next();
if (obj != null) {
- PD value = pd.decodeValue(obj.toString());
+ PD value = ValueDecoder.decode(pd, obj);
values.add(value);
}
}
@@ -240,6 +311,11 @@
throw new PropertyIsMandatoryException(pd);
}
+ if (values.isEmpty()) {
+ // Use the property's default values.
+ values.addAll(findDefaultValues(path.asSubType(mod), pd, false));
+ }
+
return values;
} catch (NameNotFoundException e) {
throw new ManagedObjectNotFoundException();
@@ -471,24 +547,28 @@
// Create a property using the provided string values.
private <PD> void decodeProperty(PropertySet newProperties,
- ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, List<String> values)
- throws PropertyException {
+ ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd,
+ Attribute attribute) throws PropertyException,
+ NamingException {
PropertyException exception = null;
// Get the property's active values.
- Collection<PD> activeValues = new ArrayList<PD>(values.size());
- for (String value : values) {
- try {
- activeValues.add(pd.decodeValue(value));
- } catch (IllegalPropertyValueStringException e) {
- exception = e;
+ SortedSet<PD> activeValues = new TreeSet<PD>(pd);
+ if (attribute != null) {
+ NamingEnumeration<?> ldapValues = attribute.getAll();
+ while (ldapValues.hasMore()) {
+ Object obj = ldapValues.next();
+ if (obj != null) {
+ PD value = ValueDecoder.decode(pd, obj);
+ activeValues.add(value);
+ }
}
}
if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
// This exception takes precedence over previous exceptions.
exception = new PropertyIsSingleValuedException(pd);
- PD value = activeValues.iterator().next();
+ PD value = activeValues.first();
activeValues.clear();
activeValues.add(value);
}
--
Gitblit v1.10.0