mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
19.31.2007 38afdba5a37f3a89ca59c8dca9376919fbb41ce5
opendj-sdk/opends/src/messages/messages/dsconfig.properties
@@ -101,7 +101,7 @@
 retrieved because another client is currently making conflicting \
 configuration changes
SEVERE_ERR_DSCFG_ERROR_CREATE_MMPE_1032=The %s could not be created because \
 the following mandatory properties must be defined: %s
 the following mandatory properties must be defined:
SEVERE_ERR_DSCFG_ERROR_CREATE_MOAEE_1033=The %s could not be created because \
 there is already an existing one with the same name
SEVERE_ERR_DSCFG_ERROR_CREATE_AUTHZ_1034=The %s could not be created because \
@@ -424,3 +424,18 @@
INFO_EDITOR_PROMPT_SELECT_COMPONENTS_REMOVE_132=Select the %s you wish to remove:
INFO_EDITOR_OPTION_CHANGE_TO_DEFAULT_COMPONENT_133=Change it to the default %s: %s
INFO_EDITOR_OPTION_CHANGE_TO_COMPONENT_134=Change it to the %s: %s
INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT_135=The referenced %s \
 called "%s" must be enabled so that it can be used with this %s. Do \
 you want to enabled it?
SEVERE_ERR_SET_REFERENCED_COMPONENT_DISABLED_136=The modifications to \
 the %s cannot be made because it contains a reference to a \
 disabled %s
SEVERE_ERR_CREATE_REFERENCED_COMPONENT_DISABLED_137=The %s cannot be created \
 because it contains a reference to a disabled %s
