Partial fix for issue 1451: admin framework constraint and dependency support.
This change provides a client-side framework for enforcing arbitrary constraints between managed objects and their properties. This framework enables us to (not exhaustive):
1) support referential integrity between managed objects (required by issue 1449)
2) support dependencies between properties (e.g. if A is true then B is mandatory). This is useful for optional features like SSL configuration
3) support constraints between properties (e.g. integer property A must always be less than integer property B)
A subsequent change will provide server-side support.
3 files added
12 files modified
| | |
| | | administrator's properties |
| | | INFO_ADMIN_ARG_USERID_DESCRIPTION_73=The administrator's unique identifier. \ |
| | | This is a required argument |
| | | SEVERE_ERR_OPERATION_REJECTED_DEFAULT_74=The operation was rejected for an \ |
| | | unspecified reason |
| | |
| | | */ |
| | | |
| | | package org.opends.server.admin; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.DefinitionDecodingException.Reason; |
| | | |
| | | |
| | |
| | | // The parent managed object definition if applicable. |
| | | private final AbstractManagedObjectDefinition<? super C, ? super S> parent; |
| | | |
| | | // The set of constraints associated with this managed object |
| | | // definition. |
| | | private final Collection<Constraint> constraints; |
| | | |
| | | // The set of property definitions applicable to this managed object |
| | | // definition. |
| | | private final Map<String, PropertyDefinition<?>> propertyDefinitions; |
| | |
| | | // definition. |
| | | private final Map<String, RelationDefinition<?, ?>> relationDefinitions; |
| | | |
| | | // The set of all constraints associated with this managed object |
| | | // definition including inherited constraints. |
| | | private final Collection<Constraint> allConstraints; |
| | | |
| | | // The set of all property definitions associated with this managed |
| | | // object definition including inherited property definitions. |
| | | private final Map<String, PropertyDefinition<?>> allPropertyDefinitions; |
| | |
| | | AbstractManagedObjectDefinition<? super C, ? super S> parent) { |
| | | this.name = name; |
| | | this.parent = parent; |
| | | this.constraints = new LinkedList<Constraint>(); |
| | | this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>(); |
| | | this.relationDefinitions = new HashMap<String, RelationDefinition<?,?>>(); |
| | | this.allConstraints = new LinkedList<Constraint>(); |
| | | this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>(); |
| | | this.allRelationDefinitions = |
| | | new HashMap<String, RelationDefinition<?, ?>>(); |
| | |
| | | if (parent != null) { |
| | | parent.children.put(name, this); |
| | | |
| | | allConstraints.addAll(parent.getAllConstraints()); |
| | | |
| | | for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) { |
| | | allPropertyDefinitions.put(pd.getName(), pd); |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * Get all the constraints associated with this type of managed |
| | | * object. The returned collection will contain inherited |
| | | * constraints. |
| | | * |
| | | * @return Returns an unmodifiable collection containing all the |
| | | * constraints associated with this type of managed object. |
| | | */ |
| | | public final Collection<Constraint> getAllConstraints() { |
| | | return Collections.unmodifiableCollection(allConstraints); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Get all the property definitions associated with this type of |
| | | * managed object. The returned collection will contain inherited |
| | | * property definitions. |
| | |
| | | |
| | | |
| | | /** |
| | | * Get the constraints defined by this managed object definition. |
| | | * The returned collection will not contain inherited constraints. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the |
| | | * constraints defined by this managed object definition. |
| | | */ |
| | | public final Collection<Constraint> getConstraints() { |
| | | return Collections.unmodifiableCollection(constraints); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the optional description of this managed object definition |
| | | * in the default locale. |
| | | * |
| | |
| | | |
| | | |
| | | /** |
| | | * Deregister a constraint from the managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications and is |
| | | * only intended for internal testing. |
| | | * |
| | | * @param constraint |
| | | * The constraint to be deregistered. |
| | | */ |
| | | protected final void deregisterConstraint(Constraint constraint) { |
| | | constraints.remove(constraint); |
| | | allConstraints.remove(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Deregister a relation definition from the managed object |
| | | * definition. |
| | | * <p> |
| | |
| | | |
| | | |
| | | /** |
| | | * Register a constraint with the managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications. |
| | | * |
| | | * @param constraint |
| | | * The constraint to be registered. |
| | | */ |
| | | protected final void registerConstraint(Constraint constraint) { |
| | | constraints.add(constraint); |
| | | allConstraints.add(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Register a property definition with the managed object definition, |
| | | * overriding any existing property definition with the same name. |
| | | * <p> |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.server.admin.client.ClientConstraintHandler; |
| | | |
| | | |
| | | |
| | | /** |
| | | * An interface for enforcing constraints and dependencies between |
| | | * managed objects and their properties. Constraints express |
| | | * relationships between managed objects and their properties, for |
| | | * example: |
| | | * <ul> |
| | | * <li>referential integrity: where one managed object references |
| | | * another a constraint can enforce referential integrity. The |
| | | * constraint can prevent creation of references to non-existent |
| | | * managed objects, and also prevent deletion of referenced managed |
| | | * objects |
| | | * <li>property dependencies: for example, when a boolean property is |
| | | * <code>true</code>, one or more additional properties must be |
| | | * specified. This is useful for features like SSL, which when |
| | | * enabled, requires that various SSL related configuration options |
| | | * are specified |
| | | * <li>property constraints: for example, when an upper limit |
| | | * property must not have a value which is less than the lower limit |
| | | * property. |
| | | * </ul> |
| | | * On the client-side constraints are enforced immediately before a |
| | | * write operation is performed. That is to say, immediately before a |
| | | * new managed object is created, changes to a managed object are |
| | | * applied, or an existing managed object is deleted. |
| | | */ |
| | | public interface Constraint { |
| | | |
| | | /** |
| | | * Gets the client-side constraint handlers which will be used to |
| | | * enforce this constraint in client applications. |
| | | * |
| | | * @return Returns the client-side constraint handlers which will be |
| | | * used to enforce this constraint in client applications. |
| | | * The returned collection must not be <code>null</code> |
| | | * but maybe empty (indicating that the constrain can only |
| | | * be enforced on the server-side). |
| | | */ |
| | | Collection<ClientConstraintHandler> getClientConstraintHandlers(); |
| | | |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | |
| | | |
| | | |
| | | /** |
| | | * An interface for performing client-side constraint validation. |
| | | * <p> |
| | | * Constraints are evaluated immediately before the client performs a |
| | | * write operation. If one or more constraints fails, the write |
| | | * operation is refused and fails with an |
| | | * {@link OperationRejectedException}. |
| | | * <p> |
| | | * A client constraint handler must override at least one of the |
| | | * provided methods. |
| | | * |
| | | * @see org.opends.server.admin.Constraint |
| | | */ |
| | | public abstract class ClientConstraintHandler { |
| | | |
| | | /** |
| | | * Determines whether or not the newly created managed object which |
| | | * is about to be added to the server configuration satisfies this |
| | | * constraint. |
| | | * <p> |
| | | * If the constraint is not satisfied, the implementation must |
| | | * return <code>false</code> and add a message describing why the |
| | | * constraint was not satisfied. |
| | | * <p> |
| | | * The default implementation is to return <code>true</code>. |
| | | * |
| | | * @param context |
| | | * The management context. |
| | | * @param managedObject |
| | | * The new managed object. |
| | | * @param unacceptableReasons |
| | | * A list of messages to which error messages should be |
| | | * added. |
| | | * @return Returns <code>true</code> if this constraint is |
| | | * satisfied, or <code>false</code> if it is not. |
| | | * @throws AuthorizationException |
| | | * If an authorization failure prevented this constraint |
| | | * from being evaluated. |
| | | * @throws CommunicationException |
| | | * If a communications problem prevented this constraint |
| | | * from being evaluated. |
| | | */ |
| | | public boolean isAddAcceptable(ManagementContext context, |
| | | ManagedObject<?> managedObject, Collection<Message> unacceptableReasons) |
| | | throws AuthorizationException, CommunicationException { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Determines whether or not the changes to an existing managed |
| | | * object which are about to be committed to the server |
| | | * configuration satisfies this constraint. |
| | | * <p> |
| | | * If the constraint is not satisfied, the implementation must |
| | | * return <code>false</code> and add a message describing why the |
| | | * constraint was not satisfied. |
| | | * <p> |
| | | * The default implementation is to return <code>true</code>. |
| | | * |
| | | * @param context |
| | | * The management context. |
| | | * @param managedObject |
| | | * The modified managed object. |
| | | * @param unacceptableReasons |
| | | * A list of messages to which error messages should be |
| | | * added. |
| | | * @return Returns <code>true</code> if this modify is satisfied, |
| | | * or <code>false</code> if it is not. |
| | | * @throws AuthorizationException |
| | | * If an authorization failure prevented this constraint |
| | | * from being evaluated. |
| | | * @throws CommunicationException |
| | | * If a communications problem prevented this constraint |
| | | * from being evaluated. |
| | | */ |
| | | public boolean isModifyAcceptable(ManagementContext context, |
| | | ManagedObject<?> managedObject, Collection<Message> unacceptableReasons) |
| | | throws AuthorizationException, CommunicationException { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Determines whether or not the existing managed object which is |
| | | * about to be deleted from the server configuration satisfies this |
| | | * constraint. |
| | | * <p> |
| | | * If the constraint is not satisfied, the implementation must |
| | | * return <code>false</code> and add a message describing why the |
| | | * constraint was not satisfied. |
| | | * <p> |
| | | * The default implementation is to return <code>true</code>. |
| | | * |
| | | * @param context |
| | | * The management context. |
| | | * @param path |
| | | * The path of the managed object which is about to be |
| | | * deleted. |
| | | * @param unacceptableReasons |
| | | * A list of messages to which error messages should be |
| | | * added. |
| | | * @return Returns <code>true</code> if this constraint is |
| | | * satisfied, or <code>false</code> if it is not. |
| | | * @throws AuthorizationException |
| | | * If an authorization failure prevented this constraint |
| | | * from being evaluated. |
| | | * @throws CommunicationException |
| | | * If a communications problem prevented this constraint |
| | | * from being evaluated. |
| | | */ |
| | | public boolean isDeleteAcceptable(ManagementContext context, |
| | | ManagedObjectPath<?, ?> path, Collection<Message> unacceptableReasons) |
| | | throws AuthorizationException, CommunicationException { |
| | | return true; |
| | | } |
| | | } |
| | |
| | | * this managed object is being modified but it has been |
| | | * removed from the server by another client. |
| | | * @throws OperationRejectedException |
| | | * If the server refuses to add or modify this managed |
| | | * object due to some server-side constraint which cannot |
| | | * be satisfied. |
| | | * If this managed object cannot be added or modified due |
| | | * to some client-side or server-side constraint which |
| | | * cannot be satisfied. |
| | | * @throws AuthorizationException |
| | | * If the server refuses to add or modify this managed |
| | | * object because the client does not have the correct |
| | |
| | | * If the managed object could not be removed because it |
| | | * could not found on the server. |
| | | * @throws OperationRejectedException |
| | | * If the server refuses to remove the managed object due |
| | | * to some server-side constraint which cannot be |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server |
| | | * by another client. |
| | | * @throws AuthorizationException |
| | | * If the server refuses to make the list the managed |
| | | * objects because the client does not have the correct |
| | | * If the server refuses to remove the managed objects |
| | | * because the client does not have the correct |
| | | * privileges. |
| | | * @throws CommunicationException |
| | | * If the client cannot contact the server due to an |
| | |
| | | * If the managed object could not be removed because it |
| | | * could not found on the server. |
| | | * @throws OperationRejectedException |
| | | * If the server refuses to remove the managed object due |
| | | * to some server-side constraint which cannot be |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server |
| | | * by another client. |
| | | * @throws AuthorizationException |
| | | * If the server refuses to make the list the managed |
| | | * objects because the client does not have the correct |
| | | * If the server refuses to remove the managed objects |
| | | * because the client does not have the correct |
| | | * privileges. |
| | | * @throws CommunicationException |
| | | * If the client cannot contact the server due to an |
| | |
| | | |
| | | |
| | | |
| | | import java.util.SortedSet; |
| | | |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | | import org.opends.server.admin.DefinitionDecodingException; |
| | | 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.client.spi.Driver; |
| | | import org.opends.server.admin.std.client.RootCfgClient; |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws AuthorizationException |
| | | * If the server refuses to remove 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> |
| | | boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, |
| | | String name) throws IllegalArgumentException, |
| | | ManagedObjectNotFoundException, OperationRejectedException, |
| | | AuthorizationException, CommunicationException { |
| | | return getDriver().deleteManagedObject(parent, rd, name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws AuthorizationException |
| | | * If the server refuses to remove 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> |
| | | boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) |
| | | throws IllegalArgumentException, ManagedObjectNotFoundException, |
| | | OperationRejectedException, AuthorizationException, |
| | | CommunicationException { |
| | | return getDriver().deleteManagedObject(parent, rd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 final <C extends ConfigurationClient, S extends Configuration> |
| | | ManagedObject<? extends C> getManagedObject( |
| | | ManagedObjectPath<C, S> path) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, |
| | | AuthorizationException, CommunicationException { |
| | | return getDriver().getManagedObject(path); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 { |
| | | return getDriver().getPropertyValue(path, pd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 final <PD> SortedSet<PD> getPropertyValues( |
| | | ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd) |
| | | throws IllegalArgumentException, DefinitionDecodingException, |
| | | AuthorizationException, ManagedObjectNotFoundException, |
| | | CommunicationException, PropertyException { |
| | | return getDriver().getPropertyValues(path, pd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(); |
| | | public final |
| | | ManagedObject<RootCfgClient> getRootConfigurationManagedObject() { |
| | | return getDriver().getRootConfigurationManagedObject(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 getDriver().listManagedObjects(parent, rd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 final <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 { |
| | | return getDriver().listManagedObjects(parent, rd, d); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Determines whether or not the named managed object exists. |
| | | * |
| | | * @param path |
| | | * The path of the named managed object. |
| | | * @return Returns <code>true</code> if the named managed object |
| | | * exists, <code>false</code> otherwise. |
| | | * @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 boolean managedObjectExists(ManagedObjectPath<?, ?> path) |
| | | throws ManagedObjectNotFoundException, AuthorizationException, |
| | | CommunicationException { |
| | | return getDriver().managedObjectExists(path); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the driver associated with this management context. |
| | | * |
| | | * @return Returns the driver associated with this management |
| | | * context. |
| | | */ |
| | | protected abstract Driver getDriver(); |
| | | } |
| | |
| | | */ |
| | | |
| | | package org.opends.server.admin.client; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | | import static org.opends.messages.AdminMessages.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.MessageBuilder; |
| | | import org.opends.server.util.Validator; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This exception is thrown when the server refuses to create, delete, |
| | | * or modify a managed object due to some server-side constraint that |
| | | * cannot be satisified and which cannot be enforced by the client. |
| | | * This exception is thrown when the client or server refuses to |
| | | * create, delete, or modify a managed object due to one or more |
| | | * constraints that cannot be satisfied. |
| | | * <p> |
| | | * Operations can be rejected either by a client-side constraint |
| | | * violation triggered by {@link ClientConstraintHandler}, or by a |
| | | * server-side error. |
| | | * <p> |
| | | * For example, the Directory Server might not be able perform an |
| | | * operation due to some OS related problem, such as lack of disk |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create an operation rejected exception. |
| | | */ |
| | | public OperationRejectedException() { |
| | | // No implementation required. |
| | | // Merge the messages into a single message. |
| | | private static Message getSingleMessage(Collection<Message> messages) { |
| | | Validator.ensureNotNull(messages); |
| | | Validator.ensureTrue(!messages.isEmpty()); |
| | | |
| | | MessageBuilder builder = new MessageBuilder(); |
| | | |
| | | boolean isFirst = true; |
| | | for (Message m : messages) { |
| | | if (!isFirst) { |
| | | builder.append("; "); |
| | | } |
| | | builder.append(m); |
| | | isFirst = false; |
| | | } |
| | | |
| | | return builder.toMessage(); |
| | | } |
| | | |
| | | // The messages describing the constraint violations that occurred. |
| | | private final Collection<Message> messages; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create an operation rejected exception with a cause. |
| | | * Creates a new operation rejected exception with the provided |
| | | * messages. |
| | | * |
| | | * @param cause |
| | | * The cause. |
| | | * @param messages |
| | | * The messages describing the constraint violations that |
| | | * occurred (must be non-<code>null</code> and |
| | | * non-empty). |
| | | */ |
| | | public OperationRejectedException(Throwable cause) { |
| | | super(cause); |
| | | public OperationRejectedException(Collection<Message> messages) { |
| | | super(getSingleMessage(messages)); |
| | | |
| | | this.messages = new ArrayList<Message>(messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create an operation rejected exception with a message and cause. |
| | | * Creates a new operation rejected exception with the provided |
| | | * message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public OperationRejectedException(Message message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Create an operation rejected exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * The message describing the constraint violation that |
| | | * occurred (must be non-<code>null</code> and |
| | | * non-empty). |
| | | */ |
| | | public OperationRejectedException(Message message) { |
| | | super(message); |
| | | this(Collections.singleton(message)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new operation rejected exception with a default |
| | | * message. |
| | | */ |
| | | public OperationRejectedException() { |
| | | this(ERR_OPERATION_REJECTED_DEFAULT.get()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets an unmodifiable collection view of the messages describing |
| | | * the constraint violations that occurred. |
| | | * |
| | | * @return Returns an unmodifiable collection view of the messages |
| | | * describing the constraint violations that occurred. |
| | | */ |
| | | public Collection<Message> getMessages() { |
| | | return Collections.unmodifiableCollection(messages); |
| | | } |
| | | |
| | | } |
| | |
| | | import javax.naming.directory.Attributes; |
| | | import javax.naming.ldap.LdapName; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | |
| | | 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.client.OperationRejectedException; |
| | | import org.opends.server.admin.client.spi.Driver; |
| | | import org.opends.server.admin.client.spi.PropertySet; |
| | | import org.opends.server.admin.std.client.RootCfgClient; |
| | | import org.opends.server.admin.std.meta.RootCfgDefn; |
| | | |
| | | |
| | | |
| | |
| | | // The LDAP connection. |
| | | private final LDAPConnection connection; |
| | | |
| | | // The LDAP management context. |
| | | private final LDAPManagementContext context; |
| | | |
| | | // 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 context |
| | | * The LDAP management context. |
| | | * @param connection |
| | | * The LDAP connection. |
| | | * @param profile |
| | | * The LDAP profile. |
| | | */ |
| | | public LDAPDriver(LDAPConnection connection, LDAPProfile profile) { |
| | | public LDAPDriver(LDAPManagementContext context, LDAPConnection connection, |
| | | LDAPProfile profile) { |
| | | this.context = context; |
| | | this.connection = connection; |
| | | this.profile = profile; |
| | | } |
| | |
| | | */ |
| | | @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 (!managedObjectExists(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 (!managedObjectExists(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, |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() { |
| | | return new LDAPManagedObject<RootCfgClient>(this, |
| | | RootCfgDefn.getInstance(), ManagedObjectPath.emptyPath(), |
| | | new PropertySet(), true, null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, |
| | |
| | | return true; |
| | | } |
| | | |
| | | ManagedObjectPath<?,?> parent = path.parent(); |
| | | ManagedObjectPath<?, ?> parent = path.parent(); |
| | | LdapName dn = LDAPNameBuilder.create(parent, profile); |
| | | if (!entryExists(dn)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected <C extends ConfigurationClient, S extends Configuration> |
| | | void deleteManagedObject( |
| | | ManagedObjectPath<C, S> path) throws OperationRejectedException, |
| | | AuthorizationException, CommunicationException { |
| | | // Delete the entry and any subordinate entries. |
| | | LdapName dn = LDAPNameBuilder.create(path, profile); |
| | | try { |
| | | connection.deleteSubtree(dn); |
| | | } catch (OperationNotSupportedException e) { |
| | | // Unwilling to perform. |
| | | if (e.getMessage() != null) { |
| | | throw new OperationRejectedException(); |
| | | } else { |
| | | Message m = Message.raw("%s", e.getMessage()); |
| | | throw new OperationRejectedException(m); |
| | | } |
| | | } catch (NamingException e) { |
| | | adaptNamingException(e); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected LDAPManagementContext getManagementContext() { |
| | | return context; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adapts a naming exception to an appropriate admin client |
| | | * exception. |
| | | * |
| | |
| | | |
| | | return d.resolveManagedObjectDefinition(resolver); |
| | | } |
| | | |
| | | |
| | | |
| | | // Remove the named managed object. |
| | | private boolean removeManagedObject(ManagedObjectPath<?, ?> path) |
| | | throws CommunicationException, AuthorizationException, |
| | | OperationRejectedException, ManagedObjectNotFoundException { |
| | | if (!managedObjectExists(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()); |
| | | } |
| | | } |
| | | } |
| | |
| | | import javax.naming.ldap.LdapName; |
| | | import javax.naming.ldap.Rdn; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | | import org.opends.server.admin.InstantiableRelationDefinition; |
| | |
| | | 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; |
| | | |
| | | |
| | | |
| | |
| | | final class LDAPManagedObject<T extends ConfigurationClient> extends |
| | | AbstractManagedObject<T> { |
| | | |
| | | /** |
| | | * Constructs a root LDAP managed object associated with the |
| | | * provided LDAP driver. |
| | | * |
| | | * @param driver |
| | | * The LDAP management driver. |
| | | * @return Returns a root LDAP managed object associated with the |
| | | * provided LDAP driver. |
| | | */ |
| | | static ManagedObject<RootCfgClient> getRootManagedObject( |
| | | LDAPDriver driver) { |
| | | return new LDAPManagedObject<RootCfgClient>(driver, RootCfgDefn |
| | | .getInstance(), ManagedObjectPath.emptyPath(), new PropertySet(), true, |
| | | null); |
| | | } |
| | | |
| | | // The LDAP management driver associated with this managed object. |
| | | private final LDAPDriver driver; |
| | | |
| | |
| | | driver.getLDAPConnection().createEntry(dn, attributes); |
| | | } catch (OperationNotSupportedException e) { |
| | | // Unwilling to perform. |
| | | throw new OperationRejectedException(e); |
| | | if (e.getMessage() != null) { |
| | | throw new OperationRejectedException(); |
| | | } else { |
| | | Message m = Message.raw("%s", e.getMessage()); |
| | | throw new OperationRejectedException(m); |
| | | } |
| | | } catch (NamingException e) { |
| | | driver.adaptNamingException(e); |
| | | } |
| | |
| | | throw new ManagedObjectAlreadyExistsException(); |
| | | } catch (OperationNotSupportedException e) { |
| | | // Unwilling to perform. |
| | | throw new OperationRejectedException(e); |
| | | if (e.getMessage() != null) { |
| | | throw new OperationRejectedException(); |
| | | } else { |
| | | Message m = Message.raw("%s", e.getMessage()); |
| | | throw new OperationRejectedException(m); |
| | | } |
| | | } catch (NamingException e) { |
| | | driver.adaptNamingException(e); |
| | | } |
| | |
| | | throw new AuthorizationException(e); |
| | | } catch (OperationNotSupportedException e) { |
| | | // Unwilling to perform. |
| | | throw new OperationRejectedException(e); |
| | | if (e.getMessage() != null) { |
| | | throw new OperationRejectedException(); |
| | | } else { |
| | | Message m = Message.raw("%s", e.getMessage()); |
| | | throw new OperationRejectedException(m); |
| | | } |
| | | } catch (NamingException e) { |
| | | // Just treat it as a communication problem. |
| | | throw new CommunicationException(e); |
| | |
| | | |
| | | |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagementContext; |
| | | import org.opends.server.admin.std.client.RootCfgClient; |
| | | import org.opends.server.admin.client.spi.Driver; |
| | | import org.opends.server.util.Validator; |
| | | |
| | | |
| | |
| | | // Private constructor. |
| | | private LDAPManagementContext(LDAPConnection connection, |
| | | LDAPProfile profile) { |
| | | this.driver = new LDAPDriver(connection, profile); |
| | | this.driver = new LDAPDriver(this, connection, profile); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() { |
| | | return LDAPManagedObject.getRootManagedObject(driver); |
| | | @Override |
| | | protected Driver getDriver() { |
| | | return driver; |
| | | } |
| | | } |
| | |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | | import org.opends.server.admin.Constraint; |
| | | import org.opends.server.admin.DefaultBehaviorException; |
| | | import org.opends.server.admin.DefinitionDecodingException; |
| | | import org.opends.server.admin.IllegalPropertyValueException; |
| | |
| | | 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.ClientConstraintHandler; |
| | | 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.ManagementContext; |
| | | import org.opends.server.admin.client.MissingMandatoryPropertiesException; |
| | | import org.opends.server.admin.client.OperationRejectedException; |
| | | |
| | |
| | | throw new MissingMandatoryPropertiesException(exceptions); |
| | | } |
| | | |
| | | // Now enforce any constraints. |
| | | List<Message> messages = new LinkedList<Message>(); |
| | | boolean isAcceptable = true; |
| | | ManagementContext context = getDriver().getManagementContext(); |
| | | |
| | | for (Constraint constraint : definition.getAllConstraints()) { |
| | | for (ClientConstraintHandler handler : constraint |
| | | .getClientConstraintHandlers()) { |
| | | if (existsOnServer) { |
| | | if (!handler.isModifyAcceptable(context, this, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | } else { |
| | | if (!handler.isAddAcceptable(context, this, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!isAcceptable) { |
| | | throw new OperationRejectedException(messages); |
| | | } |
| | | |
| | | // Commit the managed object. |
| | | if (existsOnServer) { |
| | | modifyExistingManagedObject(); |
| | |
| | | * 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. |
| | | * If the managed object cannot be added due to some |
| | | * client-side or 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 |
| | |
| | | * 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 |
| | | * If the managed object cannot be added due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied. |
| | | * @throws AuthorizationException |
| | | * If the server refuses to modify this managed object |
| | |
| | | import java.util.ArrayList; |
| | | 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 org.opends.messages.Message; |
| | | 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.Constraint; |
| | | import org.opends.server.admin.DefaultBehaviorException; |
| | | import org.opends.server.admin.DefaultBehaviorProviderVisitor; |
| | | import org.opends.server.admin.DefinedDefaultBehaviorProvider; |
| | |
| | | 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.UndefinedDefaultBehaviorProvider; |
| | | import org.opends.server.admin.DefinitionDecodingException.Reason; |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.ClientConstraintHandler; |
| | | 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.ManagementContext; |
| | | import org.opends.server.admin.client.OperationRejectedException; |
| | | import org.opends.server.admin.std.client.RootCfgClient; |
| | | |
| | | |
| | | |
| | |
| | | * @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). |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or 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 |
| | | * If the server refuses to remove 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> |
| | | public final <C extends ConfigurationClient, S extends Configuration> |
| | | boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, |
| | | String name) throws IllegalArgumentException, |
| | | ManagedObjectNotFoundException, OperationRejectedException, |
| | | AuthorizationException, CommunicationException; |
| | | AuthorizationException, CommunicationException { |
| | | validateRelationDefinition(parent, rd); |
| | | ManagedObjectPath<?, ?> child = parent.child(rd, name); |
| | | return doDeleteManagedObject(child); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | * @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). |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or 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 |
| | | * If the server refuses to remove 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> |
| | | public final <C extends ConfigurationClient, S extends Configuration> |
| | | boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) |
| | | throws IllegalArgumentException, ManagedObjectNotFoundException, |
| | | OperationRejectedException, AuthorizationException, |
| | | CommunicationException; |
| | | CommunicationException { |
| | | validateRelationDefinition(parent, rd); |
| | | ManagedObjectPath<?, ?> child = parent.child(rd); |
| | | return doDeleteManagedObject(child); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Gets the root configuration managed object associated with this |
| | | * management context driver. |
| | | * |
| | | * @return Returns the root configuration managed object associated |
| | | * with this management context driver. |
| | | */ |
| | | public abstract |
| | | ManagedObject<RootCfgClient> getRootConfigurationManagedObject(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Lists the child managed objects of the named parent managed |
| | | * object. |
| | | * |
| | |
| | | |
| | | |
| | | /** |
| | | * Deletes the named managed object. |
| | | * <p> |
| | | * Implementations do not need check whether the named managed |
| | | * object exists, nor do they need to enforce client constraints. |
| | | * |
| | | * @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 path |
| | | * The path of the managed object to be deleted. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed 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 remove 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. |
| | | */ |
| | | protected abstract <C extends ConfigurationClient, S extends Configuration> |
| | | void deleteManagedObject( |
| | | ManagedObjectPath<C, S> path) throws OperationRejectedException, |
| | | AuthorizationException, CommunicationException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the default values for the specified property. |
| | | * |
| | | * @param <PD> |
| | |
| | | return v.find(p, pd); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Gets the management context associated with this driver. |
| | | * |
| | | * @return Returns the management context associated with this |
| | | * driver. |
| | | */ |
| | | protected abstract ManagementContext getManagementContext(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Validate that a relation definition belongs to the managed object |
| | | * referenced by the provided path. |
| | | * |
| | | * @param path |
| | | * The parent managed object path. |
| | | * @param rd |
| | | * The relation definition. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition does not belong to the |
| | | * managed object definition. |
| | | */ |
| | | protected final 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()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Remove a managed object, first ensuring that the parent exists, |
| | | // then ensuring that the child exists, before ensuring that any |
| | | // constraints are satisfied. |
| | | private <C extends ConfigurationClient, S extends Configuration> |
| | | boolean doDeleteManagedObject( |
| | | ManagedObjectPath<C, S> path) throws ManagedObjectNotFoundException, |
| | | OperationRejectedException, AuthorizationException, |
| | | CommunicationException { |
| | | // First make sure that the parent exists. |
| | | if (!managedObjectExists(path.parent())) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | // Make sure that the targeted managed object exists. |
| | | if (!managedObjectExists(path)) { |
| | | return false; |
| | | } |
| | | |
| | | // The targeted managed object is guaranteed to exist, so enforce |
| | | // any constraints. |
| | | AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); |
| | | List<Message> messages = new LinkedList<Message>(); |
| | | boolean isAcceptable = true; |
| | | |
| | | for (Constraint constraint : d.getAllConstraints()) { |
| | | for (ClientConstraintHandler handler : constraint |
| | | .getClientConstraintHandlers()) { |
| | | ManagementContext context = getManagementContext(); |
| | | if (!handler.isDeleteAcceptable(context, path, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!isAcceptable) { |
| | | throw new OperationRejectedException(messages); |
| | | } |
| | | |
| | | deleteManagedObject(path); |
| | | return true; |
| | | } |
| | | |
| | | } |
| | |
| | | private TestChildCfgDefn() { |
| | | super("test-child", null); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds a constraint temporarily with this test definition. |
| | | * |
| | | * @param constraint The constraint. |
| | | */ |
| | | public void addConstraint(Constraint constraint) { |
| | | registerConstraint(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Removes a constraint from this test definition. |
| | | * |
| | | * @param constraint The constraint. |
| | | */ |
| | | public void removeConstraint(Constraint constraint) { |
| | | deregisterConstraint(constraint); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.AdminTestCase; |
| | | import org.opends.server.admin.Constraint; |
| | | import org.opends.server.admin.DefinitionDecodingException; |
| | | import org.opends.server.admin.LDAPProfile; |
| | | import org.opends.server.admin.ManagedObjectAlreadyExistsException; |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests creation of a child managed object succeeds when registered |
| | | * add constraints succeed. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testAddConstraintSuccess() throws Exception { |
| | | Constraint constraint = new MockConstraint(true, false, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | |
| | | try { |
| | | CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection( |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-type", "description"); |
| | | |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn |
| | | .getInstance(), "test child new", null); |
| | | child.setMandatoryBooleanProperty(true); |
| | | child.setMandatoryReadOnlyAttributeTypeProperty(DirectoryServer |
| | | .getAttributeType("description")); |
| | | child.commit(); |
| | | |
| | | c.assertEntryIsCreated(); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests creation of a child managed object fails when registered |
| | | * add constraints fail. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test(expectedExceptions=OperationRejectedException.class) |
| | | public void testAddConstraintFail() throws Exception { |
| | | Constraint constraint = new MockConstraint(false, true, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | |
| | | try { |
| | | CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection( |
| | | "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedAttribute("cn", "test child new"); |
| | | c.addExpectedAttribute("objectclass", "top", "ds-cfg-virtual-attribute"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-enabled", "true"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-class", |
| | | "org.opends.server.extensions.UserDefinedVirtualAttributeProvider"); |
| | | c.addExpectedAttribute("ds-cfg-virtual-attribute-type", "description"); |
| | | |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn |
| | | .getInstance(), "test child new", null); |
| | | child.setMandatoryBooleanProperty(true); |
| | | child.setMandatoryReadOnlyAttributeTypeProperty(DirectoryServer |
| | | .getAttributeType("description")); |
| | | child.commit(); |
| | | Assert.fail("The add constraint failed to prevent creation of the managed object"); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests removal of a child managed object succeeds when registered |
| | | * remove constraints succeed. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testRemoveConstraintSuccess() throws Exception { |
| | | Constraint constraint = new MockConstraint(false, false, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | |
| | | try { |
| | | DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection( |
| | | "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | parent.removeTestChild("test child 1"); |
| | | c.assertSubtreeIsDeleted(); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests removal of a child managed object fails when registered |
| | | * remove constraints fails. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test(expectedExceptions=OperationRejectedException.class) |
| | | public void testRemoveConstraintFail() throws Exception { |
| | | Constraint constraint = new MockConstraint(true, true, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | |
| | | try { |
| | | DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection( |
| | | "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | parent.removeTestChild("test child 1"); |
| | | Assert.fail("The remove constraint failed to prevent removal of the managed object"); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests modification of a child managed object succeeds when |
| | | * registered remove constraints succeed. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test |
| | | public void testModifyConstraintSuccess() throws Exception { |
| | | Constraint constraint = new MockConstraint(false, true, false); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | |
| | | try { |
| | | ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection( |
| | | "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedModification("ds-cfg-virtual-attribute-base-dn"); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.getTestChild("test child 2"); |
| | | child.setOptionalMultiValuedDNProperty1(Collections.<DN> emptySet()); |
| | | child.commit(); |
| | | Assert.assertTrue(c.isEntryModified()); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests modification of a child managed object fails when |
| | | * registered remove constraints fails. |
| | | * |
| | | * @throws Exception |
| | | * If an unexpected error occurred. |
| | | */ |
| | | @Test(expectedExceptions = OperationRejectedException.class) |
| | | public void testModifyConstraintFail() throws Exception { |
| | | Constraint constraint = new MockConstraint(true, false, true); |
| | | TestChildCfgDefn.getInstance().addConstraint(constraint); |
| | | |
| | | try { |
| | | ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection( |
| | | "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config"); |
| | | c.importLDIF(TEST_LDIF); |
| | | c.addExpectedModification("ds-cfg-virtual-attribute-base-dn"); |
| | | ManagementContext ctx = LDAPManagementContext.createFromContext(c); |
| | | TestParentCfgClient parent = getTestParent(ctx, "test parent 1"); |
| | | TestChildCfgClient child = parent.getTestChild("test child 2"); |
| | | child.setOptionalMultiValuedDNProperty1(Collections.<DN> emptySet()); |
| | | child.commit(); |
| | | Assert |
| | | .fail("The modify constraint failed to prevent modification of the managed object"); |
| | | } finally { |
| | | // Clean up. |
| | | TestChildCfgDefn.getInstance().removeConstraint(constraint); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Asserts that the actual set of DNs contains the expected values. |
| | | private void assertDNSetEquals(SortedSet<DN> actual, String... expected) { |
| | | String[] actualStrings = new String[actual.size()]; |
| New file |
| | |
| | | /* |
| | | * 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.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.Constraint; |
| | | import org.opends.server.admin.ManagedObjectPath; |
| | | import org.opends.server.admin.client.AuthorizationException; |
| | | import org.opends.server.admin.client.ClientConstraintHandler; |
| | | import org.opends.server.admin.client.CommunicationException; |
| | | import org.opends.server.admin.client.ManagedObject; |
| | | import org.opends.server.admin.client.ManagementContext; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A mock constraint which can be configured to refuse various types |
| | | * of operation. |
| | | */ |
| | | public final class MockConstraint implements Constraint { |
| | | |
| | | /** |
| | | * Mock client constraint handler. |
| | | */ |
| | | private class Handler extends ClientConstraintHandler { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAddAcceptable(ManagementContext context, |
| | | ManagedObject<?> managedObject, Collection<Message> unacceptableReasons) |
| | | throws AuthorizationException, CommunicationException { |
| | | if (!allowAdds) { |
| | | unacceptableReasons.add(Message.raw("Adds not allowed")); |
| | | } |
| | | |
| | | return allowAdds; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isDeleteAcceptable(ManagementContext context, |
| | | ManagedObjectPath<?, ?> path, Collection<Message> unacceptableReasons) |
| | | throws AuthorizationException, CommunicationException { |
| | | if (!allowDeletes) { |
| | | unacceptableReasons.add(Message.raw("Deletes not allowed")); |
| | | } |
| | | |
| | | return allowDeletes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isModifyAcceptable(ManagementContext context, |
| | | ManagedObject<?> managedObject, Collection<Message> unacceptableReasons) |
| | | throws AuthorizationException, CommunicationException { |
| | | if (!allowModifies) { |
| | | unacceptableReasons.add(Message.raw("Modifies not allowed")); |
| | | } |
| | | |
| | | return allowModifies; |
| | | } |
| | | |
| | | } |
| | | |
| | | // Determines if add operations are allowed. |
| | | private final boolean allowAdds; |
| | | |
| | | // Determines if modify operations are allowed. |
| | | private final boolean allowModifies; |
| | | |
| | | // Determines if delete operations are allowed. |
| | | private final boolean allowDeletes; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new mock constraint. |
| | | * |
| | | * @param allowAdds |
| | | * Determines if add operations are allowed. |
| | | * @param allowModifies |
| | | * Determines if modify operations are allowed. |
| | | * @param allowDeletes |
| | | * Determines if delete operations are allowed. |
| | | */ |
| | | public MockConstraint(boolean allowAdds, boolean allowModifies, |
| | | boolean allowDeletes) { |
| | | this.allowAdds = allowAdds; |
| | | this.allowModifies = allowModifies; |
| | | this.allowDeletes = allowDeletes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ClientConstraintHandler> getClientConstraintHandlers() { |
| | | return Collections.<ClientConstraintHandler> singleton(new Handler()); |
| | | } |
| | | |
| | | } |