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