| | |
| | | */ |
| | | package org.opends.server.admin.client.spi; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.opends.server.admin.AbstractManagedObjectDefinition; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.ConfigurationClient; |
| | |
| | | import org.opends.server.admin.client.OperationRejectedException; |
| | | import org.opends.server.admin.client.OperationRejectedException.OperationType; |
| | | |
| | | |
| | | |
| | | /** |
| | | * An abstract managed object implementation. |
| | | * |
| | | * @param <T> |
| | | * The type of client configuration represented by the client |
| | | * managed object. |
| | | * The type of client configuration represented by the client managed |
| | | * object. |
| | | */ |
| | | public abstract class AbstractManagedObject<T extends ConfigurationClient> |
| | | implements ManagedObject<T> { |
| | | |
| | | /** |
| | | * Creates any default managed objects associated with a relation |
| | | * definition. |
| | | */ |
| | | private final class DefaultManagedObjectFactory implements |
| | | RelationDefinitionVisitor<Void, Void> { |
| | | |
| | | // Possible exceptions. |
| | | private AuthorizationException ae = null; |
| | | |
| | | private ManagedObjectAlreadyExistsException moaee = null; |
| | | |
| | | private MissingMandatoryPropertiesException mmpe = null; |
| | | |
| | | private ConcurrentModificationException cme = null; |
| | | |
| | | private OperationRejectedException ore = null; |
| | | |
| | | private CommunicationException ce = null; |
| | | |
| | | |
| | | public abstract class AbstractManagedObject<T extends ConfigurationClient> implements ManagedObject<T> { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * Creates any default managed objects associated with a relation |
| | | * definition. |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Void visitInstantiable( |
| | | InstantiableRelationDefinition<C, S> rd, Void p) { |
| | | for (String name : rd.getDefaultManagedObjectNames()) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd |
| | | .getDefaultManagedObject(name); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo |
| | | .getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child; |
| | | try { |
| | | child = createChild(rd, d, name, null); |
| | | } catch (IllegalManagedObjectNameException e) { |
| | | // This should not happen. |
| | | throw new RuntimeException(e); |
| | | private final class DefaultManagedObjectFactory implements RelationDefinitionVisitor<Void, Void> { |
| | | |
| | | // Possible exceptions. |
| | | private AuthorizationException ae = null; |
| | | |
| | | private ManagedObjectAlreadyExistsException moaee = null; |
| | | |
| | | private MissingMandatoryPropertiesException mmpe = null; |
| | | |
| | | private ConcurrentModificationException cme = null; |
| | | |
| | | private OperationRejectedException ore = null; |
| | | |
| | | private CommunicationException ce = null; |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitInstantiable( |
| | | InstantiableRelationDefinition<C, S> rd, Void p) { |
| | | for (String name : rd.getDefaultManagedObjectNames()) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd.getDefaultManagedObject(name); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo.getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child; |
| | | try { |
| | | child = createChild(rd, d, name, null); |
| | | } catch (IllegalManagedObjectNameException e) { |
| | | // This should not happen. |
| | | throw new RuntimeException(e); |
| | | } |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitOptional( |
| | | OptionalRelationDefinition<C, S> rd, Void p) { |
| | | if (rd.getDefaultManagedObject() != null) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd.getDefaultManagedObject(); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo.getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child = createChild(rd, d, null); |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitSingleton( |
| | | SingletonRelationDefinition<C, S> rd, Void p) { |
| | | // Do nothing - not possible to create singletons |
| | | // dynamically. |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitSet(SetRelationDefinition<C, S> rd, |
| | | Void p) { |
| | | for (String name : rd.getDefaultManagedObjectNames()) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd.getDefaultManagedObject(name); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo.getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child = createChild(rd, d, null); |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // Create the child managed object. |
| | | private void createDefaultManagedObject(ManagedObjectDefinition<?, ?> d, ManagedObject<?> child, |
| | | DefaultManagedObject<?, ?> dmo) { |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | | setPropertyValues(child, pd, dmo); |
| | | } |
| | | |
| | | try { |
| | | child.commit(); |
| | | } catch (AuthorizationException e) { |
| | | ae = e; |
| | | } catch (ManagedObjectAlreadyExistsException e) { |
| | | moaee = e; |
| | | } catch (MissingMandatoryPropertiesException e) { |
| | | mmpe = e; |
| | | } catch (ConcurrentModificationException e) { |
| | | cme = e; |
| | | } catch (OperationRejectedException e) { |
| | | ore = e; |
| | | } catch (CommunicationException e) { |
| | | ce = e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Creates the default managed objects associated with the provided |
| | | * relation definition. |
| | | * |
| | | * @param rd |
| | | * The relation definition. |
| | | */ |
| | | private void createDefaultManagedObjects(RelationDefinition<?, ?> rd) throws AuthorizationException, |
| | | CommunicationException, ConcurrentModificationException, MissingMandatoryPropertiesException, |
| | | ManagedObjectAlreadyExistsException, OperationRejectedException { |
| | | rd.accept(this, null); |
| | | |
| | | if (ae != null) { |
| | | throw ae; |
| | | } else if (ce != null) { |
| | | throw ce; |
| | | } else if (cme != null) { |
| | | throw cme; |
| | | } else if (mmpe != null) { |
| | | throw mmpe; |
| | | } else if (moaee != null) { |
| | | throw moaee; |
| | | } else if (ore != null) { |
| | | throw ore; |
| | | } |
| | | } |
| | | |
| | | // Set property values. |
| | | private <PD> void setPropertyValues(ManagedObject<?> mo, PropertyDefinition<PD> pd, |
| | | DefaultManagedObject<?, ?> dmo) { |
| | | mo.setPropertyValues(pd, dmo.getPropertyValues(pd)); |
| | | } |
| | | } |
| | | |
| | | // 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; |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Void visitOptional( |
| | | OptionalRelationDefinition<C, S> rd, Void p) { |
| | | if (rd.getDefaultManagedObject() != null) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd |
| | | .getDefaultManagedObject(); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo |
| | | .getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child = createChild(rd, d, null); |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Void visitSingleton( |
| | | SingletonRelationDefinition<C, S> rd, Void p) { |
| | | // Do nothing - not possible to create singletons |
| | | // dynamically. |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> |
| | | Void visitSet( |
| | | SetRelationDefinition<C, S> rd, Void p) { |
| | | for (String name : rd.getDefaultManagedObjectNames()) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd |
| | | .getDefaultManagedObject(name); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo |
| | | .getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child = createChild(rd, d, null); |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | // Create the child managed object. |
| | | private void createDefaultManagedObject(ManagedObjectDefinition<?, ?> d, |
| | | ManagedObject<?> child, DefaultManagedObject<?, ?> dmo) { |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | | setPropertyValues(child, pd, dmo); |
| | | } |
| | | |
| | | try { |
| | | child.commit(); |
| | | } catch (AuthorizationException e) { |
| | | ae = e; |
| | | } catch (ManagedObjectAlreadyExistsException e) { |
| | | moaee = e; |
| | | } catch (MissingMandatoryPropertiesException e) { |
| | | mmpe = e; |
| | | } catch (ConcurrentModificationException e) { |
| | | cme = e; |
| | | } catch (OperationRejectedException e) { |
| | | ore = e; |
| | | } catch (CommunicationException e) { |
| | | ce = e; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates the default managed objects associated with the |
| | | * provided relation definition. |
| | | * Creates a new abstract managed object. |
| | | * |
| | | * @param rd |
| | | * The relation definition. |
| | | * @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. |
| | | */ |
| | | private void createDefaultManagedObjects(RelationDefinition<?, ?> rd) |
| | | throws AuthorizationException, CommunicationException, |
| | | ConcurrentModificationException, MissingMandatoryPropertiesException, |
| | | ManagedObjectAlreadyExistsException, OperationRejectedException { |
| | | rd.accept(this, null); |
| | | |
| | | if (ae != null) { |
| | | throw ae; |
| | | } else if (ce != null) { |
| | | throw ce; |
| | | } else if (cme != null) { |
| | | throw cme; |
| | | } else if (mmpe != null) { |
| | | throw mmpe; |
| | | } else if (moaee != null) { |
| | | throw moaee; |
| | | } else if (ore != null) { |
| | | throw ore; |
| | | } |
| | | 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)); |
| | | } |
| | | } |
| | | |
| | | // Set property values. |
| | | private <PD> void setPropertyValues(ManagedObject<?> mo, |
| | | PropertyDefinition<PD> pd, DefaultManagedObject<?, ?> dmo) { |
| | | mo.setPropertyValues(pd, dmo.getPropertyValues(pd)); |
| | | } |
| | | } |
| | | if (!exceptions.isEmpty()) { |
| | | throw new MissingMandatoryPropertiesException(definition.getUserFriendlyName(), exceptions, !existsOnServer); |
| | | } |
| | | |
| | | // Now enforce any constraints. |
| | | List<LocalizableMessage> messages = new LinkedList<LocalizableMessage>(); |
| | | 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) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // The managed object definition associated with this managed |
| | | // object. |
| | | private final ManagedObjectDefinition<T, ? extends Configuration> definition; |
| | | if (!isAcceptable) { |
| | | if (existsOnServer) { |
| | | throw new OperationRejectedException(OperationType.MODIFY, definition.getUserFriendlyName(), messages); |
| | | } else { |
| | | throw new OperationRejectedException(OperationType.CREATE, definition.getUserFriendlyName(), messages); |
| | | } |
| | | } |
| | | |
| | | // 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(definition |
| | | .getUserFriendlyName(), exceptions, !existsOnServer); |
| | | } |
| | | |
| | | // 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()) { |
| | | // Commit the managed object. |
| | | if (existsOnServer) { |
| | | if (!handler.isModifyAcceptable(context, this, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | modifyExistingManagedObject(); |
| | | } else { |
| | | if (!handler.isAddAcceptable(context, this, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | addNewManagedObject(); |
| | | } |
| | | } |
| | | if (!isAcceptable) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!isAcceptable) { |
| | | if (existsOnServer) { |
| | | throw new OperationRejectedException(OperationType.MODIFY, definition |
| | | .getUserFriendlyName(), messages); |
| | | } else { |
| | | throw new OperationRejectedException(OperationType.CREATE, definition |
| | | .getUserFriendlyName(), messages); |
| | | } |
| | | } |
| | | // Make all pending property values active. |
| | | properties.commit(); |
| | | |
| | | // Commit the managed object. |
| | | if (existsOnServer) { |
| | | modifyExistingManagedObject(); |
| | | } else { |
| | | addNewManagedObject(); |
| | | } |
| | | // If the managed object was created make sure that any default |
| | | // subordinate managed objects are also created. |
| | | if (!existsOnServer) { |
| | | DefaultManagedObjectFactory factory = new DefaultManagedObjectFactory(); |
| | | for (RelationDefinition<?, ?> rd : definition.getAllRelationDefinitions()) { |
| | | factory.createDefaultManagedObjects(rd); |
| | | } |
| | | |
| | | // Make all pending property values active. |
| | | properties.commit(); |
| | | |
| | | // If the managed object was created make sure that any default |
| | | // subordinate managed objects are also created. |
| | | if (!existsOnServer) { |
| | | DefaultManagedObjectFactory factory = new DefaultManagedObjectFactory(); |
| | | for (RelationDefinition<?, ?> rd : |
| | | definition.getAllRelationDefinitions()) { |
| | | factory.createDefaultManagedObjects(rd); |
| | | } |
| | | |
| | | existsOnServer = true; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@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, |
| | | CC extends C> |
| | | ManagedObject<CC> createChild( |
| | | SetRelationDefinition<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 <C extends ConfigurationClient, S extends Configuration> |
| | | ManagedObject<? extends C> getChild( |
| | | SetRelationDefinition<C, S> r, String name) |
| | | throws IllegalArgumentException, DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, |
| | | ConcurrentModificationException, AuthorizationException, |
| | | CommunicationException { |
| | | validateRelationDefinition(r); |
| | | ensureThisManagedObjectExists(); |
| | | Driver ctx = getDriver(); |
| | | |
| | | AbstractManagedObjectDefinition<C, S> d = r.getChildDefinition(); |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> cd; |
| | | |
| | | try |
| | | { |
| | | cd = d.getChild(name); |
| | | } |
| | | catch (IllegalArgumentException e) |
| | | { |
| | | // Unrecognized definition name - report this as a decoding |
| | | // exception. |
| | | throw new DefinitionDecodingException(d, |
| | | Reason.WRONG_TYPE_INFORMATION); |
| | | } |
| | | |
| | | return ctx.getManagedObject(path.child(r, cd)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@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.managedObjectExists(path.child(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> |
| | | String[] listChildren( |
| | | SetRelationDefinition<C, S> r) throws IllegalArgumentException, |
| | | ConcurrentModificationException, AuthorizationException, |
| | | CommunicationException { |
| | | return listChildren(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> |
| | | String[] listChildren( |
| | | SetRelationDefinition<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 <C extends ConfigurationClient, S extends Configuration> |
| | | void removeChild( |
| | | SetRelationDefinition<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 <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); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | |
| | | builder.append("{ TYPE="); |
| | | builder.append(definition.getName()); |
| | | builder.append(", PATH=\""); |
| | | builder.append(path); |
| | | builder.append('\"'); |
| | | for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) { |
| | | builder.append(", "); |
| | | builder.append(pd.getName()); |
| | | builder.append('='); |
| | | builder.append(getPropertyValues(pd)); |
| | | } |
| | | builder.append(" }"); |
| | | |
| | | return builder.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 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 |
| | | * 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 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 |
| | | * 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); |
| | | existsOnServer = true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Set the naming property if there is one. |
| | | if (namingPropertyDefinition != null) { |
| | | PD value = namingPropertyDefinition.decodeValue(name); |
| | | childProperties.setPropertyValues(namingPropertyDefinition, Collections |
| | | .singleton(value)); |
| | | } |
| | | /** |
| | | * {@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); |
| | | |
| | | 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 { |
| | | if (!ctx.managedObjectExists(path)) { |
| | | throw new ConcurrentModificationException(); |
| | | // Empty names are not allowed. |
| | | if (name.trim().length() == 0) { |
| | | throw new IllegalManagedObjectNameException(name); |
| | | } |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | |
| | | // 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); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 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()); |
| | | /** |
| | | * {@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, CC extends C> ManagedObject<CC> createChild( |
| | | SetRelationDefinition<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 <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | SetRelationDefinition<C, S> r, String name) throws IllegalArgumentException, DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | AuthorizationException, CommunicationException { |
| | | validateRelationDefinition(r); |
| | | ensureThisManagedObjectExists(); |
| | | Driver ctx = getDriver(); |
| | | |
| | | AbstractManagedObjectDefinition<C, S> d = r.getChildDefinition(); |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> cd; |
| | | |
| | | try { |
| | | cd = d.getChild(name); |
| | | } catch (IllegalArgumentException e) { |
| | | // Unrecognized definition name - report this as a decoding |
| | | // exception. |
| | | throw new DefinitionDecodingException(d, Reason.WRONG_TYPE_INFORMATION); |
| | | } |
| | | |
| | | return ctx.getManagedObject(path.child(r, cd)); |
| | | } |
| | | |
| | | /** |
| | | * {@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.managedObjectExists(path.child(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> String[] listChildren( |
| | | SetRelationDefinition<C, S> r) throws IllegalArgumentException, ConcurrentModificationException, |
| | | AuthorizationException, CommunicationException { |
| | | return listChildren(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | SetRelationDefinition<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 <C extends ConfigurationClient, S extends Configuration> void removeChild( |
| | | SetRelationDefinition<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 <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); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | |
| | | builder.append("{ TYPE="); |
| | | builder.append(definition.getName()); |
| | | builder.append(", PATH=\""); |
| | | builder.append(path); |
| | | builder.append('\"'); |
| | | for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) { |
| | | builder.append(", "); |
| | | builder.append(pd.getName()); |
| | | builder.append('='); |
| | | builder.append(getPropertyValues(pd)); |
| | | } |
| | | builder.append(" }"); |
| | | |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 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 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 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 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 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 { |
| | | if (!ctx.managedObjectExists(path)) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } 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()); |
| | | } |
| | | } |
| | | |
| | | } |