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