/*
 * 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
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 */
package org.opends.server.admin.std.meta;



import java.util.Collection;
import java.util.SortedSet;
import org.opends.server.admin.AdministratorAction;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.DefaultBehaviorProvider;
import org.opends.server.admin.DefinedDefaultBehaviorProvider;
import org.opends.server.admin.DNPropertyDefinition;
import org.opends.server.admin.DurationPropertyDefinition;
import org.opends.server.admin.EnumPropertyDefinition;
import org.opends.server.admin.IntegerPropertyDefinition;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.PropertyIsReadOnlyException;
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.PropertyProvider;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.admin.std.client.ReplicationDomainCfgClient;
import org.opends.server.admin.std.server.ReplicationDomainCfg;
import org.opends.server.admin.StringPropertyDefinition;
import org.opends.server.admin.Tag;
import org.opends.server.admin.TopCfgDefn;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.types.DN;



/**
 * An interface for querying the Replication Domain managed object
 * definition meta information.
 * <p>
 * A Replication Domain comprises of several Directory Servers sharing
 * the same synchronized set of data.
 */
public final class ReplicationDomainCfgDefn extends ManagedObjectDefinition<ReplicationDomainCfgClient, ReplicationDomainCfg> {

  // The singleton configuration definition instance.
  private static final ReplicationDomainCfgDefn INSTANCE = new ReplicationDomainCfgDefn();



  /**
   * Defines the set of permissable values for the "assured-type" property.
   * <p>
   * Defines the assured mode of the replicated domain.
   * <p>
   * The assured mode can be disable or enabled. When enabled, two sub
   * modes are available: Safe Data or Safe Read modes.
   */
  public static enum AssuredType {

    /**
     * Updates sent for replication (for being replayed on other LDAP
     * servers of the topology) are sent without waiting for any
     * aknowledgement and the LDAP client call returns immediately.
     */
    NOT_ASSURED("not-assured"),



    /**
     * Assured mode is enabled in Safe Data sub mode: updates sent for
     * replication are subject to acknowledgement defined by the
     * assured-sd-level property. After acknowlegement is received,
     * LDAP client call returns.
     */
    SAFE_DATA("safe-data"),



    /**
     * Assured mode is enabled in Safe Read sub mode: updates sent for
     * replication are subject to acknowledgement of LDAP servers of
     * the topology having the same group id than us (defined with
     * assured-sr-group-id property). After acknowlegement is received,
     * LDAP client call returns.
     */
    SAFE_READ("safe-read");



    // String representation of the value.
    private final String name;



    // Private constructor.
    private AssuredType(String name) { this.name = name; }



    /**
     * {@inheritDoc}
     */
    public String toString() { return name; }

  }



  /**
   * Defines the set of permissable values for the "isolation-policy" property.
   * <p>
   * Specifies the behavior of the Directory Server if a write
   * operation is attempted on the data within the Replication Domain
   * when none of the configured Replication Servers are available.
   */
  public static enum IsolationPolicy {

    /**
     * Indicates that updates should be accepted even though it is not
     * possible to send them to any Replication Server. Best effort is
     * made to re-send those updates to a Replication Servers when one
     * of them is available, however those changes are at risk because
     * they are only available from the historical information. This
     * mode can also introduce high replication latency.
     */
    ACCEPT_ALL_UPDATES("accept-all-updates"),



    /**
     * Indicates that all updates attempted on this Replication Domain
     * are rejected when no Replication Server is available.
     */
    REJECT_ALL_UPDATES("reject-all-updates");



    // String representation of the value.
    private final String name;



    // Private constructor.
    private IsolationPolicy(String name) { this.name = name; }



    /**
     * {@inheritDoc}
     */
    public String toString() { return name; }

  }



  // The "assured-sd-level" property definition.
  private static final IntegerPropertyDefinition PD_ASSURED_SD_LEVEL;



  // The "assured-timeout" property definition.
  private static final DurationPropertyDefinition PD_ASSURED_TIMEOUT;



