001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.tools;
018
019import static com.forgerock.opendj.cli.CliMessages.INFO_JMXPORT_PLACEHOLDER;
020import static com.forgerock.opendj.cli.CliMessages.INFO_KEYSTORE_PWD_FILE_PLACEHOLDER;
021import static com.forgerock.opendj.cli.CliMessages.INFO_NUM_ENTRIES_PLACEHOLDER;
022import static com.forgerock.opendj.cli.CliMessages.INFO_PORT_PLACEHOLDER;
023import static com.forgerock.opendj.cli.CliMessages.INFO_ROOT_USER_PWD_FILE_PLACEHOLDER;
024import static com.forgerock.opendj.cli.Utils.addErrorMessageIfArgumentsConflict;
025import static org.opends.messages.ToolMessages.*;
026
027import static com.forgerock.opendj.cli.ArgumentConstants.*;
028import static com.forgerock.opendj.util.OperatingSystem.*;
029import static com.forgerock.opendj.cli.CommonArguments.*;
030
031import java.util.Collection;
032import java.util.HashSet;
033import java.util.LinkedHashSet;
034import java.util.Set;
035
036import org.forgerock.i18n.LocalizableMessage;
037import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1;
038import org.forgerock.i18n.slf4j.LocalizedLogger;
039import org.opends.quicksetup.Constants;
040import org.opends.quicksetup.Installation;
041import org.opends.quicksetup.UserData;
042import org.opends.quicksetup.util.Utils;
043import org.opends.server.admin.AdministrationConnector;
044import org.opends.server.core.DirectoryServer.DirectoryServerVersionHandler;
045
046import com.forgerock.opendj.cli.Argument;
047import com.forgerock.opendj.cli.ArgumentException;
048import com.forgerock.opendj.cli.ArgumentParser;
049import com.forgerock.opendj.cli.BooleanArgument;
050import com.forgerock.opendj.cli.CliConstants;
051import com.forgerock.opendj.cli.FileBasedArgument;
052import com.forgerock.opendj.cli.IntegerArgument;
053import com.forgerock.opendj.cli.StringArgument;
054
055/**
056 * Class used to parse the arguments of the setup command-line and to check
057 * that there are not conflicting arguments (nor missing arguments in no prompt
058 * mode).
059 * Note that this class does not perform checks involving network (like if
060 * a given port is free) nor the validity of the certificate information
061 * provided.
062 */
063public class InstallDSArgumentParser extends ArgumentParser
064{
065  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
066
067  BooleanArgument   testOnlyArg;
068  BooleanArgument   cliArg;
069  BooleanArgument   addBaseEntryArg;
070  BooleanArgument   showUsageArg;
071  BooleanArgument   quietArg;
072  BooleanArgument   noPromptArg;
073  BooleanArgument   verboseArg;
074  StringArgument    propertiesFileArgument;
075  BooleanArgument   noPropertiesFileArgument;
076  BooleanArgument   skipPortCheckArg;
077  BooleanArgument   enableWindowsServiceArg;
078  BooleanArgument   doNotStartArg;
079  BooleanArgument   enableStartTLSArg;
080  BooleanArgument   generateSelfSignedCertificateArg;
081  StringArgument    hostNameArg;
082  BooleanArgument   usePkcs11Arg;
083  FileBasedArgument directoryManagerPwdFileArg;
084  FileBasedArgument keyStorePasswordFileArg;
085  IntegerArgument   ldapPortArg;
086  IntegerArgument   adminConnectorPortArg;
087  IntegerArgument   ldapsPortArg;
088  IntegerArgument   jmxPortArg;
089  IntegerArgument   sampleDataArg;
090  StringArgument    baseDNArg;
091  StringArgument    importLDIFArg;
092  StringArgument    rejectedImportFileArg;
093  StringArgument    skippedImportFileArg;
094  StringArgument    directoryManagerDNArg;
095  StringArgument    directoryManagerPwdStringArg;
096  StringArgument    useJavaKeyStoreArg;
097  StringArgument    useJCEKSArg;
098  StringArgument    usePkcs12Arg;
099  StringArgument    keyStorePasswordArg;
100  StringArgument    certNicknameArg;
101  StringArgument    progNameArg;
102  IntegerArgument   connectTimeoutArg;
103  BooleanArgument   acceptLicense;
104  StringArgument    backendTypeArg;
105
106  /**
107   * The default constructor for this class.
108   * @param mainClassName the class name of the main class for the command-line
109   * that is being used.
110   */
111  public InstallDSArgumentParser(String mainClassName)
112  {
113    super(mainClassName, INFO_INSTALLDS_TOOL_DESCRIPTION.get(), false);
114    setShortToolDescription(REF_SHORT_DESC_SETUP.get());
115    setVersionHandler(new DirectoryServerVersionHandler());
116  }
117
118  /**
119   * Initializes the arguments without parsing them.
120   * @throws ArgumentException if there was an error creating or adding the
121   * arguments.  If this occurs is likely to be a bug.
122   */
123  public void initializeArguments() throws ArgumentException
124  {
125    testOnlyArg =
126            BooleanArgument.builder(OPTION_LONG_TESTONLY_ARGUMENT)
127                    .description(INFO_ARGUMENT_DESCRIPTION_TESTONLY.get())
128                    .hidden()
129                    .buildArgument();
130    addArgument(testOnlyArg);
131
132    cliArg = cliArgument();
133    addArgument(cliArg);
134
135    progNameArg = StringArgument.builder("programName")
136            .shortIdentifier('P')
137            .description(INFO_INSTALLDS_DESCRIPTION_PROGNAME.get())
138            .hidden()
139            .defaultValue(Installation.getSetupFileName())
140            .valuePlaceholder(INFO_PROGRAM_NAME_PLACEHOLDER.get())
141            .buildArgument();
142    addArgument(progNameArg);
143
144    noPromptArg = noPromptArgument();
145    addArgument(noPromptArg);
146
147    quietArg = quietArgument();
148    addArgument(quietArg);
149
150    verboseArg = verboseArgument();
151    addArgument(verboseArg);
152
153    propertiesFileArgument =
154            StringArgument.builder(OPTION_LONG_PROP_FILE_PATH)
155                    .description(INFO_DESCRIPTION_PROP_FILE_PATH.get())
156                    .valuePlaceholder(INFO_PROP_FILE_PATH_PLACEHOLDER.get())
157                    .buildArgument();
158    addArgument(propertiesFileArgument);
159    setFilePropertiesArgument(propertiesFileArgument);
160
161    noPropertiesFileArgument =
162            BooleanArgument.builder(OPTION_LONG_NO_PROP_FILE)
163                    .description(INFO_DESCRIPTION_NO_PROP_FILE.get())
164                    .buildArgument();
165    addArgument(noPropertiesFileArgument);
166    setNoPropertiesFileArgument(noPropertiesFileArgument);
167
168    baseDNArg =
169            StringArgument.builder(OPTION_LONG_BASEDN)
170                    .shortIdentifier(OPTION_SHORT_BASEDN)
171                    .description(INFO_INSTALLDS_DESCRIPTION_BASEDN.get())
172                    .multiValued()
173                    .valuePlaceholder(INFO_BASEDN_PLACEHOLDER.get())
174                    .buildArgument();
175    addArgument(baseDNArg);
176
177    addBaseEntryArg =
178            BooleanArgument.builder("addBaseEntry")
179                    .shortIdentifier('a')
180                    .description(INFO_INSTALLDS_DESCRIPTION_ADDBASE.get())
181                    .buildArgument();
182    addArgument(addBaseEntryArg);
183
184    importLDIFArg =
185            StringArgument.builder(OPTION_LONG_LDIF_FILE)
186                    .shortIdentifier(OPTION_SHORT_LDIF_FILE)
187                    .description(INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get())
188                    .multiValued()
189                    .valuePlaceholder(INFO_LDIFFILE_PLACEHOLDER.get())
190                    .buildArgument();
191    addArgument(importLDIFArg);
192
193    rejectedImportFileArg =
194            StringArgument.builder("rejectFile")
195                    .shortIdentifier('R')
196                    .description(INFO_INSTALLDS_DESCRIPTION_REJECTED_FILE.get())
197                    .valuePlaceholder(INFO_REJECT_FILE_PLACEHOLDER.get())
198                    .buildArgument();
199    addArgument(rejectedImportFileArg);
200
201    skippedImportFileArg =
202            StringArgument.builder("skipFile")
203                    .description(INFO_INSTALLDS_DESCRIPTION_SKIPPED_FILE.get())
204                    .valuePlaceholder(INFO_SKIP_FILE_PLACEHOLDER.get())
205                    .buildArgument();
206    addArgument(skippedImportFileArg);
207
208    sampleDataArg =
209            IntegerArgument.builder("sampleData")
210                    .shortIdentifier('d')
211                    .description(INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get())
212                    .lowerBound(0)
213                    .defaultValue(0)
214                    .valuePlaceholder(INFO_NUM_ENTRIES_PLACEHOLDER.get())
215                    .buildArgument();
216    addArgument(sampleDataArg);
217
218    int defaultLdapPort = UserData.getDefaultPort();
219    if (defaultLdapPort == -1)
220    {
221      defaultLdapPort = 389;
222    }
223
224    ldapPortArg =
225            IntegerArgument.builder("ldapPort")
226                    .shortIdentifier(OPTION_SHORT_PORT)
227                    .description(INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get())
228                    .range(1, 65535)
229                    .defaultValue(defaultLdapPort)
230                    .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
231                    .buildArgument();
232    addArgument(ldapPortArg);
233
234    int defaultAdminPort = UserData.getDefaultAdminConnectorPort();
235    if (defaultAdminPort == -1)
236    {
237      defaultAdminPort =
238        AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT;
239    }
240
241    adminConnectorPortArg =
242            IntegerArgument.builder("adminConnectorPort")
243                    .description(INFO_INSTALLDS_DESCRIPTION_ADMINCONNECTORPORT.get())
244                    .range(1, 65535)
245                    .defaultValue(defaultAdminPort)
246                    .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
247                    .buildArgument();
248    addArgument(adminConnectorPortArg);
249
250    jmxPortArg =
251            IntegerArgument.builder("jmxPort")
252                    .shortIdentifier('x')
253                    .description(INFO_INSTALLDS_DESCRIPTION_JMXPORT.get())
254                    .range(1, 65535)
255                    .defaultValue(CliConstants.DEFAULT_JMX_PORT)
256                    .valuePlaceholder(INFO_JMXPORT_PLACEHOLDER.get())
257                    .buildArgument();
258    addArgument(jmxPortArg);
259
260    skipPortCheckArg =
261            BooleanArgument.builder("skipPortCheck")
262                    .shortIdentifier('S')
263                    .description(INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get())
264                    .buildArgument();
265    addArgument(skipPortCheckArg);
266
267    directoryManagerDNArg =
268            StringArgument.builder(OPTION_LONG_ROOT_USER_DN)
269                    .shortIdentifier(OPTION_SHORT_ROOT_USER_DN)
270                    .description(INFO_INSTALLDS_DESCRIPTION_ROOTDN.get())
271                    .defaultValue("cn=Directory Manager")
272                    .valuePlaceholder(INFO_ROOT_USER_DN_PLACEHOLDER.get())
273                    .buildArgument();
274    addArgument(directoryManagerDNArg);
275
276    directoryManagerPwdStringArg =
277            StringArgument.builder("rootUserPassword")
278                    .shortIdentifier(OPTION_SHORT_BINDPWD)
279                    .description(INFO_INSTALLDS_DESCRIPTION_ROOTPW.get())
280                    .valuePlaceholder(INFO_ROOT_USER_PWD_PLACEHOLDER.get())
281                    .buildArgument();
282    addArgument(directoryManagerPwdStringArg);
283
284    directoryManagerPwdFileArg =
285            FileBasedArgument.builder("rootUserPasswordFile")
286                    .shortIdentifier(OPTION_SHORT_BINDPWD_FILE)
287                    .description(INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get())
288                    .valuePlaceholder(INFO_ROOT_USER_PWD_FILE_PLACEHOLDER.get())
289                    .buildArgument();
290    addArgument(directoryManagerPwdFileArg);
291
292    enableWindowsServiceArg =
293            BooleanArgument.builder("enableWindowsService")
294                    .shortIdentifier('e')
295                    .description(INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get())
296                    .buildArgument();
297    if (isWindows())
298    {
299      addArgument(enableWindowsServiceArg);
300    }
301
302    doNotStartArg =
303            BooleanArgument.builder("doNotStart")
304                    .shortIdentifier('O')
305                    .description(INFO_INSTALLDS_DESCRIPTION_DO_NOT_START.get())
306                    .buildArgument();
307    addArgument(doNotStartArg);
308
309    enableStartTLSArg =
310            BooleanArgument.builder("enableStartTLS")
311                    .shortIdentifier(OPTION_SHORT_START_TLS)
312                    .description(INFO_INSTALLDS_DESCRIPTION_ENABLE_STARTTLS.get())
313                    .buildArgument();
314    addArgument(enableStartTLSArg);
315
316    int defaultSecurePort = UserData.getDefaultSslPort(defaultLdapPort);
317    if (defaultSecurePort == -1)
318    {
319      defaultSecurePort = 636;
320    }
321
322    ldapsPortArg =
323            IntegerArgument.builder("ldapsPort")
324                    .shortIdentifier(OPTION_SHORT_USE_SSL)
325                    .description(INFO_INSTALLDS_DESCRIPTION_LDAPSPORT.get())
326                    .range(1, 65535)
327                    .defaultValue(defaultSecurePort)
328                    .valuePlaceholder(INFO_PORT_PLACEHOLDER.get())
329                    .buildArgument();
330    addArgument(ldapsPortArg);
331
332    generateSelfSignedCertificateArg =
333            BooleanArgument.builder("generateSelfSignedCertificate")
334                    .description(INFO_INSTALLDS_DESCRIPTION_USE_SELF_SIGNED.get())
335                    .buildArgument();
336    addArgument(generateSelfSignedCertificateArg);
337
338    hostNameArg =
339            StringArgument.builder(OPTION_LONG_HOST)
340                    .shortIdentifier(OPTION_SHORT_HOST)
341                    .description(INFO_INSTALLDS_DESCRIPTION_HOST_NAME.get())
342                    .defaultValue(UserData.getDefaultHostName())
343                    .valuePlaceholder(INFO_HOST_PLACEHOLDER.get())
344                    .buildArgument();
345    addDefaultArgument(hostNameArg);
346
347    usePkcs11Arg =
348            BooleanArgument.builder("usePkcs11Keystore")
349                    .description(INFO_INSTALLDS_DESCRIPTION_USE_PKCS11.get())
350                    .buildArgument();
351    addArgument(usePkcs11Arg);
352
353    useJavaKeyStoreArg =
354            StringArgument.builder("useJavaKeystore")
355                    .description(INFO_INSTALLDS_DESCRIPTION_USE_JAVAKEYSTORE.get())
356                    .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
357                    .buildArgument();
358    addArgument(useJavaKeyStoreArg);
359
360    useJCEKSArg =
361            StringArgument.builder("useJCEKS")
362                    .description(INFO_INSTALLDS_DESCRIPTION_USE_JCEKS.get())
363                    .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
364                    .buildArgument();
365    addArgument(useJCEKSArg);
366
367    usePkcs12Arg =
368            StringArgument.builder("usePkcs12keyStore")
369                    .description(INFO_INSTALLDS_DESCRIPTION_USE_PKCS12.get())
370                    .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get())
371                    .buildArgument();
372    addArgument(usePkcs12Arg);
373
374    keyStorePasswordArg =
375            StringArgument.builder(OPTION_LONG_KEYSTORE_PWD)
376                    .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD)
377                    .description(INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD.get())
378                    .valuePlaceholder(INFO_KEYSTORE_PWD_PLACEHOLDER.get())
379                    .buildArgument();
380    addDefaultArgument(keyStorePasswordArg);
381
382    keyStorePasswordFileArg =
383            FileBasedArgument.builder(OPTION_LONG_KEYSTORE_PWD_FILE)
384                    .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD_FILE)
385                    .description(INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_FILE.get())
386                    .valuePlaceholder(INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get())
387                    .buildArgument();
388    addDefaultArgument(keyStorePasswordFileArg);
389
390    certNicknameArg =
391            StringArgument.builder(OPTION_LONG_CERT_NICKNAME)
392                    .shortIdentifier(OPTION_SHORT_CERT_NICKNAME)
393                    .description(INFO_INSTALLDS_DESCRIPTION_CERT_NICKNAME.get())
394                    .multiValued()
395                    .valuePlaceholder(INFO_NICKNAME_PLACEHOLDER.get())
396                    .buildArgument();
397    addDefaultArgument(certNicknameArg);
398
399    connectTimeoutArg = connectTimeOutHiddenArgument();
400    addArgument(connectTimeoutArg);
401
402    acceptLicense = acceptLicenseArgument();
403    addArgument(acceptLicense);
404
405    showUsageArg = showUsageArgument();
406    addArgument(showUsageArg);
407    setUsageArgument(showUsageArg);
408
409    backendTypeArg =
410            StringArgument.builder(OPTION_LONG_BACKEND_TYPE)
411                    .shortIdentifier(OPTION_SHORT_BACKEND_TYPE)
412                    .description(INFO_INSTALLDS_DESCRIPTION_BACKEND_TYPE.get())
413                    .defaultValue(BackendTypeHelper.filterSchemaBackendName(
414                            new BackendTypeHelper().getBackendTypes().get(0).getName()))
415                    .valuePlaceholder(INFO_INSTALLDS_BACKEND_TYPE_PLACEHOLDER.get())
416                    .buildArgument();
417    addArgument(backendTypeArg);
418  }
419
420  /**
421   * Returns whether the command was launched in CLI mode or not.
422   * @return <CODE>true</CODE> if the command was launched to use CLI mode and
423   * <CODE>false</CODE> otherwise.
424   */
425  public boolean isCli()
426  {
427    return cliArg.isPresent();
428  }
429
430  /** {@inheritDoc} */
431  @Override
432  public void parseArguments(String[] args) throws ArgumentException
433  {
434    LinkedHashSet<LocalizableMessage> errorMessages = new LinkedHashSet<>();
435    try
436    {
437      super.parseArguments(args);
438    }
439    catch (ArgumentException ae)
440    {
441      logger.error(LocalizableMessage.raw("Error parsing arguments: "+ae, ae));
442      errorMessages.add(ae.getMessageObject());
443    }
444
445    if (!isUsageArgumentPresent() && !isVersionArgumentPresent())
446    {
447      checkServerPassword(errorMessages);
448      checkProvidedPorts(errorMessages);
449      checkImportDataArguments(errorMessages);
450      checkSecurityArguments(errorMessages);
451
452      if (!errorMessages.isEmpty())
453      {
454        throw new ArgumentException(ERR_CANNOT_INITIALIZE_ARGS.get(
455            Utils.getMessageFromCollection(errorMessages, Constants.LINE_SEPARATOR)));
456      }
457    }
458  }
459
460  /**
461   * Returns the directory manager password provided by the user.  This method
462   * should be called after a call to parseArguments.
463   * @return the directory manager password provided by the user.
464   */
465  public String getDirectoryManagerPassword()
466  {
467    if (directoryManagerPwdStringArg.isPresent())
468    {
469      return directoryManagerPwdStringArg.getValue();
470    }
471    else if (directoryManagerPwdFileArg.isPresent())
472    {
473      return directoryManagerPwdFileArg.getValue();
474    }
475    return null;
476  }
477
478  /**
479   * Returns the key store password provided by the user.  This method should be
480   * called after a call to parseArguments.
481   * @return the key store password provided by the user.
482   */
483  public String getKeyStorePassword()
484  {
485    if (keyStorePasswordArg.isPresent())
486    {
487      return keyStorePasswordArg.getValue();
488    }
489    else if (keyStorePasswordFileArg.isPresent())
490    {
491      return keyStorePasswordFileArg.getValue();
492    }
493    return null;
494  }
495
496  /**
497   * Checks that there are no conflicts with the directory manager passwords.
498   * If we are in no prompt mode, check that the password was provided.
499   * @param errorMessages the list of messages to which we add the error
500   * messages describing the problems encountered during the execution of the
501   * checking.
502   */
503  private void checkServerPassword(Collection<LocalizableMessage> errorMessages)
504  {
505    addErrorMessageIfArgumentsConflict(errorMessages, directoryManagerPwdStringArg, directoryManagerPwdFileArg);
506
507    if (noPromptArg.isPresent() && !directoryManagerPwdStringArg.isPresent() &&
508        !directoryManagerPwdFileArg.isPresent())
509    {
510      errorMessages.add(ERR_INSTALLDS_NO_ROOT_PASSWORD.get(
511          directoryManagerPwdStringArg.getLongIdentifier(),
512          directoryManagerPwdFileArg.getLongIdentifier()));
513    }
514  }
515
516  /**
517   * Checks that there are no conflicts with the provided ports (like if the
518   * user provided the same port for different protocols).
519   * @param errorMessages the list of messages to which we add the error
520   * messages describing the problems encountered during the execution of the
521   * checking.
522   */
523  private void checkProvidedPorts(Collection<LocalizableMessage> errorMessages)
524  {
525    try
526    {
527      Set<Integer> ports = new HashSet<>();
528      ports.add(ldapPortArg.getIntValue());
529
530      checkPortAlreadyUsed(ports, adminConnectorPortArg.getIntValue(), errorMessages,
531          ERR_CONFIGDS_PORT_ALREADY_SPECIFIED);
532      if (jmxPortArg.isPresent())
533      {
534        checkPortAlreadyUsed(ports, jmxPortArg.getIntValue(), errorMessages, ERR_CONFIGDS_PORT_ALREADY_SPECIFIED);
535      }
536      if (ldapsPortArg.isPresent())
537      {
538        checkPortAlreadyUsed(ports, ldapsPortArg.getIntValue(), errorMessages, ERR_CONFIGDS_PORT_ALREADY_SPECIFIED);
539      }
540    }
541    catch (ArgumentException ae)
542    {
543      logger.error(LocalizableMessage.raw("Unexpected error.  "+
544          "Assuming that it is caused by a previous parsing issue: "+ae, ae));
545    }
546  }
547
548  private void checkPortAlreadyUsed(Set<Integer> ports, int port, Collection<LocalizableMessage> errorMessages,
549      Arg1<Object> errorMsg)
550  {
551    if (ports.contains(port))
552    {
553      errorMessages.add(errorMsg.get(port));
554    }
555    else
556    {
557      ports.add(port);
558    }
559  }
560
561  /**
562   * Checks that there are no conflicts with the import data arguments.
563   *
564   * @param errorMessages
565   *          the list of messages to which we add the error messages describing
566   *          the problems encountered during the execution of the checking.
567   */
568  private void checkImportDataArguments(Collection<LocalizableMessage> errorMessages)
569  {
570    //  Make sure that the user didn't provide conflicting arguments.
571    addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, importLDIFArg);
572    addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, sampleDataArg);
573    addErrorMessageIfArgumentsConflict(errorMessages, importLDIFArg, sampleDataArg);
574    addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, rejectedImportFileArg);
575    addErrorMessageIfArgumentsConflict(errorMessages, rejectedImportFileArg, sampleDataArg);
576    addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, skippedImportFileArg);
577    addErrorMessageIfArgumentsConflict(errorMessages, skippedImportFileArg, sampleDataArg);
578
579    final boolean noBaseDNProvided = !baseDNArg.isPresent() && baseDNArg.getDefaultValue() == null;
580    if (noPromptArg.isPresent() && noBaseDNProvided)
581    {
582      final Argument[] args = {importLDIFArg, addBaseEntryArg, sampleDataArg, backendTypeArg};
583      for (Argument arg : args)
584      {
585        if (arg.isPresent())
586        {
587          errorMessages.add(ERR_INSTALLDS_NO_BASE_DN_AND_CONFLICTING_ARG.get("--" + arg.getLongIdentifier()));
588        }
589      }
590    }
591  }
592
593  /**
594   * Checks that there are no conflicts with the security arguments.
595   * If we are in no prompt mode, check that all the information required has
596   * been provided (but not if this information is valid: we do not try to
597   * open the keystores or to check that the LDAPS port is in use).
598   * @param errorMessages the list of messages to which we add the error
599   * messages describing the problems encountered during the execution of the
600   * checking.
601   */
602  private void checkSecurityArguments(Collection<LocalizableMessage> errorMessages)
603  {
604    boolean certificateRequired = ldapsPortArg.isPresent() || enableStartTLSArg.isPresent();
605
606    int certificateType = 0;
607    if (generateSelfSignedCertificateArg.isPresent())
608    {
609      certificateType++;
610    }
611    if (useJavaKeyStoreArg.isPresent())
612    {
613      certificateType++;
614    }
615    if (useJCEKSArg.isPresent())
616    {
617      certificateType++;
618    }
619    if (usePkcs11Arg.isPresent())
620    {
621      certificateType++;
622    }
623    if (usePkcs12Arg.isPresent())
624    {
625      certificateType++;
626    }
627
628    if (certificateType > 1)
629    {
630      errorMessages.add(ERR_INSTALLDS_SEVERAL_CERTIFICATE_TYPE_SPECIFIED.get());
631    }
632
633    if (certificateRequired && noPromptArg.isPresent() && certificateType == 0)
634    {
635      errorMessages.add(
636          ERR_INSTALLDS_CERTIFICATE_REQUIRED_FOR_SSL_OR_STARTTLS.get());
637    }
638
639    if (certificateType == 1)
640    {
641      if (!generateSelfSignedCertificateArg.isPresent())
642      {
643        addErrorMessageIfArgumentsConflict(errorMessages, keyStorePasswordArg, keyStorePasswordFileArg);
644
645        // Check that we have one password in no prompt mode.
646        if (noPromptArg.isPresent() && !keyStorePasswordArg.isPresent() &&
647            !keyStorePasswordFileArg.isPresent())
648        {
649          errorMessages.add(ERR_INSTALLDS_NO_KEYSTORE_PASSWORD.get(
650              keyStorePasswordArg.getLongIdentifier(),
651              keyStorePasswordFileArg.getLongIdentifier()));
652        }
653      }
654      if (noPromptArg.isPresent() && !ldapsPortArg.isPresent() &&
655          !enableStartTLSArg.isPresent())
656      {
657        errorMessages.add(ERR_INSTALLDS_SSL_OR_STARTTLS_REQUIRED.get(
658            ldapsPortArg.getLongIdentifier(),
659            enableStartTLSArg.getLongIdentifier()));
660      }
661    }
662  }
663
664  /**
665   * Returns the timeout to be used to connect in milliseconds.  The method
666   * must be called after parsing the arguments.
667   * @return the timeout to be used to connect in milliseconds.  Returns
668   * {@code 0} if there is no timeout.
669   * @throws IllegalStateException if the method is called before
670   * parsing the arguments.
671   */
672  public int getConnectTimeout() throws IllegalStateException
673  {
674    try
675    {
676      return connectTimeoutArg.getIntValue();
677    }
678    catch (ArgumentException ae)
679    {
680      throw new IllegalStateException("Argument parser is not parsed: "+ae, ae);
681    }
682  }
683}