From 506eee12c5fe5d42d3f90662289426e6cc8aed76 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 31 Aug 2007 22:06:04 +0000
Subject: [PATCH] Fix issue 1734: Admin framework: refactor client APIs
---
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java | 595 ++++++++++
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java | 696 +++++++++++
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Property.java | 67
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/PropertySet.java | 127 -
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java | 38
opendj-sdk/opends/src/server/org/opends/server/admin/client/package-info.java | 8
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/package-info.java | 39
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java | 701 +++++++++++
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java | 1162 +-----------------
opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagementContext.java | 28
opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java | 46
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/spi/PropertySetTest.java | 5
12 files changed, 2,244 insertions(+), 1,268 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
index d34b3e0..e2be911 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
@@ -216,7 +216,7 @@
/**
- * Retrieve an instantiable child managed object.
+ * Retrieves an instantiable child managed object.
*
* @param <C>
* The requested type of the child managed object
@@ -262,7 +262,7 @@
/**
- * Retrieve an optional child managed object.
+ * Retrieves an optional child managed object.
*
* @param <C>
* The requested type of the child managed object
@@ -306,7 +306,7 @@
/**
- * Retrieve a singleton child managed object.
+ * Retrieves a singleton child managed object.
*
* @param <C>
* The requested type of the child managed object
@@ -362,7 +362,7 @@
/**
- * Get the definition associated with this managed object.
+ * Gets the definition associated with this managed object.
*
* @return Returns the definition associated with this managed
* object.
@@ -373,7 +373,7 @@
/**
- * Get the path of this managed object.
+ * Gets the path of this managed object.
*
* @return Returns the path of this managed object.
*/
@@ -382,30 +382,31 @@
/**
- * Get the default values of the specified property.
+ * Gets a mutable copy of the set of default values for the
+ * specified property.
*
- * @param <P>
+ * @param <PD>
* The type of the property to be retrieved.
* @param pd
* The property to be retrieved.
- * @return Returns the property's default values, or an empty set
- * if there are no default values defined.
+ * @return Returns the property's default values, or an empty set if
+ * there are no default values defined.
* @throws IllegalArgumentException
* If the property definition is not associated with this
* managed object's definition.
*/
- <P> SortedSet<P> getPropertyDefaultValues(PropertyDefinition<P> pd)
+ <PD> SortedSet<PD> getPropertyDefaultValues(PropertyDefinition<PD> pd)
throws IllegalArgumentException;
/**
- * Get the effective value of the specified property.
+ * Gets the effective value of the specified property.
* <p>
* See the class description for more information about how the
* effective property value is derived.
*
- * @param <P>
+ * @param <PD>
* The type of the property to be retrieved.
* @param pd
* The property to be retrieved.
@@ -416,18 +417,19 @@
* If the property definition is not associated with this
* managed object's definition.
*/
- <P> P getPropertyValue(PropertyDefinition<P> pd)
+ <PD> PD getPropertyValue(PropertyDefinition<PD> pd)
throws IllegalArgumentException;
/**
- * Get the effective values of the specified property.
+ * Gets a mutable copy of the set of effective values for the
+ * specified property.
* <p>
* See the class description for more information about how the
* effective property values are derived.
*
- * @param <P>
+ * @param <PD>
* The type of the property to be retrieved.
* @param pd
* The property to be retrieved.
@@ -437,7 +439,7 @@
* If the property definition is not associated with this
* managed object's definition.
*/
- <P> SortedSet<P> getPropertyValues(PropertyDefinition<P> pd)
+ <PD> SortedSet<PD> getPropertyValues(PropertyDefinition<PD> pd)
throws IllegalArgumentException;
@@ -653,12 +655,12 @@
/**
- * Set a new pending value for the specified property.
+ * Sets a new pending value for the specified property.
* <p>
* See the class description for more information regarding pending
* values.
*
- * @param <P>
+ * @param <PD>
* The type of the property to be modified.
* @param pd
* The property to be modified.
@@ -678,19 +680,19 @@
* If the specified property definition is not associated
* with this managed object.
*/
- <P> void setPropertyValue(PropertyDefinition<P> pd, P value)
+ <PD> void setPropertyValue(PropertyDefinition<PD> pd, PD value)
throws IllegalPropertyValueException, PropertyIsReadOnlyException,
PropertyIsMandatoryException, IllegalArgumentException;
/**
- * Set a new pending values for the specified property.
+ * Sets a new pending values for the specified property.
* <p>
* See the class description for more information regarding pending
* values.
*
- * @param <P>
+ * @param <PD>
* The type of the property to be modified.
* @param pd
* The property to be modified.
@@ -714,7 +716,7 @@
* If the specified property definition is not associated
* with this managed object.
*/
- <P> void setPropertyValues(PropertyDefinition<P> pd, Collection<P> values)
+ <PD> void setPropertyValues(PropertyDefinition<PD> pd, Collection<PD> values)
throws IllegalPropertyValueException, PropertyIsSingleValuedException,
PropertyIsReadOnlyException, PropertyIsMandatoryException,
IllegalArgumentException;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagementContext.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagementContext.java
index f454869..818706a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagementContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagementContext.java
@@ -34,7 +34,7 @@
/**
- * Management connection context.
+ * Client management connection context.
*/
public abstract class ManagementContext {
@@ -48,21 +48,9 @@
/**
- * Get the root configuration managed object associated with this
+ * Gets the root configuration client associated with this
* management context.
*
- * @return Returns the root configuration managed object associated
- * with this management context.
- */
- public abstract ManagedObject<RootCfgClient>
- getRootConfigurationManagedObject();
-
-
-
- /**
- * Get the root configuration client associated with this management
- * context.
- *
* @return Returns the root configuration client associated with
* this management context.
*/
@@ -70,4 +58,16 @@
return getRootConfigurationManagedObject().getConfiguration();
}
+
+
+ /**
+ * Gets the root configuration managed object associated with this
+ * management context.
+ *
+ * @return Returns the root configuration managed object associated
+ * with this management context.
+ */
+ public abstract
+ ManagedObject<RootCfgClient> getRootConfigurationManagedObject();
+
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
new file mode 100644
index 0000000..481e8c0
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -0,0 +1,595 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.Configuration;
+import org.opends.server.admin.ConfigurationClient;
+import org.opends.server.admin.DefaultBehaviorException;
+import org.opends.server.admin.DefinitionDecodingException;
+import org.opends.server.admin.DefinitionResolver;
+import org.opends.server.admin.IllegalPropertyValueStringException;
+import org.opends.server.admin.InstantiableRelationDefinition;
+import org.opends.server.admin.LDAPProfile;
+import org.opends.server.admin.ManagedObjectDefinition;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.ManagedObjectPath;
+import org.opends.server.admin.OptionalRelationDefinition;
+import org.opends.server.admin.PropertyDefinition;
+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.RelationDefinition;
+import org.opends.server.admin.DefinitionDecodingException.Reason;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.OperationRejectedException;
+import org.opends.server.admin.client.spi.Driver;
+import org.opends.server.admin.client.spi.PropertySet;
+
+
+
+/**
+ * The LDAP management context driver implementation.
+ */
+final class LDAPDriver extends Driver {
+
+ // The LDAP connection.
+ private final LDAPConnection connection;
+
+ // The LDAP profile which should be used to construct LDAP
+ // requests and decode LDAP responses.
+ private final LDAPProfile profile;
+
+
+
+ /**
+ * Creates a new LDAP driver using the specified LDAP connection and
+ * profile.
+ *
+ * @param connection
+ * The LDAP connection.
+ * @param profile
+ * The LDAP profile.
+ */
+ public LDAPDriver(LDAPConnection connection, LDAPProfile profile) {
+ this.connection = connection;
+ this.profile = profile;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ boolean deleteManagedObject(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+ String name) throws IllegalArgumentException,
+ ManagedObjectNotFoundException, OperationRejectedException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(parent, rd);
+
+ if (!entryExists(parent)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ return removeManagedObject(parent.child(rd, name));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ boolean deleteManagedObject(
+ ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, AuthorizationException,
+ CommunicationException {
+ validateRelationDefinition(parent, rd);
+
+ if (!entryExists(parent)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ return removeManagedObject(parent.child(rd));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getManagedObject(
+ ManagedObjectPath<C, S> path) throws DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException {
+ if (!entryExists(path)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ try {
+ // Read the entry associated with the managed object.
+ LdapName dn = LDAPNameBuilder.create(path, profile);
+ AbstractManagedObjectDefinition<C, S> d = path
+ .getManagedObjectDefinition();
+ ManagedObjectDefinition<? extends C, ? extends S> mod =
+ getEntryDefinition(d, dn);
+
+ ArrayList<String> attrIds = new ArrayList<String>();
+ for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
+ String attrId = profile.getAttributeName(mod, pd);
+ attrIds.add(attrId);
+ }
+
+ Attributes attributes = connection.readEntry(dn, attrIds);
+
+ // Build the managed object's properties.
+ List<PropertyException> exceptions = new LinkedList<PropertyException>();
+ PropertySet newProperties = new PropertySet();
+ 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);
+ } catch (PropertyException e) {
+ exceptions.add(e);
+ }
+ }
+
+ // If there were no decoding problems then return the object,
+ // otherwise throw an operations exception.
+ ManagedObject<? extends C> mo = createExistingManagedObject(mod, path,
+ newProperties);
+ if (exceptions.isEmpty()) {
+ return mo;
+ } else {
+ throw new ManagedObjectDecodingException(mo, exceptions);
+ }
+ } catch (NameNotFoundException e) {
+ throw new ManagedObjectNotFoundException();
+ } catch (NoPermissionException e) {
+ throw new AuthorizationException(e);
+ } catch (NamingException e) {
+ throw new CommunicationException(e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path,
+ PropertyDefinition<PD> pd) throws IllegalArgumentException,
+ DefinitionDecodingException, AuthorizationException,
+ ManagedObjectNotFoundException, CommunicationException,
+ PropertyException {
+ if (!entryExists(path)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ try {
+ // Read the entry associated with the managed object.
+ LdapName dn = LDAPNameBuilder.create(path, profile);
+ AbstractManagedObjectDefinition<?, ?> d = path
+ .getManagedObjectDefinition();
+ ManagedObjectDefinition<?, ?> mod = getEntryDefinition(d, dn);
+
+ String attrID = profile.getAttributeName(mod, pd);
+ Attributes attributes = connection.readEntry(dn, Collections
+ .singleton(attrID));
+ Attribute attribute = attributes.get(attrID);
+
+ 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.
+ NamingEnumeration<?> ldapValues = attribute.getAll();
+ while (ldapValues.hasMore()) {
+ Object obj = ldapValues.next();
+ if (obj != null) {
+ PD value = pd.decodeValue(obj.toString());
+ values.add(value);
+ }
+ }
+ }
+
+ // Sanity check the returned values.
+ if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+ throw new PropertyIsSingleValuedException(pd);
+ }
+
+ if (values.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
+ throw new PropertyIsMandatoryException(pd);
+ }
+
+ return values;
+ } catch (NameNotFoundException e) {
+ throw new ManagedObjectNotFoundException();
+ } catch (NoPermissionException e) {
+ throw new AuthorizationException(e);
+ } catch (NamingException e) {
+ throw new CommunicationException(e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ boolean hasManagedObject(
+ ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(parent, rd);
+
+ if (!entryExists(parent)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ return entryExists(parent.child(rd));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(parent, rd);
+
+ if (!entryExists(parent)) {
+ throw new ManagedObjectNotFoundException();
+ }
+
+ // Get the search base DN.
+ LdapName dn = LDAPNameBuilder.create(parent, rd, profile);
+
+ // Retrieve only those entries which are sub-types of the
+ // specified definition.
+ StringBuilder builder = new StringBuilder();
+ builder.append("(objectclass=");
+ builder.append(profile.getObjectClass(d));
+ builder.append(')');
+ String filter = builder.toString();
+
+ List<String> children = new ArrayList<String>();
+ try {
+ for (LdapName child : connection.listEntries(dn, filter)) {
+ children.add(child.getRdn(child.size() - 1).getValue().toString());
+ }
+ } catch (NameNotFoundException e) {
+ // Ignore this - it means that the base entry does not exist
+ // (which it might not if this managed object has just been
+ // created.
+ } catch (NamingException e) {
+ adaptNamingException(e);
+ }
+
+ return children.toArray(new String[children.size()]);
+ }
+
+
+
+ /**
+ * Adapts a naming exception to an appropriate admin client
+ * exception.
+ *
+ * @param ne
+ * The naming exception.
+ * @throws CommunicationException
+ * If the naming exception mapped to a communication
+ * exception.
+ * @throws AuthorizationException
+ * If the naming exception mapped to an authorization
+ * exception.
+ */
+ void adaptNamingException(NamingException ne) throws CommunicationException,
+ AuthorizationException {
+ try {
+ throw ne;
+ } catch (javax.naming.CommunicationException e) {
+ throw new CommunicationException(e);
+ } catch (javax.naming.ServiceUnavailableException e) {
+ throw new CommunicationException(e);
+ } catch (javax.naming.NoPermissionException e) {
+ throw new AuthorizationException(e);
+ } catch (NamingException e) {
+ // Just treat it as a communication problem.
+ throw new CommunicationException(e);
+ }
+ }
+
+
+
+ /**
+ * Determines whether the named LDAP entry exists.
+ *
+ * @param dn
+ * The LDAP entry name.
+ * @return Returns <code>true</code> if the named LDAP entry
+ * exists.
+ * @throws AuthorizationException
+ * If the server refuses to make the determination because
+ * the client does not have the correct privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ boolean entryExists(LdapName dn) throws CommunicationException,
+ AuthorizationException {
+ try {
+ return connection.entryExists(dn);
+ } catch (NamingException e) {
+ adaptNamingException(e);
+ }
+ return false;
+ }
+
+
+
+ /**
+ * Gets the LDAP connection used for interacting with the server.
+ *
+ * @return Returns the LDAP connection used for interacting with the
+ * server.
+ */
+ LDAPConnection getLDAPConnection() {
+ return connection;
+ }
+
+
+
+ /**
+ * Gets the LDAP profile which should be used to construct LDAP
+ * requests and decode LDAP responses.
+ *
+ * @return Returns the LDAP profile which should be used to
+ * construct LDAP requests and decode LDAP responses.
+ */
+ LDAPProfile getLDAPProfile() {
+ return profile;
+ }
+
+
+
+ // Create a managed object which already exists on the server.
+ private <M extends ConfigurationClient, N extends Configuration>
+ ManagedObject<M> createExistingManagedObject(
+ ManagedObjectDefinition<M, N> d,
+ ManagedObjectPath<? super M, ? super N> p, PropertySet properties) {
+ RelationDefinition<?, ?> rd = p.getRelationDefinition();
+ PropertyDefinition<?> pd = null;
+ if (rd instanceof InstantiableRelationDefinition) {
+ InstantiableRelationDefinition<?, ?> ird =
+ (InstantiableRelationDefinition<?, ?>) rd;
+ pd = ird.getNamingPropertyDefinition();
+ }
+ return new LDAPManagedObject<M>(this, d, p.asSubType(d), properties, true,
+ pd);
+ }
+
+
+
+ // Create a property using the provided string values.
+ private <PD> void decodeProperty(PropertySet newProperties,
+ ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, List<String> values)
+ throws PropertyException {
+ 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;
+ }
+ }
+
+ 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();
+ activeValues.clear();
+ activeValues.add(value);
+ }
+
+ if (activeValues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
+ // The active values maybe empty because of a previous
+ // exception.
+ if (exception == null) {
+ exception = new PropertyIsMandatoryException(pd);
+ }
+ }
+
+ // Get the property's default values.
+ Collection<PD> defaultValues;
+ try {
+ defaultValues = findDefaultValues(p, pd, false);
+ } catch (DefaultBehaviorException e) {
+ defaultValues = Collections.emptySet();
+ exception = e;
+ }
+
+ newProperties.addProperty(pd, defaultValues, activeValues);
+ if (exception != null) {
+ throw exception;
+ }
+ }
+
+
+
+ // Determines whether the LDAP entry associated with the managed
+ // object path exists.
+ private boolean entryExists(ManagedObjectPath<?, ?> path)
+ throws CommunicationException, AuthorizationException {
+ if (path.isEmpty()) {
+ return true;
+ }
+
+ LdapName dn = LDAPNameBuilder.create(path, profile);
+ return entryExists(dn);
+ }
+
+
+
+ // Determine the type of managed object associated with the named
+ // entry.
+ private <C extends ConfigurationClient, S extends Configuration>
+ ManagedObjectDefinition<? extends C, ? extends S> getEntryDefinition(
+ AbstractManagedObjectDefinition<C, S> d, LdapName dn)
+ throws NamingException, DefinitionDecodingException {
+ Attributes attributes = connection.readEntry(dn, Collections
+ .singleton("objectclass"));
+ Attribute oc = attributes.get("objectclass");
+
+ if (oc == null) {
+ // No object classes.
+ throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
+ }
+
+ final Set<String> objectClasses = new HashSet<String>();
+ NamingEnumeration<?> values = oc.getAll();
+ while (values.hasMore()) {
+ Object value = values.next();
+ if (value != null) {
+ objectClasses.add(value.toString().toLowerCase().trim());
+ }
+ }
+
+ if (objectClasses.isEmpty()) {
+ // No object classes.
+ throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
+ }
+
+ // Resolve the appropriate sub-type based on the object classes.
+ DefinitionResolver resolver = new DefinitionResolver() {
+
+ public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
+ String objectClass = profile.getObjectClass(d);
+ return objectClasses.contains(objectClass);
+ }
+
+ };
+
+ return d.resolveManagedObjectDefinition(resolver);
+ }
+
+
+
+ // Remove the named managed object.
+ private boolean removeManagedObject(ManagedObjectPath<?, ?> path)
+ throws CommunicationException, AuthorizationException,
+ OperationRejectedException, ManagedObjectNotFoundException {
+ if (!entryExists(path)) {
+ return false;
+ }
+
+ // Delete the entry and any subordinate entries.
+ LdapName dn = LDAPNameBuilder.create(path, profile);
+ try {
+ connection.deleteSubtree(dn);
+ } catch (OperationNotSupportedException e) {
+ // Unwilling to perform.
+ throw new OperationRejectedException(e);
+ } catch (NamingException e) {
+ adaptNamingException(e);
+ }
+
+ return true;
+ }
+
+
+
+ // Validate that a relation definition belongs to this managed
+ // object.
+ 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());
+ }
+ }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
index 16120aa..fbdf4df 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -29,18 +29,7 @@
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
-
import javax.naming.NameAlreadyBoundException;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.OperationNotSupportedException;
@@ -51,46 +40,24 @@
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
-import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
-import org.opends.server.admin.AbstractManagedObjectDefinition;
-import org.opends.server.admin.AliasDefaultBehaviorProvider;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
-import org.opends.server.admin.DefaultBehaviorException;
-import org.opends.server.admin.DefaultBehaviorProviderVisitor;
-import org.opends.server.admin.DefinedDefaultBehaviorProvider;
-import org.opends.server.admin.DefinitionDecodingException;
-import org.opends.server.admin.DefinitionResolver;
-import org.opends.server.admin.IllegalPropertyValueException;
-import org.opends.server.admin.IllegalPropertyValueStringException;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectDefinition;
-import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectPath;
-import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
-import org.opends.server.admin.PropertyException;
-import org.opends.server.admin.PropertyIsMandatoryException;
-import org.opends.server.admin.PropertyIsReadOnlyException;
-import org.opends.server.admin.PropertyIsSingleValuedException;
-import org.opends.server.admin.PropertyNotFoundException;
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelationDefinition;
-import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
-import org.opends.server.admin.SingletonRelationDefinition;
-import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
-import org.opends.server.admin.DefinitionDecodingException.Reason;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
-import org.opends.server.admin.client.IllegalManagedObjectNameException;
import org.opends.server.admin.client.ManagedObject;
-import org.opends.server.admin.client.ManagedObjectDecodingException;
-import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
-import org.opends.server.admin.client.Property;
-import org.opends.server.admin.client.PropertySet;
+import org.opends.server.admin.client.spi.AbstractManagedObject;
+import org.opends.server.admin.client.spi.Driver;
+import org.opends.server.admin.client.spi.Property;
+import org.opends.server.admin.client.spi.PropertySet;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.meta.RootCfgDefn;
@@ -103,384 +70,55 @@
* The type of client configuration represented by the client
* managed object.
*/
-final class LDAPManagedObject<T extends ConfigurationClient> implements
- ManagedObject<T> {
+final class LDAPManagedObject<T extends ConfigurationClient> extends
+ AbstractManagedObject<T> {
/**
- * A default behavior visitor used for retrieving the default values
- * of a property.
+ * Constructs a root LDAP managed object associated with the
+ * provided LDAP driver.
*
- * @param <T>
- * The type of the property.
- */
- private static class DefaultValueFinder<T> implements
- DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
-
- /**
- * Get the default values for the specified property.
- *
- * @param <T>
- * The type of the property.
- * @param context
- * The LDAP management context.
- * @param p
- * The managed object path of the current managed object.
- * @param pd
- * The property definition.
- * @param isCreate
- * Indicates whether the managed object has been created
- * yet.
- * @return Returns the default values for the specified property.
- * @throws DefaultBehaviorException
- * If the default values could not be retrieved or
- * decoded properly.
- */
- public static <T> Collection<T> getDefaultValues(
- LDAPManagementContext context, ManagedObjectPath<?, ?> p,
- PropertyDefinition<T> pd, boolean isCreate)
- throws DefaultBehaviorException {
- DefaultValueFinder<T> v = new DefaultValueFinder<T>(context, p, isCreate);
- return v.find(p, pd);
- }
-
- // The LDAP management context.
- private final LDAPManagementContext context;
-
- // Any exception that occurred whilst retrieving inherited default
- // values.
- private DefaultBehaviorException exception = null;
-
- // Indicates whether the managed object has been created yet.
- private final boolean isCreate;
-
- // The path of the managed object containing the first property.
- private final ManagedObjectPath<?, ?> firstPath;
-
- // 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;
-
-
-
- // Private constructor.
- private DefaultValueFinder(LDAPManagementContext context,
- ManagedObjectPath<?, ?> p, boolean isCreate) {
- this.context = context;
- this.firstPath = p;
- this.isCreate = isCreate;
- }
-
-
-
- /**
- * {@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 {
- this.nextPath = p;
- this.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(Reason.WRONG_TYPE_INFORMATION));
- }
-
- // Save the current property in case of recursion.
- PropertyDefinition<T> pd1 = nextProperty;
-
- try {
- // If the path relates to the current managed object and the
- // managed object is in the process of being created it won't
- // exist, so we should just use the default values of the
- // referenced property.
- if (isCreate && firstPath.equals(target)) {
- PropertyDefinition<T> pd2;
- try {
- // FIXME: we use the definition taken from the default
- // behavior here when we should really use the exact
- // definition of the component being created.
- PropertyDefinition<?> pdTmp = d.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);
- }
-
- // Recursively retrieve this property's default values.
- Collection<T> tmp = find(target, pd2);
- Collection<T> values = new ArrayList<T>(tmp.size());
- for (T value : tmp) {
- pd1.validateValue(value);
- values.add(value);
- }
- return values;
- } else {
- // Get the actual managed object definition.
- LdapName dn = LDAPNameBuilder
- .create(target, context.getLDAPProfile());
- ManagedObjectDefinition<?, ?> mod =
- getEntryDefinition(context, d, dn);
-
- 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);
- }
-
- String attrID = context.getLDAPProfile().getAttributeName(mod, pd2);
- Attributes attributes = context.getLDAPConnection().readEntry(dn,
- Collections.singleton(attrID));
- Attribute attr = attributes.get(attrID);
- if (attr == null || attr.size() == 0) {
- // Recursively retrieve this property's default values.
- Collection<T> tmp = find(target, pd2);
- Collection<T> values = new ArrayList<T>(tmp.size());
- for (T value : tmp) {
- pd1.validateValue(value);
- values.add(value);
- }
- return values;
- } else {
- Collection<T> values = new LinkedList<T>();
- NamingEnumeration<?> ne = attr.getAll();
- while (ne.hasMore()) {
- Object value = ne.next();
- if (value != null) {
- values.add(pd1.decodeValue(value.toString()));
- }
- }
- return values;
- }
- }
- } catch (DefaultBehaviorException e) {
- // Wrap any errors due to recursion.
- throw new DefaultBehaviorException(pd1, e);
- } 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 (NameNotFoundException e) {
- throw new DefaultBehaviorException(pd1,
- new ManagedObjectNotFoundException());
- } catch (NoPermissionException e) {
- throw new DefaultBehaviorException(pd1, new AuthorizationException(e));
- } catch (NamingException e) {
- throw new DefaultBehaviorException(pd1, new CommunicationException(e));
- }
- }
- };
-
-
-
- /**
- * Construct a root LDAP managed object associated with the provided
- * LDAP context.
- *
- * @param context
- * The LDAP management context.
+ * @param driver
+ * The LDAP management driver.
* @return Returns a root LDAP managed object associated with the
- * provided LDAP context.
+ * provided LDAP driver.
*/
static ManagedObject<RootCfgClient> getRootManagedObject(
- LDAPManagementContext context) {
- return new LDAPManagedObject<RootCfgClient>(context, RootCfgDefn
+ LDAPDriver driver) {
+ return new LDAPManagedObject<RootCfgClient>(driver, RootCfgDefn
.getInstance(), ManagedObjectPath.emptyPath(), new PropertySet(), true,
null);
}
-
-
- // Determine the type of managed object associated with the named
- // entry.
- private static <M extends ConfigurationClient, N extends Configuration>
- ManagedObjectDefinition<? extends M, ? extends N> getEntryDefinition(
- final LDAPManagementContext context,
- AbstractManagedObjectDefinition<M, N> d, LdapName dn)
- throws NamingException, DefinitionDecodingException {
- Attributes attributes = context.getLDAPConnection().readEntry(dn,
- Collections.singleton("objectclass"));
- Attribute oc = attributes.get("objectclass");
-
- if (oc == null) {
- // No object classes.
- throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
- }
-
- final Set<String> objectClasses = new HashSet<String>();
- NamingEnumeration<?> values = oc.getAll();
- while (values.hasMore()) {
- Object value = values.next();
- if (value != null) {
- objectClasses.add(value.toString().toLowerCase().trim());
- }
- }
-
- if (objectClasses.isEmpty()) {
- // No object classes.
- throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
- }
-
- // Resolve the appropriate sub-type based on the object classes.
- DefinitionResolver resolver = new DefinitionResolver() {
-
- public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
- String objectClass = context.getLDAPProfile().getObjectClass(d);
- return objectClasses.contains(objectClass);
- }
-
- };
-
- return d.resolveManagedObjectDefinition(resolver);
- }
-
- // The LDAP management context used for the ldap connection.
- private final LDAPManagementContext context;
-
- // The managed object definition associated with this managed
- // object.
- private final ManagedObjectDefinition<T, ? extends Configuration> definition;
-
- // Indicates whether or not this managed object exists on the server
- // (false means the managed object is new and has not been
- // committed).
- private boolean existsOnServer;
-
- // Optional naming property definition.
- private final PropertyDefinition<?> namingPropertyDefinition;
-
- // The path associated with this managed object.
- private ManagedObjectPath<T, ? extends Configuration> path;
-
- // The managed object's properties.
- private final PropertySet properties;
+ // The LDAP management driver associated with this managed object.
+ private final LDAPDriver driver;
- // Create an new LDAP managed object with the provided JNDI context.
- private LDAPManagedObject(LDAPManagementContext context,
+ /**
+ * Creates a new LDAP managed object instance.
+ *
+ * @param driver
+ * The underlying LDAP management driver.
+ * @param d
+ * The managed object's definition.
+ * @param path
+ * The managed object's path.
+ * @param properties
+ * The managed object's properties.
+ * @param existsOnServer
+ * Indicates whether or not the managed object already
+ * exists.
+ * @param namingPropertyDefinition
+ * The managed object's naming property definition if there
+ * is one.
+ */
+ LDAPManagedObject(LDAPDriver driver,
ManagedObjectDefinition<T, ? extends Configuration> d,
ManagedObjectPath<T, ? extends Configuration> path,
PropertySet properties, boolean existsOnServer,
PropertyDefinition<?> namingPropertyDefinition) {
- this.definition = d;
- this.context = context;
- this.path = path;
- this.properties = properties;
- this.existsOnServer = existsOnServer;
- this.namingPropertyDefinition = namingPropertyDefinition;
+ super(d, path, properties, existsOnServer, namingPropertyDefinition);
+ this.driver = driver;
}
@@ -488,411 +126,16 @@
/**
* {@inheritDoc}
*/
- public void commit() throws MissingMandatoryPropertiesException,
- ConcurrentModificationException, OperationRejectedException,
- AuthorizationException, CommunicationException,
- ManagedObjectAlreadyExistsException {
- // First make sure all mandatory properties are defined.
- List<PropertyIsMandatoryException> exceptions =
- new LinkedList<PropertyIsMandatoryException>();
-
- for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
- Property<?> p = properties.getProperty(pd);
- if (pd.hasOption(PropertyOption.MANDATORY)
- && p.getEffectiveValues().isEmpty()) {
- exceptions.add(new PropertyIsMandatoryException(pd));
- }
- }
-
- if (!exceptions.isEmpty()) {
- throw new MissingMandatoryPropertiesException(exceptions);
- }
-
- // Commit the managed object.
- if (existsOnServer) {
- commitExistingManagedObject();
- } else {
- commitNewManagedObject();
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration, CC extends C>
- ManagedObject<CC> createChild(InstantiableRelationDefinition<C, S> r,
- ManagedObjectDefinition<CC, ? extends S> d, String name,
- Collection<DefaultBehaviorException> exceptions)
- throws IllegalManagedObjectNameException, IllegalArgumentException {
- validateRelationDefinition(r);
-
- // Empty names are not allowed.
- if (name.trim().length() == 0) {
- throw new IllegalManagedObjectNameException(name);
- }
-
- // If the relation uses a naming property definition then it must
- // be a valid value.
- PropertyDefinition<?> pd = r.getNamingPropertyDefinition();
- if (pd != null) {
- try {
- pd.decodeValue(name);
- } catch (IllegalPropertyValueStringException e) {
- throw new IllegalManagedObjectNameException(name, pd);
- }
- }
-
- ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d, name);
- return createNewManagedObject(d, childPath, pd, name, exceptions);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration, CC extends C>
- ManagedObject<CC> createChild(OptionalRelationDefinition<C, S> r,
- ManagedObjectDefinition<CC, ? extends S> d,
- Collection<DefaultBehaviorException> exceptions)
- throws IllegalArgumentException {
- validateRelationDefinition(r);
- ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d);
- return createNewManagedObject(d, childPath, null, null, exceptions);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- ManagedObject<? extends C> getChild(InstantiableRelationDefinition<C, S> r,
- String name) throws IllegalArgumentException, DefinitionDecodingException,
- ManagedObjectDecodingException, ManagedObjectNotFoundException,
- ConcurrentModificationException, AuthorizationException,
- CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
- return readManagedObject(r.getChildDefinition(), path.child(r, name));
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- ManagedObject<? extends C> getChild(OptionalRelationDefinition<C, S> r)
- throws IllegalArgumentException, DefinitionDecodingException,
- ManagedObjectDecodingException, ManagedObjectNotFoundException,
- ConcurrentModificationException, AuthorizationException,
- CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
- return readManagedObject(r.getChildDefinition(), path.child(r));
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- ManagedObject<? extends C> getChild(
- SingletonRelationDefinition<C, S> r) throws IllegalArgumentException,
- DefinitionDecodingException, ManagedObjectDecodingException,
- ManagedObjectNotFoundException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
- return readManagedObject(r.getChildDefinition(), path.child(r));
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public T getConfiguration() {
- return definition.createClientConfiguration(this);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public ManagedObjectDefinition<T, ? extends Configuration>
- getManagedObjectDefinition() {
- return definition;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath() {
- return path;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <P> SortedSet<P> getPropertyDefaultValues(PropertyDefinition<P> pd)
- throws IllegalArgumentException {
- Property<P> p = properties.getProperty(pd);
- return p.getDefaultValues();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <P> P getPropertyValue(PropertyDefinition<P> pd)
- throws IllegalArgumentException {
- return properties.getPropertyValue(pd);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <P> SortedSet<P> getPropertyValues(PropertyDefinition<P> pd)
- throws IllegalArgumentException {
- return properties.getPropertyValues(pd);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isPropertyPresent(PropertyDefinition<?> pd)
- throws IllegalArgumentException {
- Property<?> p = properties.getProperty(pd);
- return !p.isEmpty();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- boolean hasChild(OptionalRelationDefinition<C, S> r)
- throws IllegalArgumentException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
-
- ManagedObjectPath<C, S> p = path.child(r);
- LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
- return entryExists(dn);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- String[] listChildren(InstantiableRelationDefinition<C, S> r)
- throws IllegalArgumentException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- return listChildren(r, r.getChildDefinition());
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- String[] listChildren(InstantiableRelationDefinition<C, S> r,
- AbstractManagedObjectDefinition<? extends C, ? extends S> d)
- throws IllegalArgumentException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
-
- // Get the search base DN.
- LdapName dn = LDAPNameBuilder.create(path, r, context.getLDAPProfile());
-
- // Retrieve only those entries which are sub-types of the
- // specified definition.
- StringBuilder builder = new StringBuilder();
- builder.append("(objectclass=");
- builder.append(context.getLDAPProfile().getObjectClass(d));
- builder.append(')');
- String filter = builder.toString();
-
- List<String> children = new ArrayList<String>();
- try {
- for (LdapName child :
- context.getLDAPConnection().listEntries(dn, filter)) {
- children.add(child.getRdn(child.size() - 1).getValue().toString());
- }
- } catch (NameNotFoundException e) {
- // Ignore this - it means that the base entry does not exist
- // (which it might not if this managed object has just been
- // created.
- } catch (NamingException e) {
- adaptNamingException(e);
- }
- return children.toArray(new String[children.size()]);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- void removeChild(InstantiableRelationDefinition<C, S> r, String name)
- throws IllegalArgumentException, ManagedObjectNotFoundException,
- OperationRejectedException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
- ManagedObjectPath<C, S> p = path.child(r, name);
- removeManagedObject(p);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <C extends ConfigurationClient, S extends Configuration>
- void removeChild(OptionalRelationDefinition<C, S> r)
- throws IllegalArgumentException, ManagedObjectNotFoundException,
- OperationRejectedException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- validateRelationDefinition(r);
- ensureThisManagedObjectExists();
- ManagedObjectPath<C, S> p = path.child(r);
- removeManagedObject(p);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <P> void setPropertyValue(PropertyDefinition<P> pd, P value)
- throws IllegalPropertyValueException, PropertyIsReadOnlyException,
- PropertyIsMandatoryException, IllegalArgumentException {
- if (value == null) {
- setPropertyValues(pd, Collections.<P> emptySet());
- } else {
- setPropertyValues(pd, Collections.singleton(value));
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public <P> void setPropertyValues(PropertyDefinition<P> pd,
- Collection<P> values) throws IllegalPropertyValueException,
- PropertyIsSingleValuedException, PropertyIsReadOnlyException,
- PropertyIsMandatoryException, IllegalArgumentException {
- if (pd.hasOption(PropertyOption.MONITORING)) {
- throw new PropertyIsReadOnlyException(pd);
- }
-
- if (existsOnServer && pd.hasOption(PropertyOption.READ_ONLY)) {
- throw new PropertyIsReadOnlyException(pd);
- }
-
- properties.setPropertyValues(pd, values);
-
- // If this is a naming property then update the name.
- if (pd.equals(namingPropertyDefinition)) {
- // The property must be single-valued and mandatory.
- String newName = pd.encodeValue(values.iterator().next());
- path = path.rename(newName);
- }
- }
-
- // Adapts a naming exception to an appropriate admin client
- // exception.
- private void adaptNamingException(NamingException ne)
- throws CommunicationException, AuthorizationException {
- try {
- throw ne;
- } catch (javax.naming.CommunicationException e) {
- throw new CommunicationException(e);
- } catch (javax.naming.ServiceUnavailableException e) {
- throw new CommunicationException(e);
- } catch (javax.naming.NoPermissionException e) {
- throw new AuthorizationException(e);
- } catch (NamingException e) {
- // Just treat it as a communication problem.
- throw new CommunicationException(e);
- }
- }
-
-
-
- // Commit modifications made to this managed object.
- private void commitExistingManagedObject()
- throws ConcurrentModificationException, OperationRejectedException,
- AuthorizationException, CommunicationException {
- // Build the list of modified attributes.
- Attributes mods = new BasicAttributes();
- for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
- Property<?> p = properties.getProperty(pd);
- if (p.isModified()) {
- String attrID = context.getLDAPProfile().getAttributeName(definition,
- pd);
- Attribute attribute = new BasicAttribute(attrID);
- encodeProperty(attribute, pd, properties);
- mods.put(attribute);
- }
- }
-
- // Perform the LDAP modification if something has changed.
- if (mods.size() > 0) {
- try {
- LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
- context.getLDAPConnection().modifyEntry(dn, mods);
- } catch (NoPermissionException e) {
- throw new AuthorizationException(e);
- } catch (OperationNotSupportedException e) {
- // Unwilling to perform.
- throw new OperationRejectedException(e);
- } catch (NamingException e) {
- // Just treat it as a communication problem.
- throw new CommunicationException(e);
- }
- }
-
- // The changes were committed successfully so update this managed
- // object's state.
- properties.commit();
- }
-
-
-
- // Commit this new managed object.
- private void commitNewManagedObject() throws AuthorizationException,
+ @Override
+ protected void addNewManagedObject() throws AuthorizationException,
CommunicationException, OperationRejectedException,
ConcurrentModificationException, ManagedObjectAlreadyExistsException {
// First make sure that the parent managed object still exists.
+ ManagedObjectPath<?, ?> path = getManagedObjectPath();
ManagedObjectPath<?, ?> parent = path.parent();
if (!parent.isEmpty()) {
- LdapName dn = LDAPNameBuilder.create(parent, context.getLDAPProfile());
- if (!entryExists(dn)) {
+ LdapName dn = LDAPNameBuilder.create(parent, driver.getLDAPProfile());
+ if (!driver.entryExists(dn)) {
throw new ConcurrentModificationException();
}
}
@@ -908,14 +151,14 @@
// comprise of more than one RDN arc (this will probably never
// be required anyway).
LdapName dn = LDAPNameBuilder
- .create(parent, ir, context.getLDAPProfile());
- if (!entryExists(dn)) {
+ .create(parent, ir, driver.getLDAPProfile());
+ if (!driver.entryExists(dn)) {
// We need to create the entry.
Attributes attributes = new BasicAttributes();
// Create the branch's object class attribute.
Attribute oc = new BasicAttribute("objectClass");
- for (String objectClass : context.getLDAPProfile()
+ for (String objectClass : driver.getLDAPProfile()
.getInstantiableRelationObjectClasses(ir)) {
oc.add(objectClass);
}
@@ -927,39 +170,41 @@
// Create the entry.
try {
- context.getLDAPConnection().createEntry(dn, attributes);
+ driver.getLDAPConnection().createEntry(dn, attributes);
} catch (OperationNotSupportedException e) {
// Unwilling to perform.
throw new OperationRejectedException(e);
} catch (NamingException e) {
- adaptNamingException(e);
+ driver.adaptNamingException(e);
}
}
}
// Now add the entry representing this new managed object.
- LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
+ LdapName dn = LDAPNameBuilder.create(path, driver.getLDAPProfile());
Attributes attributes = new BasicAttributes(true);
// Create the object class attribute.
Attribute oc = new BasicAttribute("objectclass");
- for (String objectClass : context.getLDAPProfile().getObjectClasses(
+ ManagedObjectDefinition<?, ?> definition = getManagedObjectDefinition();
+ for (String objectClass : driver.getLDAPProfile().getObjectClasses(
definition)) {
oc.add(objectClass);
}
attributes.put(oc);
// Create the naming attribute if there is not naming property.
- if (namingPropertyDefinition == null) {
+ PropertyDefinition<?> npd = getNamingPropertyDefinition();
+ if (npd == null) {
Rdn rdn = dn.getRdn(dn.size() - 1);
attributes.put(rdn.getType(), rdn.getValue().toString());
}
// Create the remaining attributes.
for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
- String attrID = context.getLDAPProfile().getAttributeName(definition, pd);
+ String attrID = driver.getLDAPProfile().getAttributeName(definition, pd);
Attribute attribute = new BasicAttribute(attrID);
- encodeProperty(attribute, pd, properties);
+ encodeProperty(attribute, pd);
if (attribute.size() != 0) {
attributes.put(attribute);
}
@@ -967,287 +212,100 @@
try {
// Create the entry.
- context.getLDAPConnection().createEntry(dn, attributes);
+ driver.getLDAPConnection().createEntry(dn, attributes);
} catch (NameAlreadyBoundException e) {
throw new ManagedObjectAlreadyExistsException();
} catch (OperationNotSupportedException e) {
// Unwilling to perform.
throw new OperationRejectedException(e);
} catch (NamingException e) {
- adaptNamingException(e);
+ driver.adaptNamingException(e);
}
-
- // The entry was created successfully so update this managed
- // object's state.
- properties.commit();
- existsOnServer = true;
}
- // Create a managed object which already exists on the server.
- private <M extends ConfigurationClient, N extends Configuration>
- ManagedObject<M> createExistingManagedObject(
- ManagedObjectDefinition<M, N> d,
- ManagedObjectPath<? super M, ? super N> p, PropertySet properties) {
- RelationDefinition<?, ?> rd = p.getRelationDefinition();
- PropertyDefinition<?> pd = null;
- if (rd instanceof InstantiableRelationDefinition) {
- InstantiableRelationDefinition<?, ?> ird =
- (InstantiableRelationDefinition<?, ?>) rd;
- pd = ird.getNamingPropertyDefinition();
- }
- return new LDAPManagedObject<M>(context, d, p.asSubType(d), properties,
- true, pd);
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Driver getDriver() {
+ return driver;
}
- // Creates a new managed object with no active values, just default
- // values.
- private <M extends ConfigurationClient, P>
- ManagedObject<M> createNewManagedObject(
- ManagedObjectDefinition<M, ?> d, ManagedObjectPath<M, ?> p,
- PropertyDefinition<P> namingPropertyDefinition, String name,
- Collection<DefaultBehaviorException> exceptions) {
- PropertySet childProperties = new PropertySet();
- for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void modifyExistingManagedObject()
+ throws ConcurrentModificationException, OperationRejectedException,
+ AuthorizationException, CommunicationException {
+ // Build the list of modified attributes.
+ Attributes mods = new BasicAttributes();
+ ManagedObjectDefinition<?, ?> definition = getManagedObjectDefinition();
+ for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
+ Property<?> p = getProperty(pd);
+ if (p.isModified()) {
+ String attrID = driver.getLDAPProfile().getAttributeName(definition,
+ pd);
+ Attribute attribute = new BasicAttribute(attrID);
+ encodeProperty(attribute, pd);
+ mods.put(attribute);
+ }
+ }
+
+ // Perform the LDAP modification if something has changed.
+ if (mods.size() > 0) {
try {
- createProperty(childProperties, p, pd);
- } catch (DefaultBehaviorException e) {
- // Add the exception if requested.
- if (exceptions != null) {
- exceptions.add(e);
- }
+ ManagedObjectPath<?, ?> path = getManagedObjectPath();
+ LdapName dn = LDAPNameBuilder.create(path, driver.getLDAPProfile());
+ driver.getLDAPConnection().modifyEntry(dn, mods);
+ } catch (NoPermissionException e) {
+ throw new AuthorizationException(e);
+ } catch (OperationNotSupportedException e) {
+ // Unwilling to perform.
+ throw new OperationRejectedException(e);
+ } catch (NamingException e) {
+ // Just treat it as a communication problem.
+ throw new CommunicationException(e);
}
}
-
- // Set the naming property if there is one.
- if (namingPropertyDefinition != null) {
- P value = namingPropertyDefinition.decodeValue(name);
- childProperties.setPropertyValue(namingPropertyDefinition, value);
- }
-
- return new LDAPManagedObject<M>(context, d, p, childProperties, false,
- namingPropertyDefinition);
- }
-
-
-
- // Create an empty property.
- private <P> void createProperty(PropertySet properties,
- ManagedObjectPath<?, ?> p, PropertyDefinition<P> pd)
- throws DefaultBehaviorException {
- try {
- Collection<P> defaultValues = DefaultValueFinder.getDefaultValues(
- context, p, pd, true);
- properties.addProperty(pd, defaultValues, Collections.<P> emptySet());
- } catch (DefaultBehaviorException e) {
- // Make sure that we have still created the property.
- properties.addProperty(pd, Collections.<P> emptySet(), Collections
- .<P> emptySet());
- throw e;
- }
}
- // Create a property using the provided string values.
- private <P> void decodeProperty(PropertySet newProperties,
- ManagedObjectPath<?, ?> p, PropertyDefinition<P> pd, List<String> values)
- throws PropertyException {
- PropertyException exception = null;
-
- // Get the property's active values.
- Collection<P> activeValues = new ArrayList<P>(values.size());
- for (String value : values) {
- try {
- activeValues.add(pd.decodeValue(value));
- } catch (IllegalPropertyValueStringException e) {
- exception = e;
- }
- }
-
- if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
- // This exception takes precedence over previous exceptions.
- exception = new PropertyIsSingleValuedException(pd);
- P value = activeValues.iterator().next();
- activeValues.clear();
- activeValues.add(value);
- }
-
- if (activeValues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
- // The active values maybe empty because of a previous exception.
- if (exception == null) {
- exception = new PropertyIsMandatoryException(pd);
- }
- }
-
- // Get the property's default values.
- Collection<P> defaultValues;
- try {
- defaultValues = DefaultValueFinder.getDefaultValues(context, p, pd,
- false);
- } catch (DefaultBehaviorException e) {
- defaultValues = Collections.emptySet();
- exception = e;
- }
-
- newProperties.addProperty(pd, defaultValues, activeValues);
- if (exception != null) {
- throw exception;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected <M extends ConfigurationClient> ManagedObject<M> newInstance(
+ ManagedObjectDefinition<M, ?> d, ManagedObjectPath<M, ?> path,
+ PropertySet properties, boolean existsOnServer,
+ PropertyDefinition<?> namingPropertyDefinition) {
+ return new LDAPManagedObject<M>(driver, d, path, properties,
+ existsOnServer, namingPropertyDefinition);
}
// Encode a property into LDAP string values.
- private <P> void encodeProperty(Attribute attribute,
- PropertyDefinition<P> pd, PropertySet properties) {
- Property<P> p = properties.getProperty(pd);
+ private <PD> void encodeProperty(Attribute attribute,
+ PropertyDefinition<PD> pd) {
+ Property<PD> p = getProperty(pd);
if (pd.hasOption(PropertyOption.MANDATORY)) {
// For mandatory properties we fall-back to the default values
// if defined which can sometimes be the case e.g when a
// mandatory property is overridden.
- for (P value : p.getEffectiveValues()) {
+ for (PD value : p.getEffectiveValues()) {
attribute.add(pd.encodeValue(value));
}
} else {
- for (P value : p.getPendingValues()) {
+ for (PD value : p.getPendingValues()) {
attribute.add(pd.encodeValue(value));
}
}
}
-
-
- // Makes sure that the entry corresponding to this managed object
- // exists.
- private void ensureThisManagedObjectExists()
- throws ConcurrentModificationException, CommunicationException,
- AuthorizationException {
- if (!path.isEmpty()) {
- LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
- if (!entryExists(dn)) {
- throw new ConcurrentModificationException();
- }
- }
- }
-
-
-
- // Determine whether the named entry exists or not.
- private boolean entryExists(LdapName dn) throws CommunicationException,
- AuthorizationException {
- try {
- return context.getLDAPConnection().entryExists(dn);
- } catch (NamingException e) {
- adaptNamingException(e);
- }
- return false;
- }
-
-
-
- // Read the entry identified by the path and which is a sub-type of
- // the specified definition.
- private <C extends ConfigurationClient, S extends Configuration>
- ManagedObject<? extends C> readManagedObject(
- AbstractManagedObjectDefinition<C, S> d, ManagedObjectPath<C, S> p)
- throws DefinitionDecodingException, ManagedObjectDecodingException,
- ManagedObjectNotFoundException, AuthorizationException,
- CommunicationException {
- try {
- // Read the entry associated with the managed object.
- LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
- ManagedObjectDefinition<? extends C, ? extends S> mod =
- getEntryDefinition(context, d, dn);
-
- ArrayList<String> attrIds = new ArrayList<String>();
- for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
- String attrId = context.getLDAPProfile().getAttributeName(mod, pd);
- attrIds.add(attrId);
- }
-
- Attributes attributes = context.getLDAPConnection()
- .readEntry(dn, attrIds);
-
- // Build the managed object's properties.
- List<PropertyException> exceptions = new LinkedList<PropertyException>();
- PropertySet newProperties = new PropertySet();
- for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
- String attrID = context.getLDAPProfile().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, p, pd, values);
- } catch (PropertyException e) {
- exceptions.add(e);
- }
- }
-
- // If there were no decoding problems then return the object,
- // otherwise throw an operations exception.
- ManagedObject<? extends C> mo = createExistingManagedObject(mod, p,
- newProperties);
- if (exceptions.isEmpty()) {
- return mo;
- } else {
- throw new ManagedObjectDecodingException(mo, exceptions);
- }
- } catch (NameNotFoundException e) {
- throw new ManagedObjectNotFoundException();
- } catch (NoPermissionException e) {
- throw new AuthorizationException(e);
- } catch (NamingException e) {
- throw new CommunicationException(e);
- }
- }
-
-
-
- // Remove the named managed object.
- private void removeManagedObject(ManagedObjectPath<?, ?> p)
- throws CommunicationException, AuthorizationException,
- OperationRejectedException, ManagedObjectNotFoundException {
- LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
- if (entryExists(dn)) {
- // Delete the entry and any subordinate entries.
- try {
- context.getLDAPConnection().deleteSubtree(dn);
- } catch (OperationNotSupportedException e) {
- // Unwilling to perform.
- throw new OperationRejectedException(e);
- } catch (NamingException e) {
- adaptNamingException(e);
- }
- } else {
- throw new ManagedObjectNotFoundException();
- }
- }
-
-
-
- // Validate that a relation definition belongs to this managed
- // object.
- private void validateRelationDefinition(RelationDefinition<?, ?> rd)
- throws IllegalArgumentException {
- ManagedObjectDefinition<T, ?> d = getManagedObjectDefinition();
- RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
- if (tmp != rd) {
- throw new IllegalArgumentException("The relation " + rd.getName()
- + " is not associated with a " + d.getName());
- }
- }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
index 6828bc9..9e107dc 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
@@ -55,20 +55,15 @@
return new LDAPManagementContext(connection, LDAPProfile.getInstance());
}
- // The LDAP connection.
- private final LDAPConnection connection;
-
- // The LDAP profile which should be used to construct LDAP requests
- // and decode LDAP responses.
- private final LDAPProfile profile;
+ // The LDAP management context driver.
+ private final LDAPDriver driver;
// Private constructor.
private LDAPManagementContext(LDAPConnection connection,
LDAPProfile profile) {
- this.connection = connection;
- this.profile = profile;
+ this.driver = new LDAPDriver(connection, profile);
}
@@ -77,31 +72,6 @@
* {@inheritDoc}
*/
public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
- return LDAPManagedObject.getRootManagedObject(this);
- }
-
-
-
- /**
- * Gets the LDAP connection used for interacting with the server.
- *
- * @return Returns the LDAP connection used for interacting with the
- * server.
- */
- LDAPConnection getLDAPConnection() {
- return connection;
- }
-
-
-
- /**
- * Gets the LDAP profile which should be used to construct LDAP
- * requests and decode LDAP responses.
- *
- * @return Returns the LDAP profile which should be used to
- * construct LDAP requests and decode LDAP responses.
- */
- LDAPProfile getLDAPProfile() {
- return profile;
+ return LDAPManagedObject.getRootManagedObject(driver);
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/package-info.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/package-info.java
index f92dd8b..0d5f99b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/package-info.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/package-info.java
@@ -30,12 +30,8 @@
/**
* Common client-side administration classes.
* <p>
- * This package contains classes which client applications and client-side
- * driver implementations are expected to use.
- * <p>
- * In addition, there are also two example client
- * applications, <code>ExampleClient</code> and
- * <code>ExampleIntrospection</code>.
+ * This package contains classes which client applications are
+ * expected to use.
*/
@org.opends.server.types.PublicAPI(
stability=org.opends.server.types.StabilityLevel.PRIVATE)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
new file mode 100644
index 0000000..5e9c9c2
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
@@ -0,0 +1,696 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.spi;
+
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.Configuration;
+import org.opends.server.admin.ConfigurationClient;
+import org.opends.server.admin.DefaultBehaviorException;
+import org.opends.server.admin.DefinitionDecodingException;
+import org.opends.server.admin.IllegalPropertyValueException;
+import org.opends.server.admin.IllegalPropertyValueStringException;
+import org.opends.server.admin.InstantiableRelationDefinition;
+import org.opends.server.admin.ManagedObjectAlreadyExistsException;
+import org.opends.server.admin.ManagedObjectDefinition;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.ManagedObjectPath;
+import org.opends.server.admin.OptionalRelationDefinition;
+import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.PropertyIsMandatoryException;
+import org.opends.server.admin.PropertyIsReadOnlyException;
+import org.opends.server.admin.PropertyIsSingleValuedException;
+import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.RelationDefinition;
+import org.opends.server.admin.SingletonRelationDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.IllegalManagedObjectNameException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.MissingMandatoryPropertiesException;
+import org.opends.server.admin.client.OperationRejectedException;
+
+
+
+/**
+ * An abstract managed object implementation.
+ *
+ * @param <T>
+ * The type of client configuration represented by the client
+ * managed object.
+ */
+public abstract class AbstractManagedObject<T extends ConfigurationClient>
+ implements ManagedObject<T> {
+
+ // The managed object definition associated with this managed
+ // object.
+ private final ManagedObjectDefinition<T, ? extends Configuration> definition;
+
+ // Indicates whether or not this managed object exists on the server
+ // (false means the managed object is new and has not been
+ // committed).
+ private boolean existsOnServer;
+
+ // Optional naming property definition.
+ private final PropertyDefinition<?> namingPropertyDefinition;
+
+ // The path associated with this managed object.
+ private ManagedObjectPath<T, ? extends Configuration> path;
+
+ // The managed object's properties.
+ private final PropertySet properties;
+
+
+
+ /**
+ * Creates a new abstract managed object.
+ *
+ * @param d
+ * The managed object's definition.
+ * @param path
+ * The managed object's path.
+ * @param properties
+ * The managed object's properties.
+ * @param existsOnServer
+ * Indicates whether or not the managed object exists on
+ * the server (false means the managed object is new and
+ * has not been committed).
+ * @param namingPropertyDefinition
+ * Optional naming property definition.
+ */
+ protected AbstractManagedObject(
+ ManagedObjectDefinition<T, ? extends Configuration> d,
+ ManagedObjectPath<T, ? extends Configuration> path,
+ PropertySet properties, boolean existsOnServer,
+ PropertyDefinition<?> namingPropertyDefinition) {
+ this.definition = d;
+ this.path = path;
+ this.properties = properties;
+ this.existsOnServer = existsOnServer;
+ this.namingPropertyDefinition = namingPropertyDefinition;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void commit() throws ManagedObjectAlreadyExistsException,
+ MissingMandatoryPropertiesException, ConcurrentModificationException,
+ OperationRejectedException, AuthorizationException,
+ CommunicationException {
+ // First make sure all mandatory properties are defined.
+ List<PropertyIsMandatoryException> exceptions =
+ new LinkedList<PropertyIsMandatoryException>();
+
+ for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
+ Property<?> p = getProperty(pd);
+ if (pd.hasOption(PropertyOption.MANDATORY)
+ && p.getEffectiveValues().isEmpty()) {
+ exceptions.add(new PropertyIsMandatoryException(pd));
+ }
+ }
+
+ if (!exceptions.isEmpty()) {
+ throw new MissingMandatoryPropertiesException(exceptions);
+ }
+
+ // Commit the managed object.
+ if (existsOnServer) {
+ modifyExistingManagedObject();
+ } else {
+ addNewManagedObject();
+ existsOnServer = true;
+ }
+
+ // Make all pending property values active.
+ properties.commit();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration,
+ CC extends C>
+ ManagedObject<CC> createChild(
+ InstantiableRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d, String name,
+ Collection<DefaultBehaviorException> exceptions)
+ throws IllegalManagedObjectNameException, IllegalArgumentException {
+ validateRelationDefinition(r);
+
+ // Empty names are not allowed.
+ if (name.trim().length() == 0) {
+ throw new IllegalManagedObjectNameException(name);
+ }
+
+ // If the relation uses a naming property definition then it must
+ // be a valid value.
+ PropertyDefinition<?> pd = r.getNamingPropertyDefinition();
+ if (pd != null) {
+ try {
+ pd.decodeValue(name);
+ } catch (IllegalPropertyValueStringException e) {
+ throw new IllegalManagedObjectNameException(name, pd);
+ }
+ }
+
+ ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d, name);
+ return createNewManagedObject(d, childPath, pd, name, exceptions);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient,
+ S extends Configuration, CC extends C>
+ ManagedObject<CC> createChild(
+ OptionalRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d,
+ Collection<DefaultBehaviorException> exceptions)
+ throws IllegalArgumentException {
+ validateRelationDefinition(r);
+ ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d);
+ return createNewManagedObject(d, childPath, null, null, exceptions);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(
+ InstantiableRelationDefinition<C, S> r, String name)
+ throws IllegalArgumentException, DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ validateRelationDefinition(r);
+ ensureThisManagedObjectExists();
+ Driver ctx = getDriver();
+ return ctx.getManagedObject(path.child(r, name));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(
+ OptionalRelationDefinition<C, S> r) throws IllegalArgumentException,
+ DefinitionDecodingException, ManagedObjectDecodingException,
+ ManagedObjectNotFoundException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
+ ensureThisManagedObjectExists();
+ Driver ctx = getDriver();
+ return ctx.getManagedObject(path.child(r));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(
+ SingletonRelationDefinition<C, S> r) throws IllegalArgumentException,
+ DefinitionDecodingException, ManagedObjectDecodingException,
+ ManagedObjectNotFoundException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
+ ensureThisManagedObjectExists();
+ Driver ctx = getDriver();
+ return ctx.getManagedObject(path.child(r));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final T getConfiguration() {
+ return definition.createClientConfiguration(this);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final ManagedObjectDefinition<T, ? extends Configuration>
+ getManagedObjectDefinition() {
+ return definition;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final ManagedObjectPath<T, ? extends Configuration>
+ getManagedObjectPath() {
+ return path;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <PD> SortedSet<PD> getPropertyDefaultValues(
+ PropertyDefinition<PD> pd) throws IllegalArgumentException {
+ return new TreeSet<PD>(getProperty(pd).getDefaultValues());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <PD> PD getPropertyValue(PropertyDefinition<PD> pd)
+ throws IllegalArgumentException {
+ Set<PD> values = getProperty(pd).getEffectiveValues();
+ if (values.isEmpty()) {
+ return null;
+ } else {
+ return values.iterator().next();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <PD> SortedSet<PD> getPropertyValues(PropertyDefinition<PD> pd)
+ throws IllegalArgumentException {
+ return new TreeSet<PD>(getProperty(pd).getEffectiveValues());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ boolean hasChild(
+ OptionalRelationDefinition<C, S> r) throws IllegalArgumentException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ validateRelationDefinition(r);
+ Driver ctx = getDriver();
+ try {
+ return ctx.hasManagedObject(path, r);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean isPropertyPresent(PropertyDefinition<?> pd)
+ throws IllegalArgumentException {
+ return !getProperty(pd).isEmpty();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(
+ InstantiableRelationDefinition<C, S> r) throws IllegalArgumentException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ return listChildren(r, r.getChildDefinition());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(
+ InstantiableRelationDefinition<C, S> r,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
+ Driver ctx = getDriver();
+ try {
+ return ctx.listManagedObjects(path, r, d);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(
+ InstantiableRelationDefinition<C, S> r, String name)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
+ Driver ctx = getDriver();
+ boolean found;
+
+ try {
+ found = ctx.deleteManagedObject(path, r, name);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+
+ if (!found) {
+ throw new ManagedObjectNotFoundException();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(
+ OptionalRelationDefinition<C, S> r) throws IllegalArgumentException,
+ ManagedObjectNotFoundException, OperationRejectedException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ validateRelationDefinition(r);
+ Driver ctx = getDriver();
+ boolean found;
+
+ try {
+ found = ctx.deleteManagedObject(path, r);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+
+ if (!found) {
+ throw new ManagedObjectNotFoundException();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <PD> void setPropertyValue(PropertyDefinition<PD> pd, PD value)
+ throws IllegalPropertyValueException, PropertyIsReadOnlyException,
+ PropertyIsMandatoryException, IllegalArgumentException {
+ if (value == null) {
+ setPropertyValues(pd, Collections.<PD> emptySet());
+ } else {
+ setPropertyValues(pd, Collections.singleton(value));
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final <PD> void setPropertyValues(PropertyDefinition<PD> pd,
+ Collection<PD> values) throws IllegalPropertyValueException,
+ PropertyIsSingleValuedException, PropertyIsReadOnlyException,
+ PropertyIsMandatoryException, IllegalArgumentException {
+ if (pd.hasOption(PropertyOption.MONITORING)) {
+ throw new PropertyIsReadOnlyException(pd);
+ }
+
+ if (existsOnServer && pd.hasOption(PropertyOption.READ_ONLY)) {
+ throw new PropertyIsReadOnlyException(pd);
+ }
+
+ properties.setPropertyValues(pd, values);
+
+ // If this is a naming property then update the name.
+ if (pd.equals(namingPropertyDefinition)) {
+ // The property must be single-valued and mandatory.
+ String newName = pd.encodeValue(values.iterator().next());
+ path = path.rename(newName);
+ }
+ }
+
+
+
+ /**
+ * Adds this new managed object.
+ *
+ * @throws ManagedObjectAlreadyExistsException
+ * If the managed object cannot be added to the server
+ * because it already exists.
+ * @throws ConcurrentModificationException
+ * If the managed object's parent has been removed by
+ * another client.
+ * @throws OperationRejectedException
+ * If the server refuses to add this managed object due to
+ * some server-side constraint which cannot be satisfied.
+ * @throws AuthorizationException
+ * If the server refuses to add this managed object
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ protected abstract void addNewManagedObject() throws AuthorizationException,
+ CommunicationException, OperationRejectedException,
+ ConcurrentModificationException, ManagedObjectAlreadyExistsException;
+
+
+
+ /**
+ * Gets the management context driver associated with this managed
+ * object.
+ *
+ * @return Returns the management context driver associated with
+ * this managed object.
+ */
+ protected abstract Driver getDriver();
+
+
+
+ /**
+ * Gets the naming property definition associated with this managed
+ * object.
+ *
+ * @return Returns the naming property definition associated with
+ * this managed object, or <code>null</code> if this
+ * managed object does not have a naming property.
+ */
+ protected final PropertyDefinition<?> getNamingPropertyDefinition() {
+ return namingPropertyDefinition;
+ }
+
+
+
+ /**
+ * Gets the property associated with the specified property
+ * definition.
+ *
+ * @param <PD>
+ * The underlying type of the property.
+ * @param pd
+ * The Property definition.
+ * @return Returns the property associated with the specified
+ * property definition.
+ * @throws IllegalArgumentException
+ * If this property provider does not recognize the
+ * requested property definition.
+ */
+ protected final <PD> Property<PD> getProperty(PropertyDefinition<PD> pd)
+ throws IllegalArgumentException {
+ return properties.getProperty(pd);
+ }
+
+
+
+ /**
+ * Applies changes made to this managed object.
+ *
+ * @throws ConcurrentModificationException
+ * If this managed object has been removed from the server
+ * by another client.
+ * @throws OperationRejectedException
+ * If the server refuses to modify this managed object due
+ * to some server-side constraint which cannot be
+ * satisfied.
+ * @throws AuthorizationException
+ * If the server refuses to modify this managed object
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ protected abstract void modifyExistingManagedObject()
+ throws ConcurrentModificationException, OperationRejectedException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * Creates a new managed object.
+ *
+ * @param <M>
+ * The type of client configuration represented by the
+ * client managed object.
+ * @param d
+ * The managed object's definition.
+ * @param path
+ * The managed object's path.
+ * @param properties
+ * The managed object's properties.
+ * @param existsOnServer
+ * Indicates whether or not the managed object exists on
+ * the server (false means the managed object is new and
+ * has not been committed).
+ * @param namingPropertyDefinition
+ * Optional naming property definition.
+ * @return Returns the new managed object.
+ */
+ protected abstract <M extends ConfigurationClient>
+ ManagedObject<M> newInstance(
+ ManagedObjectDefinition<M, ?> d, ManagedObjectPath<M, ?> path,
+ PropertySet properties, boolean existsOnServer,
+ PropertyDefinition<?> namingPropertyDefinition);
+
+
+
+ // Creates a new managed object with no active values, just default
+ // values.
+ private <M extends ConfigurationClient, PD> ManagedObject<M>
+ createNewManagedObject(
+ ManagedObjectDefinition<M, ?> d, ManagedObjectPath<M, ?> p,
+ PropertyDefinition<PD> namingPropertyDefinition, String name,
+ Collection<DefaultBehaviorException> exceptions) {
+ PropertySet childProperties = new PropertySet();
+ for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
+ try {
+ createProperty(childProperties, p, pd);
+ } catch (DefaultBehaviorException e) {
+ // Add the exception if requested.
+ if (exceptions != null) {
+ exceptions.add(e);
+ }
+ }
+ }
+
+ // Set the naming property if there is one.
+ if (namingPropertyDefinition != null) {
+ PD value = namingPropertyDefinition.decodeValue(name);
+ childProperties.setPropertyValues(namingPropertyDefinition, Collections
+ .singleton(value));
+ }
+
+ return newInstance(d, p, childProperties, false, namingPropertyDefinition);
+ }
+
+
+
+ // Create an empty property.
+ private <PD> void createProperty(PropertySet properties,
+ ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd)
+ throws DefaultBehaviorException {
+ try {
+ Driver context = getDriver();
+ Collection<PD> defaultValues = context.findDefaultValues(p, pd, true);
+ properties.addProperty(pd, defaultValues, Collections.<PD> emptySet());
+ } catch (DefaultBehaviorException e) {
+ // Make sure that we have still created the property.
+ properties.addProperty(pd, Collections.<PD> emptySet(), Collections
+ .<PD> emptySet());
+ throw e;
+ }
+ }
+
+
+
+ // Makes sure that this managed object exists.
+ private void ensureThisManagedObjectExists()
+ throws ConcurrentModificationException, CommunicationException,
+ AuthorizationException {
+ if (!path.isEmpty()) {
+ Driver ctx = getDriver();
+
+ try {
+ ctx.getManagedObject(path);
+ } catch (DefinitionDecodingException e) {
+ // Ignore.
+ } catch (ManagedObjectDecodingException e) {
+ // Ignore.
+ } catch (ManagedObjectNotFoundException e) {
+ throw new ConcurrentModificationException();
+ }
+ }
+ }
+
+
+
+ // Validate that a relation definition belongs to this managed
+ // object.
+ private void validateRelationDefinition(RelationDefinition<?, ?> rd)
+ throws IllegalArgumentException {
+ ManagedObjectDefinition<T, ?> d = getManagedObjectDefinition();
+ RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
+ if (tmp != rd) {
+ throw new IllegalArgumentException("The relation " + rd.getName()
+ + " is not associated with a " + d.getName());
+ }
+ }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java
new file mode 100644
index 0000000..d26004d
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java
@@ -0,0 +1,701 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client.spi;
+
+
+
+import static org.opends.server.util.StaticUtils.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.AliasDefaultBehaviorProvider;
+import org.opends.server.admin.Configuration;
+import org.opends.server.admin.ConfigurationClient;
+import org.opends.server.admin.DefaultBehaviorException;
+import org.opends.server.admin.DefaultBehaviorProviderVisitor;
+import org.opends.server.admin.DefinedDefaultBehaviorProvider;
+import org.opends.server.admin.DefinitionDecodingException;
+import org.opends.server.admin.IllegalPropertyValueStringException;
+import org.opends.server.admin.InstantiableRelationDefinition;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.ManagedObjectPath;
+import org.opends.server.admin.OptionalRelationDefinition;
+import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.PropertyException;
+import org.opends.server.admin.PropertyIsSingleValuedException;
+import org.opends.server.admin.PropertyNotFoundException;
+import org.opends.server.admin.PropertyOption;
+import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
+import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
+import org.opends.server.admin.DefinitionDecodingException.Reason;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.OperationRejectedException;
+
+
+
+/**
+ * An abstract management connection context driver which should form
+ * the basis of driver implementations.
+ */
+public abstract class Driver {
+
+ /**
+ * 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;
+
+ // The path of the managed object containing the first property.
+ private final ManagedObjectPath<?, ?> firstPath;
+
+ // Indicates whether the managed object has been created yet.
+ private final boolean isCreate;
+
+ // 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;
+
+
+
+ // Private constructor.
+ private DefaultValueFinder(ManagedObjectPath<?, ?> p, boolean isCreate) {
+ this.firstPath = p;
+ this.isCreate = isCreate;
+ }
+
+
+
+ /**
+ * {@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 {
+ this.nextPath = p;
+ this.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(Reason.WRONG_TYPE_INFORMATION));
+ }
+
+ // Save the current property in case of recursion.
+ PropertyDefinition<T> pd1 = nextProperty;
+
+ try {
+ // Determine the requested property definition.
+ PropertyDefinition<T> pd2;
+ try {
+ // FIXME: we use the definition taken from the default
+ // behavior here when we should really use the exact
+ // definition of the component being created.
+ PropertyDefinition<?> pdTmp = d.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);
+ }
+
+ // If the path relates to the current managed object and the
+ // managed object is in the process of being created it won't
+ // exist, so we should just use the default values of the
+ // referenced property.
+ if (isCreate && firstPath.equals(target)) {
+ // Recursively retrieve this property's default values.
+ Collection<T> tmp = find(target, pd2);
+ Collection<T> values = new ArrayList<T>(tmp.size());
+ for (T value : tmp) {
+ pd1.validateValue(value);
+ values.add(value);
+ }
+ return values;
+ } else {
+ return getPropertyValues(target, pd2);
+ }
+ } catch (DefaultBehaviorException e) {
+ // Wrap any errors due to recursion.
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (DefinitionDecodingException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (PropertyNotFoundException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (AuthorizationException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (ManagedObjectNotFoundException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (CommunicationException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ } catch (PropertyException e) {
+ throw new DefaultBehaviorException(pd1, e);
+ }
+ }
+ };
+
+
+
+ /**
+ * Creates a new abstract management context.
+ */
+ protected Driver() {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * Deletes the named instantiable child managed object from 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.
+ * @param name
+ * The name of the child managed object to be removed.
+ * @return Returns <code>true</code> if the named instantiable
+ * child managed object was found, or <code>false</code>
+ * if it was not found.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws OperationRejectedException
+ * If the server refuses to remove the child managed
+ * object due to some server-side constraint which cannot
+ * be satisfied (for example, if it is referenced by
+ * another managed object).
+ * @throws AuthorizationException
+ * If the server refuses to make the list the managed
+ * objects because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <C extends ConfigurationClient, S extends Configuration>
+ boolean deleteManagedObject(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+ String name) throws IllegalArgumentException,
+ ManagedObjectNotFoundException, OperationRejectedException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * Deletes the optional child managed object from 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 optional relation definition.
+ * @return Returns <code>true</code> if the optional child managed
+ * object was found, or <code>false</code> if it was not
+ * found.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws OperationRejectedException
+ * If the server refuses to remove the child managed
+ * object due to some server-side constraint which cannot
+ * be satisfied (for example, if it is referenced by
+ * another managed object).
+ * @throws AuthorizationException
+ * If the server refuses to make the list the managed
+ * objects because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <C extends ConfigurationClient, S extends Configuration>
+ boolean deleteManagedObject(
+ ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, AuthorizationException,
+ CommunicationException;
+
+
+
+ /**
+ * 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 DefinitionDecodingException
+ * If the managed object was found but its type could not
+ * be determined.
+ * @throws ManagedObjectDecodingException
+ * If the managed object was found but one or more of its
+ * properties could not be decoded.
+ * @throws ManagedObjectNotFoundException
+ * If the requested managed object could not be found on
+ * the server.
+ * @throws AuthorizationException
+ * If the server refuses to retrieve the managed object
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getManagedObject(
+ ManagedObjectPath<C, S> path) throws DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * Gets the effective value of a property in the named managed
+ * object.
+ *
+ * @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 DefinitionDecodingException
+ * If the managed object was found but its type could not
+ * be determined.
+ * @throws PropertyException
+ * If the managed object was found but the requested
+ * property could not be decoded.
+ * @throws ManagedObjectNotFoundException
+ * If the requested managed object could not be found on
+ * the server.
+ * @throws AuthorizationException
+ * If the server refuses to retrieve the managed object
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public final <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path,
+ PropertyDefinition<PD> pd) throws IllegalArgumentException,
+ DefinitionDecodingException, AuthorizationException,
+ ManagedObjectNotFoundException, CommunicationException,
+ PropertyException {
+ Set<PD> values = getPropertyValues(path, pd);
+ if (values.isEmpty()) {
+ return null;
+ } else {
+ return values.iterator().next();
+ }
+ }
+
+
+
+ /**
+ * Gets the effective values of a property in the named managed
+ * object.
+ * <p>
+ * Implementations MUST NOT not use
+ * {@link #getManagedObject(ManagedObjectPath)} to read the
+ * referenced managed object in its entirety. Specifically,
+ * implementations MUST only attempt to resolve the default values
+ * for the requested property and its dependencies (if it uses
+ * inherited defaults). This is to avoid infinite recursion where a
+ * managed object contains a property which inherits default values
+ * from another property in the same managed object.
+ *
+ * @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 DefinitionDecodingException
+ * If the managed object was found but its type could not
+ * be determined.
+ * @throws PropertyException
+ * If the managed object was found but the requested
+ * property could not be decoded.
+ * @throws ManagedObjectNotFoundException
+ * If the requested managed object could not be found on
+ * the server.
+ * @throws AuthorizationException
+ * If the server refuses to retrieve the managed object
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <PD> SortedSet<PD> getPropertyValues(
+ ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd)
+ throws IllegalArgumentException, DefinitionDecodingException,
+ AuthorizationException, ManagedObjectNotFoundException,
+ CommunicationException, PropertyException;
+
+
+
+ /**
+ * Determines whether or not the named parent managed object has the
+ * named instantiable child 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.
+ * @param name
+ * The name of the child managed object.
+ * @return Returns <code>true</code> if the named instantiable
+ * child managed object exists, <code>false</code>
+ * otherwise.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws AuthorizationException
+ * If the server refuses to make the determination because
+ * the client does not have the correct privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ boolean hasManagedObject(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+ String name) throws IllegalArgumentException,
+ ManagedObjectNotFoundException, AuthorizationException,
+ CommunicationException {
+ // FIXME: use naming properties for comparison where available.
+ String[] children = listManagedObjects(parent, rd);
+ String nname = toLowerCase(name.trim().replaceAll(" +", " "));
+ for (String child : children) {
+ if (nname.equals(toLowerCase(child.trim().replaceAll(" +", " ")))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * Determines whether or not the named parent managed object has an
+ * optional child 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 optional relation definition.
+ * @return Returns <code>true</code> if the optional child managed
+ * object exists, <code>false</code> otherwise.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws AuthorizationException
+ * If the server refuses to make the determination because
+ * the client does not have the correct privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <C extends ConfigurationClient, S extends Configuration>
+ boolean hasManagedObject(
+ ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * 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.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public final <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException {
+ return listManagedObjects(parent, rd, rd.getChildDefinition());
+ }
+
+
+
+ /**
+ * Lists the child managed objects of the named parent managed
+ * object which are a sub-type of the specified managed object
+ * definition.
+ *
+ * @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.
+ * @param d
+ * The managed object definition.
+ * @return Returns the names of the child managed objects which are
+ * a sub-type of the specified managed object definition.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with the
+ * parent managed object's definition.
+ * @throws ManagedObjectNotFoundException
+ * If the parent managed object could not be found.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ public abstract <C extends ConfigurationClient, S extends Configuration>
+ String[] listManagedObjects(
+ ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * Gets the default values for the specified property.
+ *
+ * @param <PD>
+ * The type of the property.
+ * @param p
+ * The managed object path of the current managed object.
+ * @param pd
+ * The property definition.
+ * @param isCreate
+ * Indicates whether the managed object has been created
+ * yet.
+ * @return Returns the default values for the specified property.
+ * @throws DefaultBehaviorException
+ * If the default values could not be retrieved or decoded
+ * properly.
+ */
+ protected final <PD> Collection<PD> findDefaultValues(
+ ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, boolean isCreate)
+ throws DefaultBehaviorException {
+ DefaultValueFinder<PD> v = new DefaultValueFinder<PD>(p, isCreate);
+ return v.find(p, pd);
+ }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/Property.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Property.java
similarity index 72%
rename from opendj-sdk/opends/src/server/org/opends/server/admin/client/Property.java
rename to opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Property.java
index b694cb7..33cd229 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/Property.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Property.java
@@ -25,7 +25,7 @@
* Portions Copyright 2007 Sun Microsystems, Inc.
*/
-package org.opends.server.admin.client;
+package org.opends.server.admin.client.spi;
@@ -36,28 +36,26 @@
/**
- * A managed object property comprising of the property's definition and its set
- * of values.
+ * A managed object property comprising of the property's definition
+ * and its set of values.
* <p>
- * The property stores the values in a sorted set in which values are compared
- * using the comparator defined by the property definition.
+ * The property stores the values in a sorted set in which values are
+ * compared using the comparator defined by the property definition.
* <p>
- * The property keeps track of whether or not its pending set of values differs
- * from its active values.
+ * The property keeps track of whether or not its pending set of
+ * values differs from its active values.
*
* @param <T>
* The type of the property.
- * @see ManagedObject The <code>ManagedObject</code> documentation describes
- * the different types of property values in more detail.
*/
public interface Property<T> {
/**
* Get an immutable set view of this property's active values.
*
- * @return Returns an immutable set view of this property's active values. An
- * empty set indicates that there are no active values, and any
- * default values are applicable.
+ * @return Returns an immutable set view of this property's active
+ * values. An empty set indicates that there are no active
+ * values, and any default values are applicable.
*/
SortedSet<T> getActiveValues();
@@ -66,8 +64,9 @@
/**
* Get an immutable set view of this property's default values.
*
- * @return Returns an immutable set view of this property's default values. An
- * empty set indicates that there are no default values.
+ * @return Returns an immutable set view of this property's default
+ * values. An empty set indicates that there are no default
+ * values.
*/
SortedSet<T> getDefaultValues();
@@ -76,7 +75,8 @@
/**
* Get an immutable set view of this property's effective values.
*
- * @return Returns an immutable set view of this property's effective values.
+ * @return Returns an immutable set view of this property's
+ * effective values.
*/
SortedSet<T> getEffectiveValues();
@@ -85,12 +85,12 @@
/**
* Get an immutable set view of this property's pending values.
* <p>
- * Immediately after construction, the pending values matches the active
- * values.
+ * Immediately after construction, the pending values matches the
+ * active values.
*
- * @return Returns an immutable set view of this property's pending values. An
- * empty set indicates that there are no pending values, and any
- * default values are applicable.
+ * @return Returns an immutable set view of this property's pending
+ * values. An empty set indicates that there are no pending
+ * values, and any default values are applicable.
*/
SortedSet<T> getPendingValues();
@@ -99,39 +99,42 @@
/**
* Get the property definition associated with this property.
*
- * @return Returns the property definition associated with this property.
+ * @return Returns the property definition associated with this
+ * property.
*/
PropertyDefinition<T> getPropertyDefinition();
/**
- * Determines whether or not this property contains any pending values.
+ * Determines whether or not this property contains any pending
+ * values.
*
- * @return Returns <code>true</code> if this property does not contain any
- * pending values.
+ * @return Returns <code>true</code> if this property does not
+ * contain any pending values.
*/
boolean isEmpty();
/**
- * Determines whether or not this property has been modified since it was
- * constructed. In other words, whether or not the set of pending values
- * differs from the set of active values.
+ * Determines whether or not this property has been modified since
+ * it was constructed. In other words, whether or not the set of
+ * pending values differs from the set of active values.
*
- * @return Returns <code>true</code> if this property has been modified
- * since it was constructed.
+ * @return Returns <code>true</code> if this property has been
+ * modified since it was constructed.
*/
boolean isModified();
/**
- * Determines whether or not this property contains any active values.
+ * Determines whether or not this property contains any active
+ * values.
*
- * @return Returns <code>true</code> if this property does not contain any
- * active values.
+ * @return Returns <code>true</code> if this property does not
+ * contain any active values.
*/
boolean wasEmpty();
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/PropertySet.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/PropertySet.java
similarity index 74%
rename from opendj-sdk/opends/src/server/org/opends/server/admin/client/PropertySet.java
rename to opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/PropertySet.java
index 5bddcbd..8b73974 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/PropertySet.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/PropertySet.java
@@ -25,7 +25,7 @@
* Portions Copyright 2007 Sun Microsystems, Inc.
*/
-package org.opends.server.admin.client;
+package org.opends.server.admin.client.spi;
@@ -33,7 +33,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -42,7 +41,6 @@
import org.opends.server.admin.PropertyIsMandatoryException;
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.PropertyOption;
-import org.opends.server.admin.PropertyProvider;
@@ -50,7 +48,7 @@
* A set of properties. Instances of this class can be used as the
* core of a managed object implementation.
*/
-public final class PropertySet implements PropertyProvider {
+public final class PropertySet {
/**
* Internal property implementation.
@@ -255,17 +253,6 @@
/**
- * Makes all pending values active.
- */
- public void commit() {
- for (MyProperty<?> p : properties.values()) {
- p.commit();
- }
- }
-
-
-
- /**
* Get the property associated with the specified property
* definition.
*
@@ -292,88 +279,34 @@
/**
- * Get the effective value of the specified property.
- * <p>
- * See the class description for more information about how the
- * effective property value is derived.
- *
- * @param <T>
- * The type of the property to be retrieved.
- * @param d
- * The property to be retrieved.
- * @return Returns the property's effective value, or
- * <code>null</code> if there is no effective value
- * defined.
- * @throws IllegalArgumentException
- * If the property definition is not associated with this
- * managed object's definition.
+ * {@inheritDoc}
*/
- public <T> T getPropertyValue(PropertyDefinition<T> d)
- throws IllegalArgumentException {
- Set<T> values = getPropertyValues(d);
- if (values.isEmpty()) {
- return null;
- } else {
- return values.iterator().next();
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append('{');
+ for (Map.Entry<PropertyDefinition<?>, MyProperty<?>> entry : properties
+ .entrySet()) {
+ builder.append(entry.getKey().getName());
+ builder.append('=');
+ builder.append(entry.getValue().toString());
+ builder.append(' ');
}
+ builder.append('}');
+ return builder.toString();
}
- /**
- * Get the effective values of the specified property.
- * <p>
- * See the class description for more information about how the
- * effective property values are derived.
- *
- * @param <T>
- * The type of the property to be retrieved.
- * @param d
- * The property to be retrieved.
- * @return Returns the property's effective values, or an empty set
- * if there are no effective values defined.
- * @throws IllegalArgumentException
- * If the property definition is not associated with this
- * managed object's definition.
- */
- public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
- throws IllegalArgumentException {
- Property<T> property = getProperty(d);
- return new TreeSet<T>(property.getEffectiveValues());
- }
/**
- * Set a new pending value for the specified property.
- * <p>
- * See the class description for more information regarding pending
- * values.
- *
- * @param <T>
- * The type of the property to be modified.
- * @param d
- * The property to be modified.
- * @param value
- * The new pending value for the property, or
- * <code>null</code> if the property should be reset to
- * its default behavior.
- * @throws IllegalPropertyValueException
- * If the new pending value is deemed to be invalid
- * according to the property definition.
- * @throws PropertyIsMandatoryException
- * If an attempt was made to remove a mandatory property.
- * @throws IllegalArgumentException
- * If the specified property definition is not associated
- * with this managed object.
+ * Makes all pending values active.
*/
- public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
- throws IllegalPropertyValueException, PropertyIsMandatoryException,
- IllegalArgumentException {
- if (value == null) {
- setPropertyValues(d, Collections.<T> emptySet());
- } else {
- setPropertyValues(d, Collections.singleton(value));
+ void commit() {
+ for (MyProperty<?> p : properties.values()) {
+ p.commit();
}
}
@@ -406,7 +339,7 @@
* If the specified property definition is not associated
* with this managed object.
*/
- public <T> void setPropertyValues(PropertyDefinition<T> d,
+ <T> void setPropertyValues(PropertyDefinition<T> d,
Collection<T> values) throws IllegalPropertyValueException,
PropertyIsSingleValuedException, PropertyIsMandatoryException,
IllegalArgumentException {
@@ -435,24 +368,4 @@
// Update the property.
property.setPendingValues(values);
}
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append('{');
- for (Map.Entry<PropertyDefinition<?>, MyProperty<?>> entry : properties
- .entrySet()) {
- builder.append(entry.getKey().getName());
- builder.append('=');
- builder.append(entry.getValue().toString());
- builder.append(' ');
- }
- builder.append('}');
- return builder.toString();
- }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/package-info.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/package-info.java
new file mode 100644
index 0000000..287ecb6
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+
+
+/**
+ * Client side driver implementation interfaces.
+ * <p>
+ * This package contains classes which client-side driver
+ * implementations are expected to use.
+ */
+@org.opends.server.types.PublicAPI(
+ stability=org.opends.server.types.StabilityLevel.PRIVATE)
+package org.opends.server.admin.client.spi;
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/PropertySetTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/spi/PropertySetTest.java
similarity index 98%
rename from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/PropertySetTest.java
rename to opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/spi/PropertySetTest.java
index 5633837..800af80 100755
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/PropertySetTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/spi/PropertySetTest.java
@@ -25,12 +25,15 @@
* Portions Copyright 2007 Sun Microsystems, Inc.
*/
-package org.opends.server.admin.client;
+package org.opends.server.admin.client.spi;
import static org.testng.Assert.*;
import org.testng.annotations.*;
import org.opends.server.admin.*;
import org.opends.server.admin.Configuration;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.spi.Property;
+import org.opends.server.admin.client.spi.PropertySet;
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.admin.std.meta.RootCfgDefn;
--
Gitblit v1.10.0