  // The "assured-type" property definition.
  private static final EnumPropertyDefinition<AssuredType> PD_ASSURED_TYPE;



  // The "base-dn" property definition.
  private static final DNPropertyDefinition PD_BASE_DN;



  // The "group-id" property definition.
  private static final IntegerPropertyDefinition PD_GROUP_ID;



  // The "heartbeat-interval" property definition.
  private static final DurationPropertyDefinition PD_HEARTBEAT_INTERVAL;



  // The "isolation-policy" property definition.
  private static final EnumPropertyDefinition<IsolationPolicy> PD_ISOLATION_POLICY;



  // The "referrals-url" property definition.
  private static final StringPropertyDefinition PD_REFERRALS_URL;



  // The "replication-server" property definition.
  private static final StringPropertyDefinition PD_REPLICATION_SERVER;



  // The "server-id" property definition.
  private static final IntegerPropertyDefinition PD_SERVER_ID;



  // The "window-size" property definition.
  private static final IntegerPropertyDefinition PD_WINDOW_SIZE;



  // Build the "assured-sd-level" property definition.
  static {
      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "assured-sd-level");
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "assured-sd-level"));
      DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>("1");
      builder.setDefaultBehaviorProvider(provider);
      builder.setUpperLimit(127);
      builder.setLowerLimit(1);
      PD_ASSURED_SD_LEVEL = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_ASSURED_SD_LEVEL);
  }



  // Build the "assured-timeout" property definition.
  static {
      DurationPropertyDefinition.Builder builder = DurationPropertyDefinition.createBuilder(INSTANCE, "assured-timeout");
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "assured-timeout"));
      DefaultBehaviorProvider<Long> provider = new DefinedDefaultBehaviorProvider<Long>("1000ms");
      builder.setDefaultBehaviorProvider(provider);
      builder.setBaseUnit("ms");
      builder.setLowerLimit("1");
      PD_ASSURED_TIMEOUT = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_ASSURED_TIMEOUT);
  }



  // Build the "assured-type" property definition.
  static {
      EnumPropertyDefinition.Builder<AssuredType> builder = EnumPropertyDefinition.createBuilder(INSTANCE, "assured-type");
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "assured-type"));
      DefaultBehaviorProvider<AssuredType> provider = new DefinedDefaultBehaviorProvider<AssuredType>("not-assured");
      builder.setDefaultBehaviorProvider(provider);
      builder.setEnumClass(AssuredType.class);
      PD_ASSURED_TYPE = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_ASSURED_TYPE);
  }



  // Build the "base-dn" property definition.
  static {
      DNPropertyDefinition.Builder builder = DNPropertyDefinition.createBuilder(INSTANCE, "base-dn");
      builder.setOption(PropertyOption.READ_ONLY);
      builder.setOption(PropertyOption.MANDATORY);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "base-dn"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<DN>());
      PD_BASE_DN = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_BASE_DN);
  }



  // Build the "group-id" property definition.
  static {
      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "group-id");
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "group-id"));
      DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>("1");
      builder.setDefaultBehaviorProvider(provider);
      builder.setUpperLimit(127);
      builder.setLowerLimit(1);
      PD_GROUP_ID = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_GROUP_ID);
  }



  // Build the "heartbeat-interval" property definition.
  static {
      DurationPropertyDefinition.Builder builder = DurationPropertyDefinition.createBuilder(INSTANCE, "heartbeat-interval");
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "heartbeat-interval"));
      DefaultBehaviorProvider<Long> provider = new DefinedDefaultBehaviorProvider<Long>("1000ms");
      builder.setDefaultBehaviorProvider(provider);
      builder.setBaseUnit("ms");
      builder.setLowerLimit("100");
      PD_HEARTBEAT_INTERVAL = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_HEARTBEAT_INTERVAL);
  }



  // Build the "isolation-policy" property definition.
  static {
      EnumPropertyDefinition.Builder<IsolationPolicy> builder = EnumPropertyDefinition.createBuilder(INSTANCE, "isolation-policy");
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "isolation-policy"));
      DefaultBehaviorProvider<IsolationPolicy> provider = new DefinedDefaultBehaviorProvider<IsolationPolicy>("reject-all-updates");
      builder.setDefaultBehaviorProvider(provider);
      builder.setEnumClass(IsolationPolicy.class);
      PD_ISOLATION_POLICY = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_ISOLATION_POLICY);
  }



  // Build the "referrals-url" property definition.
  static {
      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "referrals-url");
      builder.setOption(PropertyOption.MULTI_VALUED);
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "referrals-url"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
      builder.setPattern("^ldap://.+$", "LDAP URL");
      PD_REFERRALS_URL = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_REFERRALS_URL);
  }



  // Build the "replication-server" property definition.
  static {
      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "replication-server");
      builder.setOption(PropertyOption.MULTI_VALUED);
      builder.setOption(PropertyOption.MANDATORY);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "replication-server"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
      builder.setPattern("^.+:[0-9]+$", "HOST:PORT");
      PD_REPLICATION_SERVER = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_REPLICATION_SERVER);
  }



  // Build the "server-id" property definition.
  static {
      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "server-id");
      builder.setOption(PropertyOption.READ_ONLY);
      builder.setOption(PropertyOption.MANDATORY);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "server-id"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<Integer>());
      builder.setUpperLimit(65535);
      builder.setLowerLimit(1);
      PD_SERVER_ID = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_SERVER_ID);
  }



  // Build the "window-size" property definition.
  static {
      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "window-size");
      builder.setOption(PropertyOption.ADVANCED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "window-size"));
      DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>("100");
      builder.setDefaultBehaviorProvider(provider);
      PD_WINDOW_SIZE = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_WINDOW_SIZE);
  }



  // Register the tags associated with this managed object definition.
  static {
    INSTANCE.registerTag(Tag.valueOf("replication"));
  }



  /**
   * Get the Replication Domain configuration definition singleton.
   *
   * @return Returns the Replication Domain configuration definition
   *         singleton.
   */
  public static ReplicationDomainCfgDefn getInstance() {
    return INSTANCE;
  }



  /**
   * Private constructor.
   */
  private ReplicationDomainCfgDefn() {
    super("replication-domain", TopCfgDefn.getInstance());
  }



  /**
   * {@inheritDoc}
   */
  public ReplicationDomainCfgClient createClientConfiguration(
      ManagedObject<? extends ReplicationDomainCfgClient> impl) {
    return new ReplicationDomainCfgClientImpl(impl);
  }



  /**
   * {@inheritDoc}
   */
  public ReplicationDomainCfg createServerConfiguration(
      ServerManagedObject<? extends ReplicationDomainCfg> impl) {
    return new ReplicationDomainCfgServerImpl(impl);
  }



  /**
   * {@inheritDoc}
   */
  public Class<ReplicationDomainCfg> getServerConfigurationClass() {
    return ReplicationDomainCfg.class;
  }



  /**
   * Get the "assured-sd-level" property definition.
   * <p>
   * The level of acknowledgment for Safe Data assured sub mode.
   * <p>
   * When assured mode configured in Safe Data mode, this value
   * defines the number of replication servers that should acknowledge
   * the sent update before the LDAP client call can return.
   *
   * @return Returns the "assured-sd-level" property definition.
   */
  public IntegerPropertyDefinition getAssuredSdLevelPropertyDefinition() {
    return PD_ASSURED_SD_LEVEL;
  }



  /**
   * Get the "assured-timeout" property definition.
   * <p>
   * The timeout value when waiting for assured mode acknowledgements.
   * <p>
   * Defines the amount of milliseconds the server will wait for
   * assured acknowledgements (in either Safe Data or Safe Read assured
   * sub modes) before returning anyway the LDAP client call.
   *
   * @return Returns the "assured-timeout" property definition.
   */
  public DurationPropertyDefinition getAssuredTimeoutPropertyDefinition() {
    return PD_ASSURED_TIMEOUT;
  }



  /**
   * Get the "assured-type" property definition.
   * <p>
   * Defines the assured mode of the replicated domain.
   * <p>
   * The assured mode can be disable or enabled. When enabled, two sub
   * modes are available: Safe Data or Safe Read modes.
   *
   * @return Returns the "assured-type" property definition.
   */
  public EnumPropertyDefinition<AssuredType> getAssuredTypePropertyDefinition() {
    return PD_ASSURED_TYPE;
  }



  /**
   * Get the "base-dn" property definition.
   * <p>
   * Specifies the base DN of the replicated data.
   *
   * @return Returns the "base-dn" property definition.
   */
  public DNPropertyDefinition getBaseDNPropertyDefinition() {
    return PD_BASE_DN;
  }



  /**
   * Get the "group-id" property definition.
   * <p>
   * The group id associated with this replicated domain.
   * <p>
   * This value defines the group id of the replicated domain. The
   * replication system will preferably connect and send updates to
   * replicate to a replication server with the same group id as him.
   *
   * @return Returns the "group-id" property definition.
   */
  public IntegerPropertyDefinition getGroupIdPropertyDefinition() {
    return PD_GROUP_ID;
  }



  /**
   * Get the "heartbeat-interval" property definition.
   * <p>
   * Specifies the heart-beat interval that the Directory Server will
   * use when communicating with Replication Servers.
   * <p>
   * The Directory Server expects a regular heart-beat coming from the
   * Replication Server within the specified interval. If a heartbeat
   * is not received within the interval, the Directory Server closes
   * its connection and connects to another Replication Server.
   *
   * @return Returns the "heartbeat-interval" property definition.
   */
  public DurationPropertyDefinition getHeartbeatIntervalPropertyDefinition() {
    return PD_HEARTBEAT_INTERVAL;
  }



  /**
   * Get the "isolation-policy" property definition.
   * <p>
   * Specifies the behavior of the Directory Server if a write
   * operation is attempted on the data within the Replication Domain
   * when none of the configured Replication Servers are available.
   *
   * @return Returns the "isolation-policy" property definition.
   */
  public EnumPropertyDefinition<IsolationPolicy> getIsolationPolicyPropertyDefinition() {
    return PD_ISOLATION_POLICY;
  }



  /**
   * Get the "referrals-url" property definition.
   * <p>
   * The URLs other LDAP servers should you to refer to us.
   * <p>
   * URLs used by peer servers of the topology to refer to us through
   * LDAP referrals. If this attribute is not defined, every URLs
   * available to access this server will be used. If defined, only
   * URLs specified here will be used.
   *
   * @return Returns the "referrals-url" property definition.
   */
  public StringPropertyDefinition getReferralsUrlPropertyDefinition() {
    return PD_REFERRALS_URL;
  }



  /**
   * Get the "replication-server" property definition.
   * <p>
   * Specifies the addresses of the Replication Servers within the
   * Replication Domain to which the Directory Server should try to
   * connect at startup time.
   * <p>
   * Addresses must be specified using the syntax: hostname:port
   *
   * @return Returns the "replication-server" property definition.
   */
  public StringPropertyDefinition getReplicationServerPropertyDefinition() {
    return PD_REPLICATION_SERVER;
  }



  /**
   * Get the "server-id" property definition.
   * <p>
   * Specifies a unique identifier for the Directory Server within the
   * Replication Domain.
   * <p>
   * Each Directory Server within the same Replication Domain must
   * have a different server ID. A Directory Server which is a member
   * of multiple Replication Domains may use the same server ID for
   * each of its Replication Domain configurations.
   *
   * @return Returns the "server-id" property definition.
   */
  public IntegerPropertyDefinition getServerIdPropertyDefinition() {
    return PD_SERVER_ID;
  }



  /**
   * Get the "window-size" property definition.
   * <p>
   * Specifies the window size that the Directory Server will use when
   * communicating with Replication Servers.
   *
   * @return Returns the "window-size" property definition.
   */
  public IntegerPropertyDefinition getWindowSizePropertyDefinition() {
    return PD_WINDOW_SIZE;
  }



  /**
   * Managed object client implementation.
   */
  private static class ReplicationDomainCfgClientImpl implements
    ReplicationDomainCfgClient {

    // Private implementation.
    private ManagedObject<? extends ReplicationDomainCfgClient> impl;



    // Private constructor.
    private ReplicationDomainCfgClientImpl(
        ManagedObject<? extends ReplicationDomainCfgClient> impl) {
      this.impl = impl;
    }



    /**
     * {@inheritDoc}
     */
    public int getAssuredSdLevel() {
      return impl.getPropertyValue(INSTANCE.getAssuredSdLevelPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setAssuredSdLevel(Integer value) {
      impl.setPropertyValue(INSTANCE.getAssuredSdLevelPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public long getAssuredTimeout() {
      return impl.getPropertyValue(INSTANCE.getAssuredTimeoutPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setAssuredTimeout(Long value) {
      impl.setPropertyValue(INSTANCE.getAssuredTimeoutPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public AssuredType getAssuredType() {
      return impl.getPropertyValue(INSTANCE.getAssuredTypePropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setAssuredType(AssuredType value) {
      impl.setPropertyValue(INSTANCE.getAssuredTypePropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public DN getBaseDN() {
      return impl.getPropertyValue(INSTANCE.getBaseDNPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setBaseDN(DN value) throws PropertyIsReadOnlyException {
      impl.setPropertyValue(INSTANCE.getBaseDNPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public int getGroupId() {
      return impl.getPropertyValue(INSTANCE.getGroupIdPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setGroupId(Integer value) {
      impl.setPropertyValue(INSTANCE.getGroupIdPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public long getHeartbeatInterval() {
      return impl.getPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setHeartbeatInterval(Long value) {
      impl.setPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public IsolationPolicy getIsolationPolicy() {
      return impl.getPropertyValue(INSTANCE.getIsolationPolicyPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setIsolationPolicy(IsolationPolicy value) {
      impl.setPropertyValue(INSTANCE.getIsolationPolicyPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getReferralsUrl() {
      return impl.getPropertyValues(INSTANCE.getReferralsUrlPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setReferralsUrl(Collection<String> values) {
      impl.setPropertyValues(INSTANCE.getReferralsUrlPropertyDefinition(), values);
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getReplicationServer() {
      return impl.getPropertyValues(INSTANCE.getReplicationServerPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setReplicationServer(Collection<String> values) {
      impl.setPropertyValues(INSTANCE.getReplicationServerPropertyDefinition(), values);
    }



    /**
     * {@inheritDoc}
     */
    public Integer getServerId() {
      return impl.getPropertyValue(INSTANCE.getServerIdPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setServerId(int value) throws PropertyIsReadOnlyException {
      impl.setPropertyValue(INSTANCE.getServerIdPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public int getWindowSize() {
      return impl.getPropertyValue(INSTANCE.getWindowSizePropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setWindowSize(Integer value) {
      impl.setPropertyValue(INSTANCE.getWindowSizePropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public ManagedObjectDefinition<? extends ReplicationDomainCfgClient, ? extends ReplicationDomainCfg> definition() {
      return INSTANCE;
    }



    /**
     * {@inheritDoc}
     */
    public PropertyProvider properties() {
      return impl;
    }



    /**
     * {@inheritDoc}
     */
    public void commit() throws ManagedObjectAlreadyExistsException,
        MissingMandatoryPropertiesException, ConcurrentModificationException,
        OperationRejectedException, AuthorizationException,
        CommunicationException {
      impl.commit();
    }

  }



  /**
   * Managed object server implementation.
   */
  private static class ReplicationDomainCfgServerImpl implements
    ReplicationDomainCfg {

    // Private implementation.
    private ServerManagedObject<? extends ReplicationDomainCfg> impl;

    // The value of the "assured-sd-level" property.
    private final int pAssuredSdLevel;

    // The value of the "assured-timeout" property.
    private final long pAssuredTimeout;

    // The value of the "assured-type" property.
    private final AssuredType pAssuredType;

    // The value of the "base-dn" property.
    private final DN pBaseDN;

    // The value of the "group-id" property.
    private final int pGroupId;

    // The value of the "heartbeat-interval" property.
    private final long pHeartbeatInterval;

    // The value of the "isolation-policy" property.
    private final IsolationPolicy pIsolationPolicy;

    // The value of the "referrals-url" property.
    private final SortedSet<String> pReferralsUrl;

    // The value of the "replication-server" property.
    private final SortedSet<String> pReplicationServer;

    // The value of the "server-id" property.
    private final int pServerId;

    // The value of the "window-size" property.
    private final int pWindowSize;



    // Private constructor.
    private ReplicationDomainCfgServerImpl(ServerManagedObject<? extends ReplicationDomainCfg> impl) {
      this.impl = impl;
      this.pAssuredSdLevel = impl.getPropertyValue(INSTANCE.getAssuredSdLevelPropertyDefinition());
      this.pAssuredTimeout = impl.getPropertyValue(INSTANCE.getAssuredTimeoutPropertyDefinition());
      this.pAssuredType = impl.getPropertyValue(INSTANCE.getAssuredTypePropertyDefinition());
      this.pBaseDN = impl.getPropertyValue(INSTANCE.getBaseDNPropertyDefinition());
      this.pGroupId = impl.getPropertyValue(INSTANCE.getGroupIdPropertyDefinition());
      this.pHeartbeatInterval = impl.getPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition());
      this.pIsolationPolicy = impl.getPropertyValue(INSTANCE.getIsolationPolicyPropertyDefinition());
      this.pReferralsUrl = impl.getPropertyValues(INSTANCE.getReferralsUrlPropertyDefinition());
      this.pReplicationServer = impl.getPropertyValues(INSTANCE.getReplicationServerPropertyDefinition());
      this.pServerId = impl.getPropertyValue(INSTANCE.getServerIdPropertyDefinition());
      this.pWindowSize = impl.getPropertyValue(INSTANCE.getWindowSizePropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void addChangeListener(
        ConfigurationChangeListener<ReplicationDomainCfg> listener) {
      impl.registerChangeListener(listener);
    }



    /**
     * {@inheritDoc}
     */
    public void removeChangeListener(
        ConfigurationChangeListener<ReplicationDomainCfg> listener) {
      impl.deregisterChangeListener(listener);
    }



    /**
     * {@inheritDoc}
     */
    public int getAssuredSdLevel() {
      return pAssuredSdLevel;
    }



    /**
     * {@inheritDoc}
     */
    public long getAssuredTimeout() {
      return pAssuredTimeout;
    }



    /**
     * {@inheritDoc}
     */
    public AssuredType getAssuredType() {
      return pAssuredType;
    }



    /**
     * {@inheritDoc}
     */
    public DN getBaseDN() {
      return pBaseDN;
    }



    /**
     * {@inheritDoc}
     */
    public int getGroupId() {
      return pGroupId;
    }



    /**
     * {@inheritDoc}
     */
    public long getHeartbeatInterval() {
      return pHeartbeatInterval;
    }



    /**
     * {@inheritDoc}
     */
    public IsolationPolicy getIsolationPolicy() {
      return pIsolationPolicy;
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getReferralsUrl() {
      return pReferralsUrl;
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getReplicationServer() {
      return pReplicationServer;
    }



    /**
     * {@inheritDoc}
     */
    public int getServerId() {
      return pServerId;
    }



    /**
     * {@inheritDoc}
     */
    public int getWindowSize() {
      return pWindowSize;
    }



    /**
     * {@inheritDoc}
     */
    public Class<? extends ReplicationDomainCfg> configurationClass() {
      return ReplicationDomainCfg.class;
    }



    /**
     * {@inheritDoc}
     */
    public DN dn() {
      return impl.getDN();
    }

  }
}
