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

matthew_swift
19.31.2007 8228fb82f3ad657adf7832eb05c624bf48c4a30e
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);
    }
  }