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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS.
026 */
027package org.opends.guitools.uninstaller;
028
029import static com.forgerock.opendj.cli.ArgumentConstants.*;
030import static com.forgerock.opendj.cli.CliMessages.*;
031import static com.forgerock.opendj.cli.Utils.*;
032
033import java.io.OutputStream;
034import java.util.ArrayList;
035import java.util.LinkedHashSet;
036
037import org.forgerock.i18n.LocalizableMessage;
038import org.forgerock.i18n.LocalizableMessageBuilder;
039import org.opends.quicksetup.UserData;
040import org.opends.server.admin.client.cli.SecureConnectionCliArgs;
041import org.opends.server.admin.client.cli.SecureConnectionCliParser;
042import org.opends.server.core.DirectoryServer.DirectoryServerVersionHandler;
043
044import com.forgerock.opendj.cli.Argument;
045import com.forgerock.opendj.cli.ArgumentException;
046import com.forgerock.opendj.cli.BooleanArgument;
047import com.forgerock.opendj.cli.CommonArguments;
048import com.forgerock.opendj.cli.ReturnCode;
049import com.forgerock.opendj.cli.StringArgument;
050
051/** Class used to parse and populate the arguments of the Uninstaller. */
052public class UninstallerArgumentParser extends SecureConnectionCliParser
053{
054  private BooleanArgument cliArg;
055  private BooleanArgument noPromptArg;
056  BooleanArgument forceOnErrorArg;
057  private BooleanArgument quietArg;
058  private BooleanArgument removeAllArg;
059  private BooleanArgument removeServerLibrariesArg;
060  private BooleanArgument removeDatabasesArg;
061  private BooleanArgument removeLogFilesArg;
062  private BooleanArgument removeConfigurationFilesArg;
063  private BooleanArgument removeBackupFilesArg;
064  private BooleanArgument removeLDIFFilesArg;
065
066  private StringArgument referencedHostNameArg;
067
068  /** This CLI is always using the administration connector with SSL. */
069  private final boolean alwaysSSL = true;
070
071  /**
072   * Creates a new instance of this argument parser with no arguments.
073   *
074   * @param mainClassName
075   *          The fully-qualified name of the Java class that should
076   *          be invoked to launch the program with which this
077   *          argument parser is associated.
078   * @param toolDescription
079   *          A human-readable description for the tool, which will be
080   *          included when displaying usage information.
081   * @param longArgumentsCaseSensitive
082   *          Indicates whether subcommand and long argument names
083   *          should be treated in a case-sensitive manner.
084   */
085  public UninstallerArgumentParser(String mainClassName,
086      LocalizableMessage toolDescription, boolean longArgumentsCaseSensitive)
087  {
088    super(mainClassName, toolDescription, longArgumentsCaseSensitive);
089    setShortToolDescription(REF_SHORT_DESC_UNINSTALL.get());
090    setVersionHandler(new DirectoryServerVersionHandler());
091  }
092
093  /**
094   * Initialize Global option.
095   *
096   * @param outStream
097   *          The output stream used for the usage.
098   * @throws ArgumentException
099   *           If there is a problem with any of the parameters used
100   *           to create this argument.
101   */
102  public void initializeGlobalArguments(OutputStream outStream)
103  throws ArgumentException
104  {
105    LinkedHashSet<Argument> args = new LinkedHashSet<>();
106    cliArg = CommonArguments.getCLI();
107    args.add(cliArg);
108
109    removeAllArg = new BooleanArgument(
110        "remove-all",
111        'a',
112        "remove-all",
113        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_ALL.get()
114        );
115    args.add(removeAllArg);
116    removeServerLibrariesArg = new BooleanArgument(
117        "server-libraries",
118        'l',
119        "server-libraries",
120        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_SERVER_LIBRARIES.get()
121        );
122    args.add(removeServerLibrariesArg);
123    removeDatabasesArg = new BooleanArgument(
124        "databases",
125        'd',
126        "databases",
127        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_DATABASES.get()
128        );
129    args.add(removeDatabasesArg);
130    removeLogFilesArg = new BooleanArgument(
131        "log-files",
132        'L',
133        "log-files",
134        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_LOG_FILES.get()
135        );
136    args.add(removeLogFilesArg);
137    removeConfigurationFilesArg = new BooleanArgument(
138        "configuration-files",
139        'c',
140        "configuration-files",
141        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_CONFIGURATION_FILES.get()
142        );
143    args.add(removeConfigurationFilesArg);
144    removeBackupFilesArg = new BooleanArgument(
145        "backup-files",
146        'b',
147        "backup-files",
148        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_BACKUP_FILES.get()
149        );
150    args.add(removeBackupFilesArg);
151    removeLDIFFilesArg = new BooleanArgument(
152        "ldif-files",
153        'e',
154        "ldif-files",
155        INFO_UNINSTALLDS_DESCRIPTION_REMOVE_LDIF_FILES.get()
156        );
157    args.add(removeLDIFFilesArg);
158
159    noPromptArg = CommonArguments.getNoPrompt();
160    args.add(noPromptArg);
161
162    forceOnErrorArg = new BooleanArgument(
163        "forceOnError",
164        'f',
165        "forceOnError",
166        INFO_UNINSTALLDS_DESCRIPTION_FORCE.get(
167            "--"+noPromptArg.getLongIdentifier()));
168    args.add(forceOnErrorArg);
169
170    quietArg = CommonArguments.getQuiet();
171    args.add(quietArg);
172
173    for (Argument arg : args)
174    {
175      arg.setPropertyName(arg.getLongIdentifier());
176    }
177
178    ArrayList<Argument> defaultArgs = new ArrayList<>(createGlobalArguments(outStream, alwaysSSL));
179    int index = defaultArgs.indexOf(secureArgsList.bindDnArg);
180    if (index != -1)
181    {
182      defaultArgs.add(index, secureArgsList.adminUidArg);
183      defaultArgs.remove(secureArgsList.bindDnArg);
184    }
185    else
186    {
187      defaultArgs.add(secureArgsList.adminUidArg);
188    }
189    secureArgsList.adminUidArg.setHidden(false);
190    defaultArgs.remove(secureArgsList.hostNameArg);
191    defaultArgs.remove(secureArgsList.portArg);
192    referencedHostNameArg = new StringArgument("referencedHostName",
193        OPTION_SHORT_HOST,
194        OPTION_LONG_REFERENCED_HOST_NAME, false, false, true,
195        INFO_HOST_PLACEHOLDER.get(),
196        UserData.getDefaultHostName(), OPTION_LONG_REFERENCED_HOST_NAME,
197        INFO_DESCRIPTION_REFERENCED_HOST.get());
198    defaultArgs.add(referencedHostNameArg);
199
200    args.addAll(defaultArgs);
201    initializeGlobalArguments(args);
202  }
203
204  /**
205   * Tells whether the user specified to have an interactive uninstall or not.
206   * This method must be called after calling parseArguments.
207   * @return <CODE>true</CODE> if the user specified to have an interactive
208   * uninstall and <CODE>false</CODE> otherwise.
209   */
210  public boolean isInteractive()
211  {
212    return !noPromptArg.isPresent();
213  }
214
215  /**
216   * Tells whether the user specified to force on non critical error in the non
217   * interactive mode.
218   * @return <CODE>true</CODE> if the user specified to force the uninstall in
219   * non critical error and <CODE>false</CODE> otherwise.
220   */
221  public boolean isForceOnError()
222  {
223    return forceOnErrorArg.isPresent();
224  }
225
226  /**
227   * Tells whether the user specified to have a quiet uninstall or not.
228   * This method must be called after calling parseArguments.
229   * @return <CODE>true</CODE> if the user specified to have a quiet
230   * uninstall and <CODE>false</CODE> otherwise.
231   */
232  public boolean isQuiet()
233  {
234    return quietArg.isPresent();
235  }
236
237  /**
238   * Tells whether the user specified to have a verbose uninstall or not.
239   * This method must be called after calling parseArguments.
240   * @return <CODE>true</CODE> if the user specified to have a verbose
241   * uninstall and <CODE>false</CODE> otherwise.
242   */
243  @Override
244  public boolean isVerbose()
245  {
246    return verboseArg.isPresent();
247  }
248
249  /**
250   * Tells whether the user specified to remove all files.
251   * This method must be called after calling parseArguments.
252   * @return <CODE>true</CODE> if the user specified to remove all files and
253   * <CODE>false</CODE> otherwise.
254   */
255  public boolean removeAll()
256  {
257    return removeAllArg.isPresent();
258  }
259
260  /**
261   * Tells whether the user specified to remove library files.
262   * This method must be called after calling parseArguments.
263   * @return <CODE>true</CODE> if the user specified to remove library files and
264   * <CODE>false</CODE> otherwise.
265   */
266  public boolean removeServerLibraries()
267  {
268    return removeServerLibrariesArg.isPresent();
269  }
270
271  /**
272   * Tells whether the user specified to remove database files.
273   * This method must be called after calling parseArguments.
274   * @return <CODE>true</CODE> if the user specified to remove database files
275   * and <CODE>false</CODE> otherwise.
276   */
277  public boolean removeDatabases()
278  {
279    return removeDatabasesArg.isPresent();
280  }
281
282  /**
283   * Tells whether the user specified to remove configuration files.
284   * This method must be called after calling parseArguments.
285   * @return <CODE>true</CODE> if the user specified to remove configuration
286   * files and <CODE>false</CODE> otherwise.
287   */
288  public boolean removeConfigurationFiles()
289  {
290    return removeConfigurationFilesArg.isPresent();
291  }
292
293  /**
294   * Tells whether the user specified to remove backup files.
295   * This method must be called after calling parseArguments.
296   * @return <CODE>true</CODE> if the user specified to remove backup files and
297   * <CODE>false</CODE> otherwise.
298   */
299  public boolean removeBackupFiles()
300  {
301    return removeBackupFilesArg.isPresent();
302  }
303
304  /**
305   * Tells whether the user specified to remove LDIF files.
306   * This method must be called after calling parseArguments.
307   * @return <CODE>true</CODE> if the user specified to remove LDIF files and
308   * <CODE>false</CODE> otherwise.
309   */
310  public boolean removeLDIFFiles()
311  {
312    return removeLDIFFilesArg.isPresent();
313  }
314
315  /**
316   * Tells whether the user specified to remove log files.
317   * This method must be called after calling parseArguments.
318   * @return <CODE>true</CODE> if the user specified to remove log files and
319   * <CODE>false</CODE> otherwise.
320   */
321  public boolean removeLogFiles()
322  {
323    return removeLogFilesArg.isPresent();
324  }
325
326  /**
327   * Returns the default Administrator UID value.
328   * @return the default Administrator UID value.
329   */
330  public String getDefaultAdministratorUID()
331  {
332    return secureArgsList.adminUidArg.getDefaultValue();
333  }
334
335  /**
336   * Returns the Host name to update remote references as provided in the
337   * command-line.
338   * @return the Host name to update remote references as provided in the
339   * command-line.
340   */
341  public String getReferencedHostName()
342  {
343    if (referencedHostNameArg.isPresent())
344    {
345      return referencedHostNameArg.getValue();
346    }
347    return null;
348  }
349
350  /**
351   * Returns the default value for the Host name to update remote references as
352   * provided in the command-line.
353   * @return the default value for the Host name to update remote references as
354   * provided in the command-line.
355   */
356  public String getDefaultReferencedHostName()
357  {
358    return referencedHostNameArg.getDefaultValue();
359  }
360
361  /**
362   * Indication if provided global options are validate.
363   *
364   * @param buf the LocalizableMessageBuilder to write the error messages.
365   * @return return code.
366   */
367  @Override
368  public int validateGlobalOptions(LocalizableMessageBuilder buf)
369  {
370    if (!noPromptArg.isPresent() && forceOnErrorArg.isPresent())
371    {
372      final LocalizableMessage message =
373          ERR_TOOL_CONFLICTING_ARGS.get(forceOnErrorArg.getLongIdentifier(),
374              noPromptArg.getLongIdentifier());
375      if (buf.length() > 0)
376      {
377        buf.append(LINE_SEPARATOR);
378      }
379      buf.append(message);
380    }
381    if (removeAllArg.isPresent())
382    {
383      BooleanArgument[] removeArgs = {
384          removeServerLibrariesArg,
385          removeDatabasesArg,
386          removeLogFilesArg,
387          removeConfigurationFilesArg,
388          removeBackupFilesArg,
389          removeLDIFFilesArg
390      };
391      for (BooleanArgument removeArg : removeArgs)
392      {
393        if (removeArg.isPresent())
394        {
395          LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get(
396              removeAllArg.getLongIdentifier(),
397              removeArg.getLongIdentifier());
398          if (buf.length() > 0)
399          {
400            buf.append(LINE_SEPARATOR);
401          }
402          buf.append(message);
403        }
404      }
405    }
406    super.validateGlobalOptions(buf);
407    if (buf.length() > 0)
408    {
409      return ReturnCode.CONFLICTING_ARGS.get();
410    }
411    return ReturnCode.SUCCESS.get();
412  }
413
414  /**
415   * Returns whether the command was launched in CLI mode or not.
416   * @return <CODE>true</CODE> if the command was launched to use CLI mode and
417   * <CODE>false</CODE> otherwise.
418   */
419  public boolean isCli()
420  {
421    return cliArg.isPresent();
422  }
423
424  /**
425   * Returns the SecureConnectionCliArgs object containing the arguments
426   * of this parser.
427   * @return the SecureConnectionCliArgs object containing the arguments
428   * of this parser.
429   */
430  SecureConnectionCliArgs getSecureArgsList()
431  {
432    return secureArgsList;
433  }
434}