SEVERE_ERR_CREATE_HEADING_MMPE_SINGLE_138=The %s could not be created because the following mandatory property was not defined:
SEVERE_ERR_CREATE_HEADING_MMPE_PLURAL_139=The %s could not be created because the following mandatory properties were not defined:
SEVERE_ERR_MODIFY_HEADING_MMPE_SINGLE_140=The %s could not be modified because the following mandatory property was not defined:
SEVERE_ERR_MODIFY_HEADING_MMPE_PLURAL_141=The %s could not be modified because the following mandatory properties were not defined:
INFO_DSCFG_PROMPT_EDIT_142=Would you like to edit the properties of the %s in order to resolve this problem?
SEVERE_ERR_GET_HEADING_MODE_SINGLE_143=The %s could not be decoded due to the following reason:
SEVERE_ERR_GET_HEADING_MODE_PLURAL_144=The %s could not be decoded due to the following reasons:
opendj-sdk/opends/src/server/org/opends/server/admin/client/MissingMandatoryPropertiesException.java
@@ -86,21 +86,37 @@
  // The causes of this exception.
  private final Collection<PropertyIsMandatoryException> causes;
  // Indicates whether the exception occurred during managed object
  // creation.
  private final boolean isCreate;
  // The user friendly name of the component that caused this
  // exception.
  private final Message ufn;
  /**
   * Creates a new missing mandatory properties exception with the
   * provided causes.
   *
   * @param ufn
   *          The user friendly name of the component that caused this
   *          exception.
   * @param causes
   *          The causes of this exception (must be non-<code>null</code>
   *          and non-empty).
   * @param isCreate
   *          Indicates whether the exception occurred during managed
   *          object creation.
   */
  public MissingMandatoryPropertiesException(
      Collection<PropertyIsMandatoryException> causes) {
  public MissingMandatoryPropertiesException(Message ufn,
      Collection<PropertyIsMandatoryException> causes, boolean isCreate) {
    super(createMessage(causes));
    this.causes = new ArrayList<PropertyIsMandatoryException>(causes);
    this.ufn = ufn;
    this.isCreate = isCreate;
  }
@@ -128,4 +144,30 @@
    return Collections.unmodifiableCollection(causes);
  }
  /**
   * Gets the user friendly name of the component that caused this
   * exception.
   *
   * @return Returns the user friendly name of the component that
   *         caused this exception.
   */
  public Message getUserFriendlyName() {
    return ufn;
  }
  /**
   * Indicates whether or not this exception was thrown during managed
   * object creation or during modification.
   *
   * @return Returns <code>true</code> if this exception was thrown
   *         during managed object creation.
   */
  public boolean isCreate() {
    return isCreate;
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java
@@ -57,6 +57,26 @@
public class OperationRejectedException extends AdminClientException {
  /**
   * The type of operation that caused this exception.
   */
  public enum OperationType {
    /**
     * A managed object could not be created.
     */
    CREATE,
    /**
     * A managed object could not be deleted.
     */
    DELETE,
    /**
     * A managed object could not be modified.
     */
    MODIFY;
  }
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 8547688890613079044L;
@@ -102,14 +122,27 @@
  // The messages describing the constraint violations that occurred.
  private final Collection<Message> messages;
  // The type of operation that caused this exception.
  private final OperationType type;
  // The user friendly name of the component that caused this
  // exception.
  private final Message ufn;
  /**
   * Creates a new operation rejected exception with a default
   * message.
   *
   * @param type
   *          The type of operation that caused this exception.
   * @param ufn
   *          The user friendly name of the component that caused this
   *          exception.
   */
  public OperationRejectedException() {
    this(ERR_OPERATION_REJECTED_DEFAULT.get());
  public OperationRejectedException(OperationType type, Message ufn) {
    this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get());
  }
@@ -118,15 +151,23 @@
   * Creates a new operation rejected exception with the provided
   * messages.
   *
   * @param type
   *          The type of operation that caused this exception.
   * @param ufn
   *          The user friendly name of the component that caused this
   *          exception.
   * @param messages
   *          The messages describing the constraint violations that
   *          occurred (must be non-<code>null</code> and
   *          non-empty).
   */
  public OperationRejectedException(Collection<Message> messages) {
  public OperationRejectedException(OperationType type, Message ufn,
      Collection<Message> messages) {
    super(getDefaultMessage(messages));
    this.messages = new ArrayList<Message>(messages);
    this.type = type;
    this.ufn = ufn;
  }
@@ -135,12 +176,18 @@
   * Creates a new operation rejected exception with the provided
   * message.
   *
   * @param type
   *          The type of operation that caused this exception.
   * @param ufn
   *          The user friendly name of the component that caused this
   *          exception.
   * @param message
   *          The message describing the constraint violation that
   *          occurred.
   */
  public OperationRejectedException(Message message) {
    this(Collections.singleton(message));
  public OperationRejectedException(OperationType type, Message ufn,
      Message message) {
    this(type, ufn, Collections.singleton(message));
  }
@@ -169,4 +216,28 @@
    return getSingleMessage(messages);
  }
  /**
   * Gets the type of operation that caused this exception.
   *
   * @return Returns the type of operation that caused this exception.
   */
  public OperationType getOperationType() {
    return type;
  }
  /**
   * Gets the user friendly name of the component that caused this
   * exception.
   *
   * @return Returns the user friendly name of the component that
   *         caused this exception.
   */
  public Message getUserFriendlyName() {
    return ufn;
  }
}
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -76,6 +76,7 @@
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.client.OperationRejectedException.OperationType;
import org.opends.server.admin.client.spi.Driver;
import org.opends.server.admin.client.spi.PropertySet;
import org.opends.server.admin.std.client.RootCfgClient;
@@ -422,11 +423,15 @@
      connection.deleteSubtree(dn);
    } catch (OperationNotSupportedException e) {
      // Unwilling to perform.
      AbstractManagedObjectDefinition<?, ?> d =
        path.getManagedObjectDefinition();
      if (e.getMessage() == null) {
        throw new OperationRejectedException();
        throw new OperationRejectedException(OperationType.DELETE, d
            .getUserFriendlyName());
      } else {
        Message m = Message.raw("%s", e.getMessage());
        throw new OperationRejectedException(m);
        throw new OperationRejectedException(OperationType.DELETE, d
            .getUserFriendlyName(), m);
      }
    } catch (NamingException e) {
      adaptNamingException(e);
opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -60,6 +60,7 @@
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.client.OperationRejectedException.OperationType;
import org.opends.server.admin.client.spi.AbstractManagedObject;
import org.opends.server.admin.client.spi.Driver;
import org.opends.server.admin.client.spi.Property;
@@ -160,6 +161,7 @@
      CommunicationException, OperationRejectedException,
      ConcurrentModificationException, ManagedObjectAlreadyExistsException {
    // First make sure that the parent managed object still exists.
    ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition();
    ManagedObjectPath<?, ?> path = getManagedObjectPath();
    ManagedObjectPath<?, ?> parent = path.parent();
@@ -181,8 +183,7 @@
      // TODO: this implementation does not handle relations which
      // comprise of more than one RDN arc (this will probably never
      // be required anyway).
      LdapName dn = LDAPNameBuilder
          .create(parent, ir, driver.getLDAPProfile());
      LdapName dn = LDAPNameBuilder.create(parent, ir, driver.getLDAPProfile());
      if (!driver.entryExists(dn)) {
        // We need to create the entry.
        Attributes attributes = new BasicAttributes();
@@ -205,10 +206,12 @@
        } catch (OperationNotSupportedException e) {
          // Unwilling to perform.
          if (e.getMessage() == null) {
            throw new OperationRejectedException();
            throw new OperationRejectedException(OperationType.CREATE, d
                .getUserFriendlyName());
          } else {
            Message m = Message.raw("%s", e.getMessage());
            throw new OperationRejectedException(m);
            throw new OperationRejectedException(OperationType.CREATE, d
                .getUserFriendlyName(), m);
          }
        } catch (NamingException e) {
          driver.adaptNamingException(e);
@@ -254,10 +257,12 @@
    } catch (OperationNotSupportedException e) {
      // Unwilling to perform.
      if (e.getMessage() == null) {
        throw new OperationRejectedException();
        throw new OperationRejectedException(OperationType.CREATE, d
            .getUserFriendlyName());
      } else {
        Message m = Message.raw("%s", e.getMessage());
        throw new OperationRejectedException(m);
        throw new OperationRejectedException(OperationType.CREATE, d
            .getUserFriendlyName(), m);
      }
    } catch (NamingException e) {
      driver.adaptNamingException(e);
@@ -285,12 +290,11 @@
      AuthorizationException, CommunicationException {
    // Build the list of modified attributes.
    Attributes mods = new BasicAttributes();
    ManagedObjectDefinition<?, ?> definition = getManagedObjectDefinition();
    for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) {
    ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition();
    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
      Property<?> p = getProperty(pd);
      if (p.isModified()) {
        String attrID = driver.getLDAPProfile().getAttributeName(definition,
            pd);
        String attrID = driver.getLDAPProfile().getAttributeName(d, pd);
        Attribute attribute = new BasicAttribute(attrID);
        encodeProperty(attribute, pd);
        mods.put(attribute);
@@ -308,10 +312,12 @@
      } catch (OperationNotSupportedException e) {
        // Unwilling to perform.
        if (e.getMessage() == null) {
          throw new OperationRejectedException();
          throw new OperationRejectedException(OperationType.MODIFY, d
              .getUserFriendlyName());
        } else {
          Message m = Message.raw("%s", e.getMessage());
          throw new OperationRejectedException(m);
          throw new OperationRejectedException(OperationType.MODIFY, d
              .getUserFriendlyName(), m);
        }
      } catch (NamingException e) {
        // Just treat it as a communication problem.
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/AbstractManagedObject.java
@@ -68,6 +68,7 @@
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.client.OperationRejectedException.OperationType;
@@ -151,7 +152,8 @@
    }
    if (!exceptions.isEmpty()) {
      throw new MissingMandatoryPropertiesException(exceptions);
      throw new MissingMandatoryPropertiesException(definition
          .getUserFriendlyName(), exceptions, !existsOnServer);
    }
    // Now enforce any constraints.
@@ -175,7 +177,13 @@
    }
    if (!isAcceptable) {
      throw new OperationRejectedException(messages);
      if (existsOnServer) {
        throw new OperationRejectedException(OperationType.MODIFY, definition
            .getUserFriendlyName(), messages);
      } else {
        throw new OperationRejectedException(OperationType.CREATE, definition
            .getUserFriendlyName(), messages);
      }
    }
    // Commit the managed object.
opendj-sdk/opends/src/server/org/opends/server/admin/client/spi/Driver.java
@@ -69,6 +69,7 @@
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.client.OperationRejectedException.OperationType;
import org.opends.server.admin.std.client.RootCfgClient;
@@ -783,7 +784,8 @@
    }
    if (!isAcceptable) {
      throw new OperationRejectedException(messages);
      throw new OperationRejectedException(OperationType.DELETE, d
          .getUserFriendlyName(), messages);
    }
    deleteManagedObject(path);
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java
@@ -44,10 +44,15 @@
import org.opends.server.admin.PropertyIsSingleValuedException;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.client.IllegalManagedObjectNameException;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.util.args.Argument;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.cli.CLIException;
import org.opends.server.util.cli.ConsoleApplication;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
@@ -103,35 +108,6 @@
  /**
   * Creates an argument exception from a missing mandatory properties
   * exception.
   *
   * @param e
   *          The missing mandatory properties exception.
   * @param d
   *          The managed object definition.
   * @return Returns an argument exception.
   */
  public static ArgumentException adaptMissingMandatoryPropertiesException(
      MissingMandatoryPropertiesException e,
      AbstractManagedObjectDefinition<?, ?> d) {
    StringBuilder builder = new StringBuilder();
    boolean isFirst = true;
    for (PropertyIsMandatoryException pe : e.getCauses()) {
      if (!isFirst) {
        builder.append(", ");
      }
      builder.append(pe.getPropertyDefinition().getName());
      isFirst = false;
    }
    Message msg = ERR_DSCFG_ERROR_CREATE_MMPE.get(
            d.getUserFriendlyName(), builder.toString());
    return new ArgumentException(msg);
  }
  /**
   * Creates an argument exception from a property exception.
   *
   * @param e
@@ -172,6 +148,150 @@
  /**
   * Displays a table listing reasons why a managed object could not
   * be decoded successfully.
   *
   * @param app
   *          The console application.
   * @param e
   *          The managed object decoding exception.
   */
  public static void displayManagedObjectDecodingException(
      ConsoleApplication app, ManagedObjectDecodingException e) {
    AbstractManagedObjectDefinition<?, ?> d = e.getPartialManagedObject()
        .getManagedObjectDefinition();
    Message ufn = d.getUserFriendlyName();
    Message msg;
    if (e.getCauses().size() == 1) {
      msg = ERR_GET_HEADING_MODE_SINGLE.get(ufn);
    } else {
      msg = ERR_GET_HEADING_MODE_PLURAL.get(ufn);
    }
    app.println(msg);
    app.println();
    TableBuilder builder = new TableBuilder();
    for (PropertyException pe : e.getCauses()) {
      ArgumentException ae = adaptPropertyException(pe, d);
      builder.startRow();
      builder.appendCell("*");
      builder.appendCell(ae.getMessage());
    }
    TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
    printer.setDisplayHeadings(false);
    printer.setColumnWidth(1, 0);
    printer.setIndentWidth(4);
    builder.print(printer);
  }
  /**
   * Displays a table listing missing mandatory properties.
   *
   * @param app
   *          The console application.
   * @param e
   *          The missing mandatory property exception.
   */
  public static void displayMissingMandatoryPropertyException(
      ConsoleApplication app, MissingMandatoryPropertiesException e) {
    Message ufn = e.getUserFriendlyName();
    Message msg;
    if (e.isCreate()) {
      if (e.getCauses().size() == 1) {
        msg = ERR_CREATE_HEADING_MMPE_SINGLE.get(ufn);
      } else {
        msg = ERR_CREATE_HEADING_MMPE_PLURAL.get(ufn);
      }
    } else {
      if (e.getCauses().size() == 1) {
        msg = ERR_MODIFY_HEADING_MMPE_SINGLE.get(ufn);
      } else {
        msg = ERR_MODIFY_HEADING_MMPE_PLURAL.get(ufn);
      }
    }
    app.println(msg);
    app.println();
    TableBuilder builder = new TableBuilder();
    builder.addSortKey(0);
    builder.appendHeading(INFO_DSCFG_HEADING_PROPERTY_NAME.get());
    builder.appendHeading(INFO_DSCFG_HEADING_PROPERTY_SYNTAX.get());
    PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder(true);
    for (PropertyIsMandatoryException pe : e.getCauses()) {
      PropertyDefinition<?> pd = pe.getPropertyDefinition();
      builder.startRow();
      builder.appendCell(pd.getName());
      builder.appendCell(b.getUsage(pd));
    }
    TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
    printer.setDisplayHeadings(true);
    printer.setColumnWidth(1, 0);
    printer.setIndentWidth(4);
    builder.print(printer);
  }
  /**
   * Displays a table listing the reasons why an operation was
   * rejected.
   *
   * @param app
   *          The console application.
   * @param e
   *          The operation rejected exception.
   */
  public static void displayOperationRejectedException(ConsoleApplication app,
      OperationRejectedException e) {
    Message ufn = e.getUserFriendlyName();
    Message msg;
    switch (e.getOperationType()) {
    case CREATE:
      if (e.getMessages().size() == 1) {
        msg = ERR_DSCFG_ERROR_CREATE_ORE_SINGLE.get(ufn);
      } else {
        msg = ERR_DSCFG_ERROR_CREATE_ORE_PLURAL.get(ufn);
      }
      break;
    case DELETE:
      if (e.getMessages().size() == 1) {
        msg = ERR_DSCFG_ERROR_DELETE_ORE_SINGLE.get(ufn);
      } else {
        msg = ERR_DSCFG_ERROR_DELETE_ORE_PLURAL.get(ufn);
      }
      break;
    default:
      if (e.getMessages().size() == 1) {
        msg = ERR_DSCFG_ERROR_MODIFY_ORE_SINGLE.get(ufn);
      } else {
        msg = ERR_DSCFG_ERROR_MODIFY_ORE_PLURAL.get(ufn);
      }
      break;
    }
    app.println(msg);
    app.println();
    TableBuilder builder = new TableBuilder();
    for (Message reason : e.getMessages()) {
      builder.startRow();
      builder.appendCell("*");
      builder.appendCell(reason);
    }
    TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
    printer.setDisplayHeadings(false);
    printer.setColumnWidth(1, 0);
    printer.setIndentWidth(4);
    builder.print(printer);
  }
  /**
   * Creates an argument exception which should be used when a
   * property modification argument is incompatible with a previous
   * modification argument.
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
@@ -29,6 +29,7 @@
import static org.opends.messages.DSConfigMessages.*;
import static org.opends.server.tools.dsconfig.ArgumentExceptionFactory.*;
import java.util.Collection;
import java.util.Collections;
@@ -44,6 +45,8 @@
import org.opends.messages.Message;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.BooleanPropertyDefinition;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.DefaultBehaviorException;
@@ -355,6 +358,285 @@
    return new CreateSubCommandHandler<C, S>(parser, p, r, null, p.child(r));
  }
  /**
   * Create the provided managed object.
   *
   * @param app
   *          The console application.
   * @param context
   *          The management context.
   * @param mo
   *          The managed object to be created.
   * @return Returns a MenuResult.success() if the managed object was
   *         created successfully, or MenuResult.quit(), or
   *         MenuResult.cancel(), if the managed object was edited
   *         interactively and the user chose to quit or cancel.
   * @throws ClientException
   *           If an unrecoverable client exception occurred whilst
   *           interacting with the server.
   * @throws CLIException
   *           If an error occurred whilst interacting with the
   *           console.
   */
  public static MenuResult<Void> createManagedObject(ConsoleApplication app,
      ManagementContext context, ManagedObject<?> mo) throws ClientException,
      CLIException {
    ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition();
    Message ufn = d.getUserFriendlyName();
    while (true) {
      // Interactively set properties if applicable.
      if (app.isInteractive()) {
        SortedSet<PropertyDefinition<?>> properties =
          new TreeSet<PropertyDefinition<?>>();
        for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
          if (pd.hasOption(PropertyOption.HIDDEN)) {
            continue;
          }
          if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
            continue;
          }
          properties.add(pd);
        }
        PropertyValueEditor editor = new PropertyValueEditor(app, context);
        MenuResult<Void> result = editor.edit(mo, properties, false);
        // Interactively enable/edit referenced components.
        if (result.isSuccess()) {
          result = checkReferences(app, context, mo);
          if (result.isAgain()) {
            // Edit again.
            continue;
          }
        }
        if (result.isQuit()) {
          if (!app.isMenuDrivenMode()) {
            // User chose to cancel any changes.
            Message msg = INFO_DSCFG_CONFIRM_CREATE_FAIL.get(ufn);
            app.printVerboseMessage(msg);
          }
          return MenuResult.quit();
        } else if (result.isCancel()) {
          return MenuResult.cancel();
        }
      }
      try {
        // Create the managed object.
        mo.commit();
        // Output success message.
        app.println();
        Message msg = INFO_DSCFG_CONFIRM_CREATE_SUCCESS.get(ufn);
        app.printVerboseMessage(msg);
        return MenuResult.success();
      } catch (MissingMandatoryPropertiesException e) {
        if (app.isInteractive()) {
          // If interactive, give the user the chance to fix the
          // problems.
          app.println();
          displayMissingMandatoryPropertyException(app, e);
          app.println();
          if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
            return MenuResult.cancel();
          }
        } else {
          throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e
              .getMessageObject(), e);
        }
      } catch (AuthorizationException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
        throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
            msg);
      } catch (ConcurrentModificationException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn);
        throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg);
      } catch (OperationRejectedException e) {
        if (app.isInteractive()) {
          // If interactive, give the user the chance to fix the
          // problems.
          app.println();
          displayOperationRejectedException(app, e);
          app.println();
          if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
            return MenuResult.cancel();
          }
        } else {
          throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e
              .getMessageObject(), e);
        }
      } catch (CommunicationException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage());
        throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
      } catch (ManagedObjectAlreadyExistsException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_MOAEE.get(ufn);
        throw new ClientException(LDAPResultCode.ENTRY_ALREADY_EXISTS, msg);
      }
    }
  }
  // Check that any referenced components are enabled if
  // required.
  private static MenuResult<Void> checkReferences(ConsoleApplication app,
      ManagementContext context, ManagedObject<?> mo) throws ClientException,
      CLIException {
    ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition();
    Message ufn = d.getUserFriendlyName();
    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
      if (pd instanceof AggregationPropertyDefinition) {
        AggregationPropertyDefinition<?, ?> apd =
          (AggregationPropertyDefinition<?, ?>) pd;
        // Skip this aggregation if it doesn't have an enable
        // property.
        BooleanPropertyDefinition tpd = apd
            .getTargetEnabledPropertyDefinition();
        if (tpd == null) {
          continue;
        }
        // Skip this aggregation if this managed object's enable
        // properties are not all true.
        boolean needsEnabling = true;
        for (BooleanPropertyDefinition bpd : apd
            .getSourceEnabledPropertyDefinitions()) {
          if (!mo.getPropertyValue(bpd)) {
            needsEnabling = false;
            break;
          }
        }
        if (!needsEnabling) {
          continue;
        }
        // The referenced component(s) must be enabled.
        for (String name : mo.getPropertyValues(apd)) {
          ManagedObjectPath<?, ?> path = apd.getChildPath(name);
          Message rufn = path.getManagedObjectDefinition()
              .getUserFriendlyName();
          ManagedObject<?> ref;
          try {
            ref = context.getManagedObject(path);
          } catch (AuthorizationException e) {
            Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
            throw new ClientException(
                LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
          } catch (DefinitionDecodingException e) {
            Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn);
            throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
          } catch (ManagedObjectDecodingException e) {
            // FIXME: should not abort here. Instead, display the
            // errors (if verbose) and apply the changes to the
            // partial managed object.
            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn);
            throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg, e);
          } catch (CommunicationException e) {
            Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage());
            throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
          } catch (ManagedObjectNotFoundException e) {
            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn);
            throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg);
          }
          while (!ref.getPropertyValue(tpd)) {
            boolean isBadReference = true;
            app.println();
            if (app.confirmAction(
                INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn, name,
                    ufn), true)) {
              ref.setPropertyValue(tpd, true);
              try {
                ref.commit();
                isBadReference = false;
              } catch (MissingMandatoryPropertiesException e) {
                // Give the user the chance to fix the problems.
                app.println();
                displayMissingMandatoryPropertyException(app, e);
                app.println();
                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
                  // FIXME: edit the properties of the referenced
                  // object.
                  MenuResult<Void> result = SetPropSubCommandHandler
                      .modifyManagedObject(app, context, ref);
                  if (result.isQuit()) {
                    return result;
                  } else if (result.isSuccess()) {
                    // The referenced component was modified
                    // successfully, but may still be disabled.
                    isBadReference = false;
                  }
                }
              } catch (AuthorizationException e) {
                Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
                throw new ClientException(
                    LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
              } catch (ConcurrentModificationException e) {
                Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn);
                throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
                    msg);
              } catch (OperationRejectedException e) {
                // Give the user the chance to fix the problems.
                app.println();
                displayOperationRejectedException(app, e);
                app.println();
                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
                  MenuResult<Void> result = SetPropSubCommandHandler
                      .modifyManagedObject(app, context, ref);
                  if (result.isQuit()) {
                    return result;
                  } else if (result.isSuccess()) {
                    // The referenced component was modified
                    // successfully, but may still be disabled.
                    isBadReference = false;
                  }
                }
              } catch (CommunicationException e) {
                Message msg = ERR_DSCFG_ERROR_CREATE_CE
                    .get(ufn, e.getMessage());
                throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
              } catch (ManagedObjectAlreadyExistsException e) {
                // Should never happen.
                throw new IllegalStateException(e);
              }
            }
            // If the referenced component is still disabled because
            // the user refused to modify it, then give the used the
            // option of editing the referencing component.
            if (isBadReference) {
              app.println();
              app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED.get(ufn, rufn));
              app.println();
              if (app
                  .confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
                return MenuResult.again();
              } else {
                return MenuResult.cancel();
              }
            }
            // If the referenced component is now enabled, then drop out.
            if (ref.getPropertyValue(tpd)) {
              break;
            }
          }
        }
      }
    }
    return MenuResult.success();
  }
  // The sub-commands naming arguments.
  private final List<StringArgument> namingArgs;
@@ -642,94 +924,16 @@
      setProperty(child, provider, pd);
    }
    while (true) {
      // Interactively set properties if applicable.
      if (app.isInteractive()) {
        SortedSet<PropertyDefinition<?>> properties =
          new TreeSet<PropertyDefinition<?>>();
        for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
          if (pd.hasOption(PropertyOption.HIDDEN)) {
            continue;
          }
          if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
            continue;
          }
          properties.add(pd);
        }
        PropertyValueEditor editor = new PropertyValueEditor(app, context);
        MenuResult<Void> result2 = editor.edit(child, properties, true);
        if (result2.isQuit()) {
          if (!app.isMenuDrivenMode()) {
            Message msg = INFO_DSCFG_CONFIRM_CREATE_FAIL.get(ufn);
            app.printVerboseMessage(msg);
          }
          return MenuResult.quit();
        } else if (result2.isCancel()) {
          return MenuResult.cancel();
        }
      }
      try {
        // Create the managed object.
        child.commit();
        // Output success message.
        Message msg = INFO_DSCFG_CONFIRM_CREATE_SUCCESS.get(ufn);
        app.printVerboseMessage(msg);
        return MenuResult.success(0);
      } catch (MissingMandatoryPropertiesException e) {
        throw ArgumentExceptionFactory.adaptMissingMandatoryPropertiesException(
            e, d);
      } catch (AuthorizationException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_AUTHZ.get(ufn);
        throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
            msg);
      } catch (ManagedObjectAlreadyExistsException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_MOAEE.get(ufn);
        throw new ClientException(LDAPResultCode.ENTRY_ALREADY_EXISTS, msg);
      } catch (ConcurrentModificationException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_CME.get(ufn);
        throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg);
      } catch (OperationRejectedException e) {
        Message msg;
        if (e.getMessages().size() == 1) {
          msg = ERR_DSCFG_ERROR_CREATE_ORE_SINGLE.get(ufn);
        } else {
          msg = ERR_DSCFG_ERROR_CREATE_ORE_PLURAL.get(ufn);
        }
        if (app.isInteractive()) {
          // If interactive, give the user the chance to fix the problems.
          app.println();
          app.println(msg);
          app.println();
          TableBuilder builder = new TableBuilder();
          for (Message reason : e.getMessages()) {
            builder.startRow();
            builder.appendCell("*");
            builder.appendCell(reason);
          }
          TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
          printer.setDisplayHeadings(false);
          printer.setColumnWidth(1, 0);
          printer.setIndentWidth(4);
          builder.print(printer);
          app.println();
          if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
            return MenuResult.cancel();
          }
        } else {
          throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
              msg, e);
        }
      } catch (CommunicationException e) {
        Message msg = ERR_DSCFG_ERROR_CREATE_CE.get(ufn, e.getMessage());
        throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN, msg);
      }
    // Now the command line changes have been made, create the managed
    // object interacting with the user to fix any problems if
    // required.
    MenuResult<Void> result2 = createManagedObject(app, context, child);
    if (result2.isCancel()) {
      return MenuResult.cancel();
    } else if (result2.isQuit()) {
      return MenuResult.quit();
    } else {
      return MenuResult.success(0);
    }
  }
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -32,6 +32,7 @@
import static org.opends.messages.ToolMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.tools.ToolConstants.*;
import static org.opends.server.tools.dsconfig.ArgumentExceptionFactory.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.InputStream;
@@ -45,15 +46,14 @@
import java.util.TreeSet;
import org.opends.messages.Message;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.AttributeTypePropertyDefinition;
import org.opends.server.admin.ClassLoaderProvider;
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.Tag;
import org.opends.server.admin.client.ManagedObjectDecodingException;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.tools.ClientException;
@@ -72,8 +72,6 @@
import org.opends.server.util.cli.MenuCallback;
import org.opends.server.util.cli.MenuResult;
import org.opends.server.util.cli.OutputStreamConsoleApplication;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
@@ -826,50 +824,27 @@
      println(e.getMessageObject());
      return 1;
    } catch (ClientException e) {
      // If the client exception was caused by a decoding exception
      // then we should display the causes.
      println(e.getMessageObject());
      Throwable cause = e.getCause();
      if (cause instanceof ManagedObjectDecodingException) {
        ManagedObjectDecodingException de =
          (ManagedObjectDecodingException) cause;
        println();
        TableBuilder builder = new TableBuilder();
        for (PropertyException pe : de.getCauses()) {
          AbstractManagedObjectDefinition<?, ?> d = de
              .getPartialManagedObject().getManagedObjectDefinition();
          ArgumentException ae = ArgumentExceptionFactory
              .adaptPropertyException(pe, d);
          builder.startRow();
          builder.appendCell("*");
          builder.appendCell(ae.getMessage());
        }
        TextTablePrinter printer = new TextTablePrinter(getErrorStream());
        printer.setDisplayHeadings(false);
        printer.setColumnWidth(1, 0);
        printer.setIndentWidth(4);
        builder.print(printer);
        displayManagedObjectDecodingException(this, de);
        println();
      } else if (cause instanceof MissingMandatoryPropertiesException) {
        MissingMandatoryPropertiesException mmpe =
          (MissingMandatoryPropertiesException) cause;
        println();
        displayMissingMandatoryPropertyException(this, mmpe);
        println();
      } else if (cause instanceof OperationRejectedException) {
        OperationRejectedException ore = (OperationRejectedException) cause;
        println();
        TableBuilder builder = new TableBuilder();
        for (Message reason : ore.getMessages()) {
          builder.startRow();
          builder.appendCell("*");
          builder.appendCell(reason);
        }
        TextTablePrinter printer = new TextTablePrinter(getErrorStream());
        printer.setDisplayHeadings(false);
        printer.setColumnWidth(1, 0);
        printer.setIndentWidth(4);
        builder.print(printer);
        displayOperationRejectedException(this, ore);
        println();
      } else {
        // Just display the default message.
        println(e.getMessageObject());
      }
      return 1;
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
@@ -29,6 +29,7 @@
import static org.opends.messages.DSConfigMessages.*;
import static org.opends.server.tools.dsconfig.ArgumentExceptionFactory.*;
import java.util.HashMap;
import java.util.List;
@@ -38,6 +39,8 @@
import java.util.TreeSet;
import org.opends.messages.Message;
import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.BooleanPropertyDefinition;
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.IllegalPropertyValueStringException;
import org.opends.server.admin.InstantiableRelationDefinition;
@@ -69,8 +72,6 @@
import org.opends.server.util.cli.CLIException;
import org.opends.server.util.cli.ConsoleApplication;
import org.opends.server.util.cli.MenuResult;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
@@ -83,7 +84,7 @@
final class SetPropSubCommandHandler extends SubCommandHandler {
  /**
   * Type of modication being performed.
   * Type of modification being performed.
   */
  private static enum ModificationType {
    /**
@@ -207,6 +208,285 @@
    return new SetPropSubCommandHandler(parser, path.child(r), r);
  }
  /**
   * Configure the provided managed object.
   *
   * @param app
   *          The console application.
   * @param context
   *          The management context.
   * @param mo
   *          The managed object to be configured.
   * @return Returns a MenuResult.success() if the managed object was
   *         configured successfully, or MenuResult.quit(), or
   *         MenuResult.cancel(), if the managed object was edited
   *         interactively and the user chose to quit or cancel.
   * @throws ClientException
   *           If an unrecoverable client exception occurred whilst
   *           interacting with the server.
   * @throws CLIException
   *           If an error occurred whilst interacting with the
   *           console.
   */
  public static MenuResult<Void> modifyManagedObject(ConsoleApplication app,
      ManagementContext context, ManagedObject<?> mo) throws ClientException,
      CLIException {
    ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition();
    Message ufn = d.getUserFriendlyName();
    while (true) {
      // Interactively set properties if applicable.
      if (app.isInteractive()) {
        SortedSet<PropertyDefinition<?>> properties =
          new TreeSet<PropertyDefinition<?>>();
        for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
          if (pd.hasOption(PropertyOption.HIDDEN)) {
            continue;
          }
          if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
            continue;
          }
          properties.add(pd);
        }
        PropertyValueEditor editor = new PropertyValueEditor(app, context);
        MenuResult<Void> result = editor.edit(mo, properties, false);
        // Interactively enable/edit referenced components.
        if (result.isSuccess()) {
          result = checkReferences(app, context, mo);
          if (result.isAgain()) {
            // Edit again.
            continue;
          }
        }
        if (result.isQuit()) {
          if (!app.isMenuDrivenMode()) {
            // User chose to cancel any changes.
            Message msg = INFO_DSCFG_CONFIRM_MODIFY_FAIL.get(ufn);
            app.printVerboseMessage(msg);
          }
          return MenuResult.quit();
        } else if (result.isCancel()) {
          return MenuResult.cancel();
        }
      }
      try {
        // Commit the changes.
        mo.commit();
        // Output success message.
        app.println();
        Message msg = INFO_DSCFG_CONFIRM_MODIFY_SUCCESS.get(ufn);
        app.printVerboseMessage(msg);
        return MenuResult.success();
      } catch (MissingMandatoryPropertiesException e) {
        if (app.isInteractive()) {
          // If interactive, give the user the chance to fix the
          // problems.
          app.println();
          displayMissingMandatoryPropertyException(app, e);
          app.println();
          if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
            return MenuResult.cancel();
          }
        } else {
          throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e
              .getMessageObject(), e);
        }
      } catch (AuthorizationException e) {
        Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
        throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
            msg);
      } catch (ConcurrentModificationException e) {
        Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn);
        throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg);
      } catch (OperationRejectedException e) {
        if (app.isInteractive()) {
          // If interactive, give the user the chance to fix the
          // problems.
          app.println();
          displayOperationRejectedException(app, e);
          app.println();
          if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
            return MenuResult.cancel();
          }
        } else {
          throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, e
              .getMessageObject(), e);
        }
      } catch (CommunicationException e) {
        Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage());
        throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
      } catch (ManagedObjectAlreadyExistsException e) {
        // Should never happen.
        throw new IllegalStateException(e);
      }
    }
  }
  // Check that any referenced components are enabled if
  // required.
  private static MenuResult<Void> checkReferences(ConsoleApplication app,
      ManagementContext context, ManagedObject<?> mo) throws ClientException,
      CLIException {
    ManagedObjectDefinition<?, ?> d = mo.getManagedObjectDefinition();
    Message ufn = d.getUserFriendlyName();
    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
      if (pd instanceof AggregationPropertyDefinition) {
        AggregationPropertyDefinition<?, ?> apd =
          (AggregationPropertyDefinition<?, ?>) pd;
        // Skip this aggregation if it doesn't have an enable
        // property.
        BooleanPropertyDefinition tpd = apd
            .getTargetEnabledPropertyDefinition();
        if (tpd == null) {
          continue;
        }
        // Skip this aggregation if this managed object's enable
        // properties are not all true.
        boolean needsEnabling = true;
        for (BooleanPropertyDefinition bpd : apd
            .getSourceEnabledPropertyDefinitions()) {
          if (!mo.getPropertyValue(bpd)) {
            needsEnabling = false;
            break;
          }
        }
        if (!needsEnabling) {
          continue;
        }
        // The referenced component(s) must be enabled.
        for (String name : mo.getPropertyValues(apd)) {
          ManagedObjectPath<?, ?> path = apd.getChildPath(name);
          Message rufn = path.getManagedObjectDefinition()
              .getUserFriendlyName();
          ManagedObject<?> ref;
          try {
            ref = context.getManagedObject(path);
          } catch (AuthorizationException e) {
            Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
            throw new ClientException(
                LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
          } catch (DefinitionDecodingException e) {
            Message msg = ERR_DSCFG_ERROR_GET_CHILD_DDE.get(rufn, rufn, rufn);
            throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
          } catch (ManagedObjectDecodingException e) {
            // FIXME: should not abort here. Instead, display the
            // errors (if verbose) and apply the changes to the
            // partial managed object.
            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MODE.get(rufn);
            throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg, e);
          } catch (CommunicationException e) {
            Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage());
            throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
          } catch (ManagedObjectNotFoundException e) {
            Message msg = ERR_DSCFG_ERROR_GET_CHILD_MONFE.get(rufn);
            throw new ClientException(LDAPResultCode.NO_SUCH_OBJECT, msg);
          }
          while (!ref.getPropertyValue(tpd)) {
            boolean isBadReference = true;
            app.println();
            if (app.confirmAction(
                INFO_EDITOR_PROMPT_ENABLED_REFERENCED_COMPONENT.get(rufn, name,
                    ufn), true)) {
              ref.setPropertyValue(tpd, true);
              try {
                ref.commit();
                isBadReference = false;
              } catch (MissingMandatoryPropertiesException e) {
                // Give the user the chance to fix the problems.
                app.println();
                displayMissingMandatoryPropertyException(app, e);
                app.println();
                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
                  // FIXME: edit the properties of the referenced
                  // object.
                  MenuResult<Void> result =
                    modifyManagedObject(app, context, ref);
                  if (result.isQuit()) {
                    return result;
                  } else if (result.isSuccess()) {
                    // The referenced component was modified
                    // successfully, but may still be disabled.
                    isBadReference = false;
                  }
                }
              } catch (AuthorizationException e) {
                Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
                throw new ClientException(
                    LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS, msg);
              } catch (ConcurrentModificationException e) {
                Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn);
                throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
                    msg);
              } catch (OperationRejectedException e) {
                // Give the user the chance to fix the problems.
                app.println();
                displayOperationRejectedException(app, e);
                app.println();
                if (app.confirmAction(INFO_DSCFG_PROMPT_EDIT.get(rufn), true)) {
                  MenuResult<Void> result =
                    modifyManagedObject(app, context, ref);
                  if (result.isQuit()) {
                    return result;
                  } else if (result.isSuccess()) {
                    // The referenced component was modified
                    // successfully, but may still be disabled.
                    isBadReference = false;
                  }
                }
              } catch (CommunicationException e) {
                Message msg = ERR_DSCFG_ERROR_MODIFY_CE
                    .get(ufn, e.getMessage());
                throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
              } catch (ManagedObjectAlreadyExistsException e) {
                // Should never happen.
                throw new IllegalStateException(e);
              }
            }
            // If the referenced component is still disabled because
            // the user refused to modify it, then give the used the
            // option of editing the referencing component.
            if (isBadReference) {
              app.println();
              app.println(ERR_SET_REFERENCED_COMPONENT_DISABLED.get(ufn, rufn));
              app.println();
              if (app
                  .confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
                return MenuResult.again();
              } else {
                return MenuResult.cancel();
              }
            }
            // If the referenced component is now enabled, then drop out.
            if (ref.getPropertyValue(tpd)) {
              break;
            }
          }
        }
      }
    }
    return MenuResult.success();
  }
  // The sub-commands naming arguments.
  private final List<StringArgument> namingArgs;
@@ -509,96 +789,15 @@
      }
    }
    while (true) {
      // Interactively set properties if applicable.
      if (app.isInteractive()) {
        SortedSet<PropertyDefinition<?>> properties =
          new TreeSet<PropertyDefinition<?>>();
        for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
          if (pd.hasOption(PropertyOption.HIDDEN)) {
            continue;
          }
          if (!app.isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
            continue;
          }
          properties.add(pd);
        }
        PropertyValueEditor editor = new PropertyValueEditor(app, context);
        MenuResult<Void> result2 = editor.edit(child, properties, false);
        if (result2.isQuit()) {
          if (!app.isMenuDrivenMode()) {
            // User chose to cancel any changes.
            Message msg = INFO_DSCFG_CONFIRM_MODIFY_FAIL.get(ufn);
            app.printVerboseMessage(msg);
          }
          return MenuResult.quit();
        } else if (result2.isCancel()) {
          return MenuResult.cancel();
        }
      }
      try {
        // Commit the changes.
        child.commit();
        // Output success message.
        Message msg = INFO_DSCFG_CONFIRM_MODIFY_SUCCESS.get(ufn);
        app.printVerboseMessage(msg);
        return MenuResult.success(0);
      } catch (MissingMandatoryPropertiesException e) {
        throw ArgumentExceptionFactory
            .adaptMissingMandatoryPropertiesException(e, d);
      } catch (AuthorizationException e) {
        Message msg = ERR_DSCFG_ERROR_MODIFY_AUTHZ.get(ufn);
        throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
            msg);
      } catch (ConcurrentModificationException e) {
        Message msg = ERR_DSCFG_ERROR_MODIFY_CME.get(ufn);
        throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msg);
      } catch (OperationRejectedException e) {
        Message msg;
        if (e.getMessages().size() == 1) {
          msg = ERR_DSCFG_ERROR_MODIFY_ORE_SINGLE.get(ufn);
        } else {
          msg = ERR_DSCFG_ERROR_MODIFY_ORE_PLURAL.get(ufn);
        }
        if (app.isInteractive()) {
          // If interactive, give the user the chance to fix the problems.
          app.println();
          app.println(msg);
          app.println();
          TableBuilder builder = new TableBuilder();
          for (Message reason : e.getMessages()) {
            builder.startRow();
            builder.appendCell("*");
            builder.appendCell(reason);
          }
          TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
          printer.setDisplayHeadings(false);
          printer.setColumnWidth(1, 0);
          printer.setIndentWidth(4);
          builder.print(printer);
          app.println();
          if (!app.confirmAction(INFO_DSCFG_PROMPT_EDIT_AGAIN.get(ufn), true)) {
            return MenuResult.cancel();
          }
        } else {
          throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
              msg, e);
        }
      } catch (CommunicationException e) {
        Message msg = ERR_DSCFG_ERROR_MODIFY_CE.get(ufn, e.getMessage());
        throw new ClientException(LDAPResultCode.OPERATIONS_ERROR, msg);
      } catch (ManagedObjectAlreadyExistsException e) {
        // Should never happen.
        throw new IllegalStateException(e);
      }
    // Now the command line changes have been made, apply the changes
    // interacting with the user to fix any problems if required.
    MenuResult<Void> result2 = modifyManagedObject(app, context, child);
    if (result2.isCancel()){
      return MenuResult.cancel();
    } else if (result2.isQuit()) {
      return MenuResult.quit();
    } else {
      return MenuResult.success(0);
    }
  }