/**
   * Test to show that reporting an error about an uninitialized variable when generating templates
   * reports the correct line.
   */
  @Test
  public void testParseTemplate() throws Exception {
    String[] lines = {
      /* 0 */ "template: template",
      /* 1 */ "a: {missingVar}",
      /* 2 */ "a: b",
      /* 3 */ "a: c",
      /* 4 */ "",
      /* 5 */ "template: template2",
    };

    // Test must show "missingVar" missing on line 1.
    // Previous behaviour showed "missingVar" on line 5.

    TemplateFile templateFile = new TemplateFile(resourcePath);
    List<LocalizableMessage> warns = new ArrayList<>();

    try {
      templateFile.parse(lines, warns);
    } catch (InitializationException e) {
      String msg = e.getMessage();
      LocalizableMessage msg_locale = ERR_MAKELDIF_TAG_UNDEFINED_ATTRIBUTE.get("missingVar", 1);
      assertEquals(msg, msg_locale.toString(), msg);
    }
  }
  /**
   * Rebuild index(es) in the backend instance. Note that the server will not explicitly initialize
   * this backend before calling this method.
   *
   * @param rebuildConfig The rebuild configuration.
   * @throws ConfigException If an unrecoverable problem arises during initialization.
   * @throws InitializationException If a problem occurs during initialization that is not related
   *     to the server configuration.
   * @throws DirectoryException If a Directory Server error occurs.
   */
  public void rebuildBackend(RebuildConfig rebuildConfig)
      throws InitializationException, ConfigException, DirectoryException {
    // If the backend already has the root container open, we must use the same
    // underlying root container
    boolean openRootContainer = rootContainer == null;

    /*
     * If the rootContainer is open, the backend is initialized by something
     * else. We can't do any rebuild of system indexes while others are using
     * this backend.
     */
    if (!openRootContainer && rebuildConfig.includesSystemIndex()) {
      Message message = ERR_JEB_REBUILD_BACKEND_ONLINE.get();
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    }

    try {
      EnvironmentConfig envConfig;
      if (openRootContainer) {
        envConfig = new EnvironmentConfig();
        envConfig.setAllowCreate(true);
        envConfig.setTransactional(false);
        envConfig.setDurability(Durability.COMMIT_NO_SYNC);
        envConfig.setLockTimeout(0, TimeUnit.SECONDS);
        envConfig.setTxnTimeout(0, TimeUnit.SECONDS);
        envConfig.setConfigParam(
            EnvironmentConfig.CLEANER_MIN_FILE_UTILIZATION,
            String.valueOf(cfg.getDBCleanerMinUtilization()));
        envConfig.setConfigParam(
            EnvironmentConfig.LOG_FILE_MAX, String.valueOf(cfg.getDBLogFileMax()));

        Importer importer = new Importer(rebuildConfig, cfg, envConfig);
        rootContainer = initializeRootContainer(envConfig);
        importer.rebuildIndexes(rootContainer);
      } else {
        envConfig = ConfigurableEnvironment.parseConfigEntry(cfg);

        Importer importer = new Importer(rebuildConfig, cfg, envConfig);
        importer.rebuildIndexes(rootContainer);
      }
    } catch (ExecutionException execEx) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, execEx);
      }
      Message message = ERR_EXECUTION_ERROR.get(execEx.getMessage());
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    } catch (InterruptedException intEx) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, intEx);
      }
      Message message = ERR_INTERRUPTED_ERROR.get(intEx.getMessage());
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    } catch (ConfigException ce) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), ce.getMessageObject());
    } catch (JebException e) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), e.getMessageObject());
    } catch (InitializationException e) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      throw new InitializationException(e.getMessageObject());
    } finally {
      // If a root container was opened in this method as read only, close it
      // to leave the backend in the same state.
      if (openRootContainer && rootContainer != null) {
        try {
          rootContainer.close();
          rootContainer = null;
        } catch (DatabaseException e) {
          if (debugEnabled()) {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
        }
      }
    }
  }
Exemple #3
0
  /**
   * Processes the command-line arguments and invokes the export process.
   *
   * @param args The command-line arguments provided to this program.
   * @param initializeServer Indicates whether to initialize the server.
   * @return The error code.
   */
  public int process(String[] args, boolean initializeServer) {
    if (initializeServer) {
      DirectoryServer.bootstrapClient();
    }
    JDKLogging.disableLogging();

    // Create the command-line argument parser for use with this program.
    LDAPConnectionArgumentParser argParser =
        new LDAPConnectionArgumentParser(
            "org.opends.server.tools.TaskInfo",
            INFO_TASKINFO_TOOL_DESCRIPTION.get(),
            false,
            null,
            alwaysSSL);
    argParser.setShortToolDescription(REF_SHORT_DESC_MANAGE_TASKS.get());

    // Initialize all the command-line argument types and register them with the
    // parser.
    try {

      StringArgument propertiesFileArgument =
          new StringArgument(
              "propertiesFilePath",
              null,
              OPTION_LONG_PROP_FILE_PATH,
              false,
              false,
              true,
              INFO_PROP_FILE_PATH_PLACEHOLDER.get(),
              null,
              null,
              INFO_DESCRIPTION_PROP_FILE_PATH.get());
      argParser.addArgument(propertiesFileArgument);
      argParser.setFilePropertiesArgument(propertiesFileArgument);

      BooleanArgument noPropertiesFileArgument =
          new BooleanArgument(
              "noPropertiesFileArgument",
              null,
              OPTION_LONG_NO_PROP_FILE,
              INFO_DESCRIPTION_NO_PROP_FILE.get());
      argParser.addArgument(noPropertiesFileArgument);
      argParser.setNoPropertiesFileArgument(noPropertiesFileArgument);

      task =
          new StringArgument(
              "info",
              'i',
              "info",
              false,
              true,
              INFO_TASK_ID_PLACEHOLDER.get(),
              INFO_TASKINFO_TASK_ARG_DESCRIPTION.get());
      argParser.addArgument(task);

      cancel =
          new StringArgument(
              "cancel",
              'c',
              "cancel",
              false,
              true,
              INFO_TASK_ID_PLACEHOLDER.get(),
              INFO_TASKINFO_TASK_ARG_CANCEL.get());
      argParser.addArgument(cancel);

      summary =
          new BooleanArgument(
              "summary", 's', "summary", INFO_TASKINFO_SUMMARY_ARG_DESCRIPTION.get());
      argParser.addArgument(summary);

      noPrompt = CommonArguments.getNoPrompt();
      argParser.addArgument(noPrompt);

      BooleanArgument displayUsage = CommonArguments.getShowUsage();
      argParser.addArgument(displayUsage);
      argParser.setUsageArgument(displayUsage);
    } catch (ArgumentException ae) {
      LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
      println(message);
      return 1;
    }

    try {
      argParser.getArguments().initArgumentsWithConfiguration();
    } catch (ConfigException ce) {
      // Ignore.
    }

    // Parse the command-line arguments provided to this program.
    try {
      argParser.parseArguments(args);
      StaticUtils.checkOnlyOneArgPresent(task, summary, cancel);
    } catch (ArgumentException ae) {
      LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
      println(message);
      println(argParser.getUsageMessage());
      return 1;
    }

    if (!argParser.usageOrVersionDisplayed()) {
      // Checks the version - if upgrade required, the tool is unusable
      try {
        BuildVersion.checkVersionMismatch();
      } catch (InitializationException e) {
        println(e.getMessageObject());
        return 1;
      }

      try {
        LDAPConnectionConsoleInteraction ui =
            new LDAPConnectionConsoleInteraction(this, argParser.getArguments());

        taskClient = new TaskClient(argParser.connect(ui, getOutputStream(), getErrorStream()));

        if (isMenuDrivenMode()) {

          // Keep prompting the user until they specify quit of
          // there is a fatal exception
          while (true) {
            getOutputStream().println();
            Menu<Void> menu = getSummaryMenu();
            MenuResult<Void> result = menu.run();
            if (result.isQuit()) {
              return 0;
            }
          }

        } else if (task.isPresent()) {
          getOutputStream().println();
          MenuResult<TaskEntry> r = new PrintTaskInfo(task.getValue()).invoke(this);
          if (r.isAgain()) {
            return 1;
          }
        } else if (summary.isPresent()) {
          getOutputStream().println();
          printSummaryTable();
        } else if (cancel.isPresent()) {
          MenuResult<TaskEntry> r = new CancelTask(cancel.getValue()).invoke(this);
          if (r.isAgain()) {
            return 1;
          }
        } else if (!isInteractive()) {
          // no-prompt option
          getOutputStream().println();
          printSummaryTable();
          return 0;
        }

      } catch (LDAPConnectionException lce) {
        println(INFO_TASKINFO_LDAP_EXCEPTION.get(lce.getMessageObject()));
        return 1;
      } catch (Exception e) {
        println(LocalizableMessage.raw(StaticUtils.getExceptionMessage(e)));
        return 1;
      }
    }
    return 0;
  }
  /** {@inheritDoc} */
  @Override()
  public LDIFImportResult importLDIF(LDIFImportConfig importConfig) throws DirectoryException {
    RuntimeInformation.logInfo();

    // If the backend already has the root container open, we must use the same
    // underlying root container
    boolean openRootContainer = rootContainer == null;

    // If the rootContainer is open, the backend is initialized by something
    // else.
    // We can't do import while the backend is online.
    if (!openRootContainer) {
      Message message = ERR_JEB_IMPORT_BACKEND_ONLINE.get();
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    }

    try {
      EnvironmentConfig envConfig = new EnvironmentConfig();

      envConfig.setAllowCreate(true);
      envConfig.setTransactional(false);
      envConfig.setDurability(Durability.COMMIT_NO_SYNC);
      envConfig.setLockTimeout(0, TimeUnit.SECONDS);
      envConfig.setTxnTimeout(0, TimeUnit.SECONDS);
      envConfig.setConfigParam(
          EnvironmentConfig.CLEANER_MIN_FILE_UTILIZATION,
          String.valueOf(cfg.getDBCleanerMinUtilization()));
      envConfig.setConfigParam(
          EnvironmentConfig.LOG_FILE_MAX, String.valueOf(cfg.getDBLogFileMax()));

      if (!importConfig.appendToExistingData()) {
        if (importConfig.clearBackend() || cfg.getBaseDN().size() <= 1) {
          // We have the writer lock on the environment, now delete the
          // environment and re-open it. Only do this when we are
          // importing to all the base DNs in the backend or if the backend only
          // have one base DN.
          File parentDirectory = getFileForPath(cfg.getDBDirectory());
          File backendDirectory = new File(parentDirectory, cfg.getBackendId());
          // If the backend does not exist the import will create it.
          if (backendDirectory.exists()) {
            EnvManager.removeFiles(backendDirectory.getPath());
          }
        }
      }

      Importer importer = new Importer(importConfig, cfg, envConfig);
      rootContainer = initializeRootContainer(envConfig);
      return importer.processImport(rootContainer);
    } catch (ExecutionException execEx) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, execEx);
      }
      if (execEx.getCause() instanceof DirectoryException) {
        throw ((DirectoryException) execEx.getCause());
      } else {
        Message message = ERR_EXECUTION_ERROR.get(execEx.getMessage());
        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
      }
    } catch (InterruptedException intEx) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, intEx);
      }
      Message message = ERR_INTERRUPTED_ERROR.get(intEx.getMessage());
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    } catch (JebException je) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, je);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), je.getMessageObject());
    } catch (InitializationException ie) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ie);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), ie.getMessageObject());
    } catch (ConfigException ce) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), ce.getMessageObject());
    } finally {
      // leave the backend in the same state.
      try {
        if (rootContainer != null) {
          long startTime = System.currentTimeMillis();
          rootContainer.close();
          long finishTime = System.currentTimeMillis();
          long closeTime = (finishTime - startTime) / 1000;
          Message msg = NOTE_JEB_IMPORT_LDIF_ROOTCONTAINER_CLOSE.get(closeTime);
          logError(msg);
          rootContainer = null;
        }

        // Sync the environment to disk.
        if (debugEnabled()) {
          Message message = NOTE_JEB_IMPORT_CLOSING_DATABASE.get();
          TRACER.debugInfo(message.toString());
        }
      } catch (DatabaseException de) {
        if (debugEnabled()) {
          TRACER.debugCaught(DebugLogLevel.ERROR, de);
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override()
  public void exportLDIF(LDIFExportConfig exportConfig) throws DirectoryException {
    // If the backend already has the root container open, we must use the same
    // underlying root container
    boolean openRootContainer = rootContainer == null;

    try {
      if (openRootContainer) {
        EnvironmentConfig envConfig = ConfigurableEnvironment.parseConfigEntry(cfg);

        envConfig.setReadOnly(true);
        envConfig.setAllowCreate(false);
        envConfig.setTransactional(false);
        envConfig.setConfigParam("je.env.isLocking", "true");
        envConfig.setConfigParam("je.env.runCheckpointer", "true");

        rootContainer = initializeRootContainer(envConfig);
      }

      ExportJob exportJob = new ExportJob(exportConfig);
      exportJob.exportLDIF(rootContainer);
    } catch (IOException ioe) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ioe);
      }
      Message message = ERR_JEB_EXPORT_IO_ERROR.get(ioe.getMessage());
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    } catch (JebException je) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, je);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), je.getMessageObject());
    } catch (DatabaseException de) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, de);
      }
      throw createDirectoryException(de);
    } catch (LDIFException e) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), e.getMessageObject());
    } catch (InitializationException ie) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ie);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), ie.getMessageObject());
    } catch (ConfigException ce) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(), ce.getMessageObject());
    } finally {
      // If a root container was opened in this method as read only, close it
      // to leave the backend in the same state.
      if (openRootContainer && rootContainer != null) {
        try {
          rootContainer.close();
          rootContainer = null;
        } catch (DatabaseException e) {
          if (debugEnabled()) {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
        }
      }
    }
  }
  /**
   * Parses the provided command-line arguments and makes the appropriate changes to the Directory
   * Server configuration.
   *
   * @param args The command-line arguments provided to this program.
   * @param outStream Output stream.
   * @param errStream Error stream.
   * @return The exit code from the configuration processing. A nonzero value indicates that there
   *     was some kind of problem during the configuration processing.
   */
  public static int configMain(String[] args, OutputStream outStream, OutputStream errStream) {
    BooleanArgument showUsage;
    BooleanArgument enableStartTLS;
    FileBasedArgument rootPasswordFile;
    StringArgument hostName;
    IntegerArgument ldapPort;
    IntegerArgument adminConnectorPort;
    IntegerArgument ldapsPort;
    IntegerArgument jmxPort;
    StringArgument baseDNString;
    StringArgument configClass;
    StringArgument configFile;
    StringArgument rootDNString;
    StringArgument rootPassword;
    StringArgument keyManagerProviderDN;
    StringArgument trustManagerProviderDN;
    StringArgument certNickName;
    StringArgument keyManagerPath;
    StringArgument serverRoot;
    PrintStream out, err;

    if (outStream != null) {
      out = new PrintStream(outStream);
    } else {
      out = NullOutputStream.printStream();
    }

    if (errStream != null) {
      err = new PrintStream(errStream);
    } else {
      err = NullOutputStream.printStream();
    }
    Message toolDescription = INFO_CONFIGDS_TOOL_DESCRIPTION.get();
    ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription, false);
    try {
      configFile =
          new StringArgument(
              "configfile",
              'c',
              "configFile",
              true,
              false,
              true,
              INFO_CONFIGFILE_PLACEHOLDER.get(),
              null,
              null,
              INFO_DESCRIPTION_CONFIG_FILE.get());
      configFile.setHidden(true);
      argParser.addArgument(configFile);

      configClass =
          new StringArgument(
              "configclass",
              OPTION_SHORT_CONFIG_CLASS,
              OPTION_LONG_CONFIG_CLASS,
              false,
              false,
              true,
              INFO_CONFIGCLASS_PLACEHOLDER.get(),
              ConfigFileHandler.class.getName(),
              null,
              INFO_DESCRIPTION_CONFIG_CLASS.get());
      configClass.setHidden(true);
      argParser.addArgument(configClass);

      String defaultHostName;
      try {
        defaultHostName = InetAddress.getLocalHost().getHostName();
      } catch (Exception e) {
        // Not much we can do here.
        defaultHostName = "localhost";
      }
      hostName =
          new StringArgument(
              OPTION_LONG_HOST.toLowerCase(),
              OPTION_SHORT_HOST,
              OPTION_LONG_HOST,
              false,
              false,
              true,
              INFO_HOST_PLACEHOLDER.get(),
              defaultHostName,
              null,
              INFO_INSTALLDS_DESCRIPTION_HOST_NAME.get());
      argParser.addArgument(hostName);

      ldapPort =
          new IntegerArgument(
              "ldapport",
              OPTION_SHORT_PORT,
              "ldapPort",
              false,
              false,
              true,
              INFO_LDAPPORT_PLACEHOLDER.get(),
              389,
              null,
              true,
              1,
              true,
              65535,
              INFO_CONFIGDS_DESCRIPTION_LDAP_PORT.get());
      argParser.addArgument(ldapPort);

      adminConnectorPort =
          new IntegerArgument(
              "adminConnectorPort".toLowerCase(),
              null,
              "adminConnectorPort",
              false,
              false,
              true,
              INFO_PORT_PLACEHOLDER.get(),
              4444,
              "adminConnectorPort",
              true,
              1,
              true,
              65535,
              INFO_INSTALLDS_DESCRIPTION_ADMINCONNECTORPORT.get());
      argParser.addArgument(adminConnectorPort);

      ldapsPort =
          new IntegerArgument(
              "ldapsPort",
              'P',
              "ldapsPort",
              false,
              false,
              true,
              INFO_LDAPPORT_PLACEHOLDER.get(),
              636,
              null,
              true,
              1,
              true,
              65535,
              INFO_CONFIGDS_DESCRIPTION_LDAPS_PORT.get());
      argParser.addArgument(ldapsPort);

      enableStartTLS =
          new BooleanArgument(
              "enableStartTLS",
              OPTION_SHORT_START_TLS,
              "enableStartTLS",
              INFO_CONFIGDS_DESCRIPTION_ENABLE_START_TLS.get());
      argParser.addArgument(enableStartTLS);

      jmxPort =
          new IntegerArgument(
              "jmxport",
              'x',
              "jmxPort",
              false,
              false,
              true,
              INFO_JMXPORT_PLACEHOLDER.get(),
              SetupUtils.getDefaultJMXPort(),
              null,
              true,
              1,
              true,
              65535,
              INFO_CONFIGDS_DESCRIPTION_JMX_PORT.get());
      argParser.addArgument(jmxPort);

      keyManagerProviderDN =
          new StringArgument(
              "keymanagerproviderdn",
              'k',
              "keyManagerProviderDN",
              false,
              false,
              true,
              INFO_KEY_MANAGER_PROVIDER_DN_PLACEHOLDER.get(),
              null,
              null,
              INFO_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN.get());
      argParser.addArgument(keyManagerProviderDN);

      trustManagerProviderDN =
          new StringArgument(
              "trustmanagerproviderdn",
              't',
              "trustManagerProviderDN",
              false,
              false,
              true,
              INFO_TRUST_MANAGER_PROVIDER_DN_PLACEHOLDER.get(),
              null,
              null,
              INFO_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN.get());
      argParser.addArgument(trustManagerProviderDN);

      keyManagerPath =
          new StringArgument(
              "keymanagerpath",
              'm',
              "keyManagerPath",
              false,
              false,
              true,
              INFO_KEY_MANAGER_PATH_PLACEHOLDER.get(),
              null,
              null,
              INFO_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH.get());
      argParser.addArgument(keyManagerPath);

      certNickName =
          new StringArgument(
              "certnickname",
              'a',
              "certNickName",
              false,
              false,
              true,
              INFO_NICKNAME_PLACEHOLDER.get(),
              null,
              null,
              INFO_CONFIGDS_DESCRIPTION_CERTNICKNAME.get());
      argParser.addArgument(certNickName);

      baseDNString =
          new StringArgument(
              "basedn",
              OPTION_SHORT_BASEDN,
              OPTION_LONG_BASEDN,
              false,
              true,
              true,
              INFO_BASEDN_PLACEHOLDER.get(),
              "dc=example,dc=com",
              null,
              INFO_CONFIGDS_DESCRIPTION_BASE_DN.get());
      argParser.addArgument(baseDNString);

      rootDNString =
          new StringArgument(
              "rootdn",
              OPTION_SHORT_ROOT_USER_DN,
              OPTION_LONG_ROOT_USER_DN,
              false,
              false,
              true,
              INFO_ROOT_USER_DN_PLACEHOLDER.get(),
              "cn=Directory Manager",
              null,
              INFO_CONFIGDS_DESCRIPTION_ROOT_DN.get());
      argParser.addArgument(rootDNString);

      rootPassword =
          new StringArgument(
              "rootpw",
              OPTION_SHORT_BINDPWD,
              "rootPassword",
              false,
              false,
              true,
              INFO_ROOT_USER_PWD_PLACEHOLDER.get(),
              null,
              null,
              INFO_CONFIGDS_DESCRIPTION_ROOT_PW.get());
      argParser.addArgument(rootPassword);

      rootPasswordFile =
          new FileBasedArgument(
              "rootpwfile",
              OPTION_SHORT_BINDPWD_FILE,
              "rootPasswordFile",
              false,
              false,
              INFO_FILE_PLACEHOLDER.get(),
              null,
              null,
              INFO_CONFIGDS_DESCRIPTION_ROOT_PW_FILE.get());
      argParser.addArgument(rootPasswordFile);

      showUsage =
          new BooleanArgument(
              "showusage", OPTION_SHORT_HELP, OPTION_LONG_HELP, INFO_DESCRIPTION_USAGE.get());
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);

      serverRoot =
          new StringArgument(
              "serverRoot",
              ToolConstants.OPTION_SHORT_SERVER_ROOT,
              ToolConstants.OPTION_LONG_SERVER_ROOT,
              false,
              false,
              true,
              INFO_SERVER_ROOT_DIR_PLACEHOLDER.get(),
              null,
              null,
              null);
      serverRoot.setHidden(true);
      argParser.addArgument(serverRoot);
    } catch (ArgumentException ae) {
      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }

    // Parse the command-line arguments provided to the program.
    try {
      argParser.parseArguments(args);
    } catch (ArgumentException ae) {
      Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());

      err.println(wrapText(message, MAX_LINE_WIDTH));
      err.println(argParser.getUsage());
      return LDAPResultCode.CLIENT_SIDE_PARAM_ERROR;
    }

    // If we should just display usage or version information,
    // then print it and exit.
    if (argParser.usageOrVersionDisplayed()) {
      return 0;
    }

    // Make sure that the user actually tried to configure something.
    if (!(baseDNString.isPresent()
        || ldapPort.isPresent()
        || jmxPort.isPresent()
        || rootDNString.isPresent())) {
      Message message = ERR_CONFIGDS_NO_CONFIG_CHANGES.get();
      err.println(wrapText(message, MAX_LINE_WIDTH));
      err.println(argParser.getUsage());
      return 1;
    }

    try {
      Set<Integer> ports = new HashSet<Integer>();
      if (ldapPort.isPresent()) {
        ports.add(ldapPort.getIntValue());
      }
      if (adminConnectorPort.isPresent()) {
        if (ports.contains(adminConnectorPort.getIntValue())) {
          Message message =
              ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
                  String.valueOf(adminConnectorPort.getIntValue()));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          err.println(argParser.getUsage());
          return 1;
        } else {
          ports.add(adminConnectorPort.getIntValue());
        }
      }
      if (ldapsPort.isPresent()) {
        if (ports.contains(ldapsPort.getIntValue())) {
          Message message =
              ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(String.valueOf(ldapsPort.getIntValue()));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          err.println(argParser.getUsage());
          return 1;
        } else {
          ports.add(ldapsPort.getIntValue());
        }
      }
      if (jmxPort.isPresent()) {
        if (ports.contains(jmxPort.getIntValue())) {
          Message message =
              ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(String.valueOf(jmxPort.getIntValue()));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          err.println(argParser.getUsage());
          return 1;
        } else {
          ports.add(jmxPort.getIntValue());
        }
      }
    } catch (ArgumentException ae) {
      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }

    if (serverRoot.isPresent()) {
      DirectoryEnvironmentConfig env = DirectoryServer.getEnvironmentConfig();
      String root = serverRoot.getValue();
      try {
        env.setServerRoot(new File(serverRoot.getValue()));
      } catch (InitializationException e) {
        ERR_INITIALIZE_SERVER_ROOT.get(root, e.getMessageObject());
      }
    }

    // Initialize the Directory Server configuration handler using the
    // information that was provided.
    DirectoryServer directoryServer = DirectoryServer.getInstance();
    DirectoryServer.bootstrapClient();

    try {
      DirectoryServer.initializeJMX();
    } catch (Exception e) {
      Message message =
          ERR_CONFIGDS_CANNOT_INITIALIZE_JMX.get(
              String.valueOf(configFile.getValue()), e.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }

    try {
      directoryServer.initializeConfiguration(configClass.getValue(), configFile.getValue());
    } catch (Exception e) {
      Message message =
          ERR_CONFIGDS_CANNOT_INITIALIZE_CONFIG.get(
              String.valueOf(configFile.getValue()), e.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }

    try {
      directoryServer.initializeSchema();
    } catch (Exception e) {
      Message message =
          ERR_CONFIGDS_CANNOT_INITIALIZE_SCHEMA.get(
              String.valueOf(configFile.getValue()), e.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }

    // Make sure that we can get an exclusive lock for the Directory Server, so
    // that no other operation will be allowed while this is in progress.
    String serverLockFileName = LockFileManager.getServerLockFileName();
    StringBuilder failureReason = new StringBuilder();
    if (!LockFileManager.acquireExclusiveLock(serverLockFileName, failureReason)) {
      Message message =
          ERR_CONFIGDS_CANNOT_ACQUIRE_SERVER_LOCK.get(
              String.valueOf(serverLockFileName), String.valueOf(failureReason));
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }

    try {
      // If one or more base DNs were provided, then make sure that they can be
      // parsed as valid DNs.
      LinkedList<DN> baseDNs = null;
      if (baseDNString.isPresent()) {
        baseDNs = new LinkedList<DN>();
        for (String dnString : baseDNString.getValues()) {
          try {
            baseDNs.add(DN.decode(dnString));
          } catch (DirectoryException de) {
            Message message =
                ERR_CONFIGDS_CANNOT_PARSE_BASE_DN.get(
                    String.valueOf(dnString), de.getMessageObject());
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
      }

      // If a root user DN was provided, then make sure it can be parsed.  Also,
      // make sure that either a password or password file was specified.
      DN rootDN = null;
      String rootPW = null;
      if (rootDNString.isPresent()) {
        try {
          rootDN = DN.decode(rootDNString.getValue());
        } catch (DirectoryException de) {
          Message message =
              ERR_CONFIGDS_CANNOT_PARSE_ROOT_DN.get(
                  String.valueOf(rootDNString.getValue()), de.getMessageObject());
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }

        if (rootPassword.isPresent()) {
          rootPW = rootPassword.getValue();
        } else if (rootPasswordFile.isPresent()) {
          rootPW = rootPasswordFile.getValue();
        } else {
          Message message = ERR_CONFIGDS_NO_ROOT_PW.get();
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // Get the Directory Server configuration handler and use it to make the
      // appropriate configuration changes.
      ConfigHandler configHandler = DirectoryServer.getConfigHandler();

      // Check that the key manager provided is valid.
      if (keyManagerProviderDN.isPresent()) {
        DN dn = null;
        DN JCEKSProviderDN = null;
        try {
          dn = DN.decode(keyManagerProviderDN.getValue());
          JCEKSProviderDN = DN.decode("cn=JCEKS,cn=Key Manager Providers,cn=config");
        } catch (DirectoryException de) {
          Message message =
              ERR_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN.get(
                  keyManagerProviderDN.getValue(), de.getMessageObject());
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }

        if (dn.equals(JCEKSProviderDN)) {
          // Create the JCEKSProvider entry
          try {
            String ldif =
                "dn: cn=JCEKS,cn=Key Manager Providers,cn=config\n"
                    + "objectClass: top\n"
                    + "objectClass: ds-cfg-key-manager-provider\n"
                    + "objectClass: ds-cfg-file-based-key-manager-provider\n"
                    + "cn: JCEKS\n"
                    + "ds-cfg-java-class: org.opends.server.extensions."
                    + "FileBasedKeyManagerProvider\n"
                    + "ds-cfg-enabled: true\n"
                    + "ds-cfg-key-store-type: JCEKS\n"
                    + "ds-cfg-key-store-file: config/keystore.jceks\n"
                    + "ds-cfg-key-store-pin-file: config/keystore.pin";

            LDIFImportConfig ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
            LDIFReader reader = new LDIFReader(ldifImportConfig);
            Entry providerConfigEntry;
            while ((providerConfigEntry = reader.readEntry()) != null) {
              configHandler.addEntry(providerConfigEntry, null);
            }
          } catch (Exception e) {
            Message message =
                ERR_CONFIG_KEYMANAGER_CANNOT_CREATE_JCEKS_PROVIDER.get(String.valueOf(e));
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        } else {
          try {
            configHandler.getConfigEntry(dn);
          } catch (Exception e) {
            Message message = ERR_CONFIG_KEYMANAGER_CANNOT_GET_BASE.get(String.valueOf(e));
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
      }

      // Check that the trust manager provided is valid.
      if (trustManagerProviderDN.isPresent()) {
        DN dn = null;
        DN JCEKSTrustManagerDN = null;
        try {
          dn = DN.decode(trustManagerProviderDN.getValue());
          JCEKSTrustManagerDN = DN.decode("cn=JCEKS,cn=Trust Manager Providers,cn=config");
        } catch (DirectoryException de) {
          Message message =
              ERR_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN.get(
                  trustManagerProviderDN.getValue(), de.getMessageObject());
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }

        if (dn.equals(JCEKSTrustManagerDN)) {
          try {
            String ldif =
                "dn: cn=JCEKS,cn=Trust Manager Providers,cn=config\n"
                    + "objectClass: top\n"
                    + "objectClass: ds-cfg-trust-manager-provider\n"
                    + "objectClass: ds-cfg-file-based-trust-manager-provider\n"
                    + "cn: JCEKS\n"
                    + "ds-cfg-java-class: org.opends.server.extensions."
                    + "FileBasedTrustManagerProvider\n"
                    + "ds-cfg-enabled: false\n"
                    + "ds-cfg-trust-store-type: JCEKS\n"
                    + "ds-cfg-trust-store-file: config/truststore\n";

            LDIFImportConfig ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
            LDIFReader reader = new LDIFReader(ldifImportConfig);
            Entry trustManagerConfigEntry;
            while ((trustManagerConfigEntry = reader.readEntry()) != null) {
              configHandler.addEntry(trustManagerConfigEntry, null);
            }
          } catch (Exception e) {
            Message message = ERR_CONFIG_KEYMANAGER_CANNOT_GET_BASE.get(String.valueOf(e));
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        } else {
          try {
            configHandler.getConfigEntry(dn);
          } catch (Exception e) {
            Message message = ERR_CONFIG_TRUSTMANAGER_CANNOT_GET_BASE.get(String.valueOf(e));
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
      }

      // Check that the keystore path values are valid.
      if (keyManagerPath.isPresent()) {
        if (!keyManagerProviderDN.isPresent()) {
          Message message =
              ERR_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED.get(
                  keyManagerProviderDN.getLongIdentifier(), keyManagerPath.getLongIdentifier());
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // If one or more base DNs were specified, then update the config
      // accordingly.
      if (baseDNs != null) {
        try {
          DN jeBackendDN = DN.decode(DN_JE_BACKEND);
          ConfigEntry configEntry = configHandler.getConfigEntry(jeBackendDN);

          DNConfigAttribute baseDNAttr =
              new DNConfigAttribute(
                  ATTR_BACKEND_BASE_DN,
                  INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS.get(),
                  true,
                  true,
                  false,
                  baseDNs);
          configEntry.putConfigAttribute(baseDNAttr);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_BASE_DN.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // If an LDAP port was specified, then update the config accordingly.
      if (ldapPort.isPresent()) {
        try {
          DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
          ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);

          IntegerConfigAttribute portAttr =
              new IntegerConfigAttribute(
                  ATTR_LISTEN_PORT,
                  INFO_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
                  true,
                  false,
                  true,
                  true,
                  1,
                  true,
                  65535,
                  ldapPort.getIntValue());
          configEntry.putConfigAttribute(portAttr);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_LDAP_PORT.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // If an Admin Connector port was specified, then update the config
      // accordingly.
      if (adminConnectorPort.isPresent()) {
        try {
          DN adminConnectorDN = DN.decode(DN_ADMIN_CONNECTOR);
          ConfigEntry configEntry = configHandler.getConfigEntry(adminConnectorDN);

          IntegerConfigAttribute portAttr =
              new IntegerConfigAttribute(
                  ATTR_LISTEN_PORT,
                  INFO_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
                  true,
                  false,
                  true,
                  true,
                  1,
                  true,
                  65535,
                  adminConnectorPort.getIntValue());
          configEntry.putConfigAttribute(portAttr);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_ADMIN_CONNECTOR_PORT.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      //    If an LDAPS port was specified, then update the config accordingly.
      if (ldapsPort.isPresent()) {
        try {
          DN ldapListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
          ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);

          IntegerConfigAttribute portAttr =
              new IntegerConfigAttribute(
                  ATTR_LISTEN_PORT,
                  INFO_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
                  true,
                  false,
                  true,
                  true,
                  1,
                  true,
                  65535,
                  ldapsPort.getIntValue());
          configEntry.putConfigAttribute(portAttr);

          BooleanConfigAttribute enablePortAttr =
              new BooleanConfigAttribute(
                  ATTR_CONNECTION_HANDLER_ENABLED,
                  INFO_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE.get(),
                  true,
                  true);
          configEntry.putConfigAttribute(enablePortAttr);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      //    If an JMX port was specified, then update the config accordingly.
      if (jmxPort.isPresent()) {
        try {
          DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
          ConfigEntry configEntry = configHandler.getConfigEntry(jmxListenerDN);

          IntegerConfigAttribute portAttr =
              new IntegerConfigAttribute(
                  ATTR_LISTEN_PORT,
                  INFO_JMX_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
                  true,
                  false,
                  true,
                  true,
                  1,
                  true,
                  65535,
                  jmxPort.getIntValue());
          configEntry.putConfigAttribute(portAttr);

          BooleanConfigAttribute enablePortAttr =
              new BooleanConfigAttribute(
                  ATTR_CONNECTION_HANDLER_ENABLED,
                  INFO_JMX_CONNHANDLER_DESCRIPTION_ENABLE.get(),
                  true,
                  true);
          configEntry.putConfigAttribute(enablePortAttr);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_JMX_PORT.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // Start TLS configuration
      if (enableStartTLS.isPresent()) {
        try {
          DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
          ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);

          BooleanConfigAttribute startTLS =
              new BooleanConfigAttribute(
                  ATTR_ALLOW_STARTTLS,
                  INFO_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS.get(),
                  true,
                  true);
          configEntry.putConfigAttribute(startTLS);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_ENABLE_STARTTLS.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // Key manager provider
      if (keyManagerProviderDN.isPresent()) {
        if (enableStartTLS.isPresent() || ldapsPort.isPresent()) {
          try {
            // Enable the key manager
            DN dn = DN.decode(keyManagerProviderDN.getValue());
            ConfigEntry configEntry = configHandler.getConfigEntry(dn);

            BooleanConfigAttribute enableAttr =
                new BooleanConfigAttribute(
                    ATTR_KEYMANAGER_ENABLED,
                    INFO_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED.get(),
                    true,
                    true);
            configEntry.putConfigAttribute(enableAttr);
          } catch (Exception e) {
            Message message = ERR_CONFIGDS_CANNOT_ENABLE_KEYMANAGER.get(String.valueOf(e));
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }

        try {
          if (enableStartTLS.isPresent()) {
            // Use the key manager specified for the LDAP connection handler.
            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
            ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);

            StringConfigAttribute keyManagerProviderAttr =
                new StringConfigAttribute(
                    ATTR_KEYMANAGER_DN,
                    INFO_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN.get(),
                    false,
                    false,
                    true,
                    keyManagerProviderDN.getValue());
            configEntry.putConfigAttribute(keyManagerProviderAttr);
          }

          if (ldapsPort.isPresent()) {
            // Use the key manager specified for the LDAPS connection handler.
            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
            ConfigEntry configEntry = configHandler.getConfigEntry(ldapsListenerDN);

            StringConfigAttribute keyManagerProviderAttr =
                new StringConfigAttribute(
                    ATTR_KEYMANAGER_DN,
                    INFO_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN.get(),
                    false,
                    false,
                    true,
                    keyManagerProviderDN.getValue());
            configEntry.putConfigAttribute(keyManagerProviderAttr);
          }
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }

        if (keyManagerPath.isPresent()) {
          try {
            // Enable the key manager
            DN dn = DN.decode(keyManagerProviderDN.getValue());
            ConfigEntry configEntry = configHandler.getConfigEntry(dn);

            StringConfigAttribute pathAttr =
                new StringConfigAttribute(
                    ATTR_KEYSTORE_FILE,
                    INFO_FILE_KEYMANAGER_DESCRIPTION_FILE.get(),
                    true,
                    true,
                    true,
                    keyManagerPath.getValue());
            configEntry.putConfigAttribute(pathAttr);
          } catch (Exception e) {
            String message = String.valueOf(e);
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }
      }
      if (trustManagerProviderDN.isPresent()) {
        if (enableStartTLS.isPresent() || ldapsPort.isPresent()) {
          // Enable the trust manager
          try {
            DN dn = DN.decode(trustManagerProviderDN.getValue());
            ConfigEntry configEntry = configHandler.getConfigEntry(dn);

            BooleanConfigAttribute enableAttr =
                new BooleanConfigAttribute(
                    ATTR_TRUSTMANAGER_ENABLED,
                    ERR_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED.get(),
                    true,
                    true);
            configEntry.putConfigAttribute(enableAttr);
          } catch (Exception e) {
            Message message = ERR_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER.get(String.valueOf(e));
            err.println(wrapText(message, MAX_LINE_WIDTH));
            return 1;
          }
        }

        try {
          if (enableStartTLS.isPresent()) {
            // Use the trust manager specified for the LDAP connection handler.
            DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
            ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);

            StringConfigAttribute trustManagerProviderAttr =
                new StringConfigAttribute(
                    ATTR_TRUSTMANAGER_DN,
                    INFO_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN.get(),
                    false,
                    false,
                    true,
                    trustManagerProviderDN.getValue());
            configEntry.putConfigAttribute(trustManagerProviderAttr);
          }

          if (ldapsPort.isPresent()) {
            // Use the trust manager specified for the LDAPS connection handler.
            DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
            ConfigEntry configEntry = configHandler.getConfigEntry(ldapsListenerDN);

            StringConfigAttribute trustManagerProviderAttr =
                new StringConfigAttribute(
                    ATTR_TRUSTMANAGER_DN,
                    INFO_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN.get(),
                    false,
                    false,
                    true,
                    trustManagerProviderDN.getValue());
            configEntry.putConfigAttribute(trustManagerProviderAttr);
          }
        } catch (Exception e) {
          Message message =
              ERR_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      if (certNickName.isPresent()) {
        try {
          StringConfigAttribute certNickNameAttr =
              new StringConfigAttribute(
                  ATTR_SSL_CERT_NICKNAME,
                  INFO_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME.get(),
                  false,
                  false,
                  true,
                  certNickName.getValue());

          DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
          ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);
          if (ldapPort.isPresent()) {
            // Use the key manager specified for the LDAP connection handler.
            configEntry.putConfigAttribute(certNickNameAttr);
          } else {
            configEntry.removeConfigAttribute(ATTR_SSL_CERT_NICKNAME.toLowerCase());
          }

          // Use the key manager specified for the LDAPS connection handler.
          DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
          configEntry = configHandler.getConfigEntry(ldapsListenerDN);
          if (ldapsPort.isPresent()) {
            configEntry.putConfigAttribute(certNickNameAttr);
          } else {
            configEntry.removeConfigAttribute(ATTR_SSL_CERT_NICKNAME.toLowerCase());
          }

          certNickNameAttr =
              new StringConfigAttribute(
                  ATTR_SSL_CERT_NICKNAME,
                  INFO_JMX_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME.get(),
                  false,
                  false,
                  true,
                  certNickName.getValue());

          // Use the key manager specified for the JMX connection handler.
          DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
          configEntry = configHandler.getConfigEntry(jmxListenerDN);
          if (jmxPort.isPresent()) {
            configEntry.putConfigAttribute(certNickNameAttr);
          } else {
            configEntry.removeConfigAttribute(ATTR_SSL_CERT_NICKNAME.toLowerCase());
          }
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      } else {
        try {
          // Use the key manager specified for the LDAP connection handler.
          DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
          ConfigEntry configEntry = configHandler.getConfigEntry(ldapListenerDN);

          configEntry.removeConfigAttribute(ATTR_SSL_CERT_NICKNAME.toLowerCase());

          // Use the key manager specified for the LDAPS connection handler.
          DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
          configEntry = configHandler.getConfigEntry(ldapsListenerDN);

          configEntry.removeConfigAttribute(ATTR_SSL_CERT_NICKNAME.toLowerCase());

          // Use the key manager specified for the JMX connection handler.
          DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
          configEntry = configHandler.getConfigEntry(jmxListenerDN);

          configEntry.removeConfigAttribute(ATTR_SSL_CERT_NICKNAME.toLowerCase());
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // If a root user DN and password were specified, then update the config
      // accordingly.
      if (rootDN != null) {
        try {
          DN rootUserDN = DN.decode(DN_ROOT_USER);
          ConfigEntry configEntry = configHandler.getConfigEntry(rootUserDN);

          DNConfigAttribute bindDNAttr =
              new DNConfigAttribute(
                  ATTR_ROOTDN_ALTERNATE_BIND_DN,
                  INFO_CONFIG_ROOTDN_DESCRIPTION_ALTERNATE_BIND_DN.get(),
                  false,
                  true,
                  false,
                  rootDN);
          configEntry.putConfigAttribute(bindDNAttr);

          byte[] rootPWBytes = getBytes(rootPW);
          String encodedPassword = SaltedSHA512PasswordStorageScheme.encodeOffline(rootPWBytes);
          StringConfigAttribute bindPWAttr =
              new StringConfigAttribute(
                  ATTR_USER_PASSWORD, Message.EMPTY, false, false, false, encodedPassword);
          configEntry.putConfigAttribute(bindPWAttr);
        } catch (Exception e) {
          Message message = ERR_CONFIGDS_CANNOT_UPDATE_ROOT_USER.get(String.valueOf(e));
          err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }

      // Set the FQDN for the DIGEST-MD5 SASL mechanism.
      try {
        DN digestMD5DN = DN.decode(DN_DIGEST_MD5_SASL_MECHANISM);
        ConfigEntry configEntry = configHandler.getConfigEntry(digestMD5DN);
        StringConfigAttribute fqdnAttr =
            new StringConfigAttribute(
                "ds-cfg-server-fqdn", Message.EMPTY, false, false, false, hostName.getValue());
        configEntry.putConfigAttribute(fqdnAttr);
      } catch (Exception e) {
        Message message = ERR_CONFIGDS_CANNOT_UPDATE_DIGEST_MD5_FQDN.get(String.valueOf(e));
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
      }

      // Check that the cipher specified is supported.  This is intended to
      // fix issues with JVM that do not support the default cipher (see
      // issue 3075 for instance).
      CryptoManagerCfgDefn cryptoManager = CryptoManagerCfgDefn.getInstance();
      StringPropertyDefinition prop =
          cryptoManager.getKeyWrappingTransformationPropertyDefinition();
      String defaultCipher = null;
      DefaultBehaviorProvider<?> p = prop.getDefaultBehaviorProvider();
      if (p instanceof DefinedDefaultBehaviorProvider) {
        Collection<?> defaultValues = ((DefinedDefaultBehaviorProvider<?>) p).getDefaultValues();
        if (!defaultValues.isEmpty()) {
          defaultCipher = defaultValues.iterator().next().toString();
        }
      }
      if (defaultCipher != null) {
        // Check that the default cipher is supported by the JVM.
        try {
          Cipher.getInstance(defaultCipher);
        } catch (GeneralSecurityException ex) {
          // The cipher is not supported: try to find an alternative one.
          String alternativeCipher = getAlternativeCipher();
          if (alternativeCipher != null) {
            try {
              DN cipherDN = DN.decode(DN_CRYPTO_MANAGER);
              ConfigEntry configEntry = configHandler.getConfigEntry(cipherDN);

              // Set the alternative cipher
              StringConfigAttribute keyWrappingTransformation =
                  new StringConfigAttribute(
                      ATTR_CRYPTO_CIPHER_KEY_WRAPPING_TRANSFORMATION,
                      Message.EMPTY,
                      false,
                      false,
                      true,
                      alternativeCipher);
              configEntry.putConfigAttribute(keyWrappingTransformation);
            } catch (Exception e) {
              Message message = ERR_CONFIGDS_CANNOT_UPDATE_CRYPTO_MANAGER.get(String.valueOf(e));
              err.println(wrapText(message, MAX_LINE_WIDTH));
              return 1;
            }
          }
        }
      }

      // Write the updated configuration.
      try {
        configHandler.writeUpdatedConfig();

        Message message = INFO_CONFIGDS_WROTE_UPDATED_CONFIG.get();
        out.println(wrapText(message, MAX_LINE_WIDTH));
      } catch (DirectoryException de) {
        Message message = ERR_CONFIGDS_CANNOT_WRITE_UPDATED_CONFIG.get(de.getMessageObject());
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
      }
    } finally {
      LockFileManager.releaseLock(serverLockFileName, failureReason);
    }

    // If we've gotten here, then everything was successful.
    return 0;
  }
Exemple #7
0
  /** {@inheritDoc} */
  @Override
  protected int processLocal(boolean initializeServer, PrintStream out, PrintStream err) {

    // Perform the initial bootstrap of the Directory Server and process the
    // configuration.
    DirectoryServer directoryServer = DirectoryServer.getInstance();
    if (initializeServer) {
      try {
        DirectoryServer.bootstrapClient();
        DirectoryServer.initializeJMX();
      } catch (Exception e) {
        printWrappedText(err, ERR_SERVER_BOOTSTRAP_ERROR.get(getExceptionMessage(e)));
        return 1;
      }

      try {
        directoryServer.initializeConfiguration(configClass.getValue(), configFile.getValue());
      } catch (InitializationException ie) {
        printWrappedText(err, ERR_CANNOT_LOAD_CONFIG.get(ie.getMessage()));
        return 1;
      } catch (Exception e) {
        printWrappedText(err, ERR_CANNOT_LOAD_CONFIG.get(getExceptionMessage(e)));
        return 1;
      }

      // Initialize the Directory Server schema elements.
      try {
        directoryServer.initializeSchema();
      } catch (ConfigException | InitializationException e) {
        printWrappedText(err, ERR_CANNOT_LOAD_SCHEMA.get(e.getMessage()));
        return 1;
      } catch (Exception e) {
        printWrappedText(err, ERR_CANNOT_LOAD_SCHEMA.get(getExceptionMessage(e)));
        return 1;
      }

      // Initialize the Directory Server core configuration.
      try {
        CoreConfigManager coreConfigManager =
            new CoreConfigManager(directoryServer.getServerContext());
        coreConfigManager.initializeCoreConfig();
      } catch (ConfigException | InitializationException e) {
        printWrappedText(err, ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(e.getMessage()));
        return 1;
      } catch (Exception e) {
        printWrappedText(err, ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(getExceptionMessage(e)));
        return 1;
      }

      // Initialize the Directory Server crypto manager.
      try {
        directoryServer.initializeCryptoManager();
      } catch (ConfigException | InitializationException e) {
        printWrappedText(err, ERR_CANNOT_INITIALIZE_CRYPTO_MANAGER.get(e.getMessage()));
        return 1;
      } catch (Exception e) {
        printWrappedText(err, ERR_CANNOT_INITIALIZE_CRYPTO_MANAGER.get(getExceptionMessage(e)));
        return 1;
      }

      try {
        ErrorLogPublisher errorLogPublisher =
            TextErrorLogPublisher.getToolStartupTextErrorPublisher(new TextWriter.STREAM(out));
        ErrorLogger.getInstance().addLogPublisher(errorLogPublisher);

        DebugLogger.getInstance().addPublisherIfRequired(new TextWriter.STREAM(out));
      } catch (Exception e) {
        err.println("Error installing the custom error logger: " + stackTraceToSingleLineString(e));
      }

      // Make sure that the Directory Server plugin initialization is performed.
      try {
        HashSet<PluginType> pluginTypes = new HashSet<>(1);
        pluginTypes.add(PluginType.LDIF_EXPORT);
        directoryServer.initializePlugins(pluginTypes);
      } catch (ConfigException | InitializationException e) {
        printWrappedText(err, ERR_LDIFEXPORT_CANNOT_INITIALIZE_PLUGINS.get(e.getMessage()));
        return 1;
      } catch (Exception e) {
        printWrappedText(err, ERR_LDIFEXPORT_CANNOT_INITIALIZE_PLUGINS.get(getExceptionMessage(e)));
        return 1;
      }
    }

    // See if there were any user-defined sets of include/exclude attributes or
    // filters.  If so, then process them.
    Set<AttributeType> excludeAttributes = toAttributeTypes(excludeAttributeStrings);
    Set<AttributeType> includeAttributes = toAttributeTypes(includeAttributeStrings);

    ArrayList<SearchFilter> excludeFilters;
    if (excludeFilterStrings == null) {
      excludeFilters = null;
    } else {
      excludeFilters = new ArrayList<>();
      for (String filterString : excludeFilterStrings.getValues()) {
        try {
          excludeFilters.add(SearchFilter.createFilterFromString(filterString));
        } catch (DirectoryException de) {
          logger.error(
              ERR_LDIFEXPORT_CANNOT_PARSE_EXCLUDE_FILTER, filterString, de.getMessageObject());
          return 1;
        } catch (Exception e) {
          logger.error(
              ERR_LDIFEXPORT_CANNOT_PARSE_EXCLUDE_FILTER, filterString, getExceptionMessage(e));
          return 1;
        }
      }
    }

    ArrayList<SearchFilter> includeFilters;
    if (includeFilterStrings == null) {
      includeFilters = null;
    } else {
      includeFilters = new ArrayList<>();
      for (String filterString : includeFilterStrings.getValues()) {
        try {
          includeFilters.add(SearchFilter.createFilterFromString(filterString));
        } catch (DirectoryException de) {
          logger.error(
              ERR_LDIFEXPORT_CANNOT_PARSE_INCLUDE_FILTER, filterString, de.getMessageObject());
          return 1;
        } catch (Exception e) {
          logger.error(
              ERR_LDIFEXPORT_CANNOT_PARSE_INCLUDE_FILTER, filterString, getExceptionMessage(e));
          return 1;
        }
      }
    }

    // Get information about the backends defined in the server.  Iterate
    // through them, finding the one backend that should be used for the export,
    // and also finding backends with subordinate base DNs that should be
    // excluded from the export.
    Backend backend = null;
    List<DN> baseDNList = null;
    List<DN> defaultIncludeBranches = null;
    ArrayList<DN> excludeBranches = null;

    ArrayList<Backend> backendList = new ArrayList<>();
    ArrayList<BackendCfg> entryList = new ArrayList<>();
    ArrayList<List<DN>> dnList = new ArrayList<>();
    BackendToolUtils.getBackends(backendList, entryList, dnList);

    int numBackends = backendList.size();
    for (int i = 0; i < numBackends; i++) {
      Backend b = backendList.get(i);
      if (!backendID.getValue().equals(b.getBackendID())) {
        continue;
      }

      if (backend == null) {
        backend = b;
        baseDNList = dnList.get(i);
        defaultIncludeBranches = dnList.get(i);
      } else {
        logger.error(ERR_LDIFEXPORT_MULTIPLE_BACKENDS_FOR_ID, backendID.getValue());
        return 1;
      }
    }

    if (backend == null) {
      logger.error(ERR_LDIFEXPORT_NO_BACKENDS_FOR_ID, backendID.getValue());
      return 1;
    } else if (!backend.supports(BackendOperation.RESTORE)) {
      logger.error(ERR_LDIFEXPORT_CANNOT_EXPORT_BACKEND, backendID.getValue());
      return 1;
    }

    if (excludeBranchStrings.isPresent()) {
      excludeBranches = new ArrayList<>();
      for (String s : excludeBranchStrings.getValues()) {
        DN excludeBranch;
        try {
          excludeBranch = DN.valueOf(s);
        } catch (DirectoryException de) {
          logger.error(ERR_LDIFEXPORT_CANNOT_DECODE_EXCLUDE_BASE, s, de.getMessageObject());
          return 1;
        } catch (Exception e) {
          logger.error(ERR_LDIFEXPORT_CANNOT_DECODE_EXCLUDE_BASE, s, getExceptionMessage(e));
          return 1;
        }

        if (!excludeBranches.contains(excludeBranch)) {
          excludeBranches.add(excludeBranch);
        }
      }
    }

    List<DN> includeBranches;
    if (includeBranchStrings.isPresent()) {
      includeBranches = new ArrayList<>();
      for (String s : includeBranchStrings.getValues()) {
        DN includeBranch;
        try {
          includeBranch = DN.valueOf(s);
        } catch (DirectoryException de) {
          logger.error(ERR_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE, s, de.getMessageObject());
          return 1;
        } catch (Exception e) {
          logger.error(ERR_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE, s, getExceptionMessage(e));
          return 1;
        }

        if (!Backend.handlesEntry(includeBranch, defaultIncludeBranches, excludeBranches)) {
          logger.error(ERR_LDIFEXPORT_INVALID_INCLUDE_BASE, s, backendID.getValue());
          return 1;
        }

        includeBranches.add(includeBranch);
      }
    } else {
      includeBranches = defaultIncludeBranches;
    }

    // Create the LDIF export configuration to use when reading the LDIF.
    ExistingFileBehavior existingBehavior;
    if (appendToLDIF.isPresent()) {
      existingBehavior = ExistingFileBehavior.APPEND;
    } else {
      existingBehavior = ExistingFileBehavior.OVERWRITE;
    }

    LDIFExportConfig exportConfig = new LDIFExportConfig(ldifFile.getValue(), existingBehavior);
    exportConfig.setCompressData(compressLDIF.isPresent());
    exportConfig.setEncryptData(encryptLDIF.isPresent());
    exportConfig.setExcludeAttributes(excludeAttributes);
    exportConfig.setExcludeBranches(excludeBranches);
    exportConfig.setExcludeFilters(excludeFilters);
    exportConfig.setIncludeAttributes(includeAttributes);
    exportConfig.setIncludeBranches(includeBranches);
    exportConfig.setIncludeFilters(includeFilters);
    exportConfig.setSignHash(signHash.isPresent());
    exportConfig.setIncludeOperationalAttributes(!excludeOperationalAttrs.isPresent());

    // FIXME -- Should this be conditional?
    exportConfig.setInvokeExportPlugins(true);

    try {
      exportConfig.setWrapColumn(wrapColumn.getIntValue());
    } catch (ArgumentException ae) {
      logger.error(ERR_LDIFEXPORT_CANNOT_DECODE_WRAP_COLUMN_AS_INTEGER, wrapColumn.getValue());
      return 1;
    }

    // Get the set of base DNs for the backend as an array.
    DN[] baseDNs = new DN[baseDNList.size()];
    baseDNList.toArray(baseDNs);

    // Acquire a shared lock for the backend.
    try {
      String lockFile = LockFileManager.getBackendLockFileName(backend);
      StringBuilder failureReason = new StringBuilder();
      if (!LockFileManager.acquireSharedLock(lockFile, failureReason)) {
        logger.error(ERR_LDIFEXPORT_CANNOT_LOCK_BACKEND, backend.getBackendID(), failureReason);
        return 1;
      }
    } catch (Exception e) {
      logger.error(
          ERR_LDIFEXPORT_CANNOT_LOCK_BACKEND, backend.getBackendID(), getExceptionMessage(e));
      return 1;
    }

    boolean errorOccurred = false;

    // Launch the export.
    try {
      backend.exportLDIF(exportConfig);
    } catch (DirectoryException de) {
      logger.error(ERR_LDIFEXPORT_ERROR_DURING_EXPORT, de.getMessageObject());
      errorOccurred = true;
    } catch (Exception e) {
      logger.error(ERR_LDIFEXPORT_ERROR_DURING_EXPORT, getExceptionMessage(e));
      errorOccurred = true;
    }

    // Release the shared lock on the backend.
    try {
      String lockFile = LockFileManager.getBackendLockFileName(backend);
      StringBuilder failureReason = new StringBuilder();
      if (!LockFileManager.releaseLock(lockFile, failureReason)) {
        logger.warn(WARN_LDIFEXPORT_CANNOT_UNLOCK_BACKEND, backend.getBackendID(), failureReason);
      }
    } catch (Exception e) {
      logger.warn(
          WARN_LDIFEXPORT_CANNOT_UNLOCK_BACKEND, backend.getBackendID(), getExceptionMessage(e));
    }

    // Clean up after the export by closing the export config.
    exportConfig.close();
    return !errorOccurred ? 0 : 1;
  }
Exemple #8
0
  private int process(
      String[] args, boolean initializeServer, OutputStream outStream, OutputStream errStream) {

    PrintStream out = NullOutputStream.wrapOrNullStream(outStream);
    PrintStream err = NullOutputStream.wrapOrNullStream(errStream);
    JDKLogging.disableLogging();

    // Create the command-line argument parser for use with this program.
    LDAPConnectionArgumentParser argParser =
        createArgParser(
            "org.opends.server.tools.ExportLDIF", INFO_LDIFEXPORT_TOOL_DESCRIPTION.get());
    argParser.setShortToolDescription(REF_SHORT_DESC_EXPORT_LDIF.get());

    // Initialize all the command-line argument types and register them with the
    // parser.
    try {
      configClass =
          new StringArgument(
              "configclass",
              OPTION_SHORT_CONFIG_CLASS,
              OPTION_LONG_CONFIG_CLASS,
              true,
              false,
              true,
              INFO_CONFIGCLASS_PLACEHOLDER.get(),
              ConfigFileHandler.class.getName(),
              null,
              INFO_DESCRIPTION_CONFIG_CLASS.get());
      configClass.setHidden(true);
      argParser.addArgument(configClass);

      configFile =
          new StringArgument(
              "configfile",
              'f',
              "configFile",
              true,
              false,
              true,
              INFO_CONFIGFILE_PLACEHOLDER.get(),
              null,
              null,
              INFO_DESCRIPTION_CONFIG_FILE.get());
      configFile.setHidden(true);
      argParser.addArgument(configFile);

      ldifFile =
          new StringArgument(
              "ldiffile",
              OPTION_SHORT_LDIF_FILE,
              OPTION_LONG_LDIF_FILE,
              true,
              false,
              true,
              INFO_LDIFFILE_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_LDIF_FILE.get());
      argParser.addArgument(ldifFile);

      appendToLDIF =
          new BooleanArgument(
              "appendldif", 'a', "appendToLDIF", INFO_LDIFEXPORT_DESCRIPTION_APPEND_TO_LDIF.get());
      argParser.addArgument(appendToLDIF);

      backendID =
          new StringArgument(
              "backendid",
              'n',
              "backendID",
              true,
              false,
              true,
              INFO_BACKENDNAME_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_BACKEND_ID.get());
      argParser.addArgument(backendID);

      includeBranchStrings =
          new StringArgument(
              "includebranch",
              'b',
              "includeBranch",
              false,
              true,
              true,
              INFO_BRANCH_DN_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_INCLUDE_BRANCH.get());
      argParser.addArgument(includeBranchStrings);

      excludeBranchStrings =
          new StringArgument(
              "excludebranch",
              'B',
              "excludeBranch",
              false,
              true,
              true,
              INFO_BRANCH_DN_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_BRANCH.get());
      argParser.addArgument(excludeBranchStrings);

      includeAttributeStrings =
          new StringArgument(
              "includeattribute",
              'i',
              "includeAttribute",
              false,
              true,
              true,
              INFO_ATTRIBUTE_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_INCLUDE_ATTRIBUTE.get());
      argParser.addArgument(includeAttributeStrings);

      excludeAttributeStrings =
          new StringArgument(
              "excludeattribute",
              'e',
              "excludeAttribute",
              false,
              true,
              true,
              INFO_ATTRIBUTE_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_ATTRIBUTE.get());
      argParser.addArgument(excludeAttributeStrings);

      includeFilterStrings =
          new StringArgument(
              "includefilter",
              'I',
              "includeFilter",
              false,
              true,
              true,
              INFO_FILTER_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_INCLUDE_FILTER.get());
      argParser.addArgument(includeFilterStrings);

      excludeFilterStrings =
          new StringArgument(
              "excludefilter",
              'E',
              "excludeFilter",
              false,
              true,
              true,
              INFO_FILTER_PLACEHOLDER.get(),
              null,
              null,
              INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_FILTER.get());
      argParser.addArgument(excludeFilterStrings);

      excludeOperationalAttrs =
          new BooleanArgument(
              "excludeoperational",
              'O',
              "excludeOperational",
              INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_OPERATIONAL.get());
      argParser.addArgument(excludeOperationalAttrs);

      wrapColumn =
          new IntegerArgument(
              "wrapcolumn",
              null,
              "wrapColumn",
              false,
              false,
              true,
              INFO_WRAP_COLUMN_PLACEHOLDER.get(),
              0,
              null,
              true,
              0,
              false,
              0,
              INFO_LDIFEXPORT_DESCRIPTION_WRAP_COLUMN.get());
      argParser.addArgument(wrapColumn);

      compressLDIF =
          new BooleanArgument(
              "compressldif",
              OPTION_SHORT_COMPRESS,
              OPTION_LONG_COMPRESS,
              INFO_LDIFEXPORT_DESCRIPTION_COMPRESS_LDIF.get());
      argParser.addArgument(compressLDIF);

      encryptLDIF =
          new BooleanArgument(
              "encryptldif", 'y', "encryptLDIF", INFO_LDIFEXPORT_DESCRIPTION_ENCRYPT_LDIF.get());
      encryptLDIF.setHidden(true); // See issue #27
      argParser.addArgument(encryptLDIF);

      signHash =
          new BooleanArgument(
              "signhash", 's', "signHash", INFO_LDIFEXPORT_DESCRIPTION_SIGN_HASH.get());
      signHash.setHidden(true); // See issue #28
      argParser.addArgument(signHash);

      displayUsage = CommonArguments.getShowUsage();
      argParser.addArgument(displayUsage);
      argParser.setUsageArgument(displayUsage);
    } catch (ArgumentException ae) {
      printWrappedText(err, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()));
      return 1;
    }

    // Init the default values so that they can appear also on the usage.
    try {
      argParser.getArguments().initArgumentsWithConfiguration();
    } catch (ConfigException ce) {
      // Ignore.
    }

    // Parse the command-line arguments provided to this program.
    try {
      argParser.parseArguments(args);
      validateTaskArgs();
    } catch (ArgumentException ae) {
      printWrappedText(err, ERR_ERROR_PARSING_ARGS.get(ae.getMessage()));
      err.println(argParser.getUsage());
      return 1;
    } catch (ClientException ce) {
      // No need to display the usage since the problem comes with a provided value.
      printWrappedText(err, ce.getMessageObject());
      return 1;
    }

    // If we should just display usage or version information,
    // then print it and exit.
    if (argParser.usageOrVersionDisplayed()) {
      return 0;
    }

    // Checks the version - if upgrade required, the tool is unusable
    try {
      checkVersion();
    } catch (InitializationException e) {
      printWrappedText(err, e.getMessage());
      return 1;
    }

    return process(argParser, initializeServer, out, err);
  }