/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2009 Sun Microsystems, Inc. */ package org.opends.server.util.cli; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.opends.server.util.SetupUtils; import org.opends.server.util.args.Argument; import org.opends.server.util.args.BooleanArgument; import org.opends.server.util.args.FileBasedArgument; /** * Class used to be able to generate the non interactive mode. * */ public class CommandBuilder { // The command name. private String commandName; // The subcommand name. private String subcommandName; private ArrayList args = new ArrayList(); private HashSet obfuscatedArgs = new HashSet(); /** * The value used to display arguments that must be obfuscated (such as * passwords). This does not require localization (since the output of * command builder by its nature is not localized). */ public final static String OBFUSCATED_VALUE = "******"; /** * The separator used to link the lines of the resulting command-lines. */ public final static String LINE_SEPARATOR; static { if (SetupUtils.isWindows()) { LINE_SEPARATOR = " "; } else { LINE_SEPARATOR = " \\\n "; } } /** * The separator used to link the lines of the resulting command-lines in * HTML format. */ public final static String HTML_LINE_SEPARATOR; static { if (SetupUtils.isWindows()) { HTML_LINE_SEPARATOR = " "; } else { HTML_LINE_SEPARATOR = " \\
          "; } } /** * The constructor for the CommandBuilder. * @param commandName the command name. */ public CommandBuilder(String commandName) { this(commandName, null); } /** * The constructor for the CommandBuilder. * @param commandName the command name. * @param subcommandName the subcommand name. */ public CommandBuilder(String commandName, String subcommandName) { this.commandName = commandName; this.subcommandName = subcommandName; } /** * Adds an argument to the list of the command builder. * @param argument the argument to be added. */ public void addArgument(Argument argument) { // We use an ArrayList to be able to provide the possibility of updating // the position of the attributes. if (!args.contains(argument)) { args.add(argument); } } /** * Adds an argument whose values must be obfuscated (passwords for instance). * @param argument the argument to be added. */ public void addObfuscatedArgument(Argument argument) { addArgument(argument); obfuscatedArgs.add(argument); } /** * Removes the provided argument from this CommandBuilder. * @param argument the argument to be removed. * @return true if the attribute was present and removed and * false otherwise. */ public boolean removeArgument(Argument argument) { obfuscatedArgs.remove(argument); return args.remove(argument); } /** * Appends the arguments of another command builder to this command builder. * @param builder the CommandBuilder to append. */ public void append(CommandBuilder builder) { for (Argument arg : builder.args) { if (builder.isObfuscated(arg)) { addObfuscatedArgument(arg); } else { addArgument(arg); } } } /** * Returns the String representation of this command builder (i.e. what we * want to show to the user). * @return the String representation of this command builder (i.e. what we * want to show to the user). */ public String toString() { return toString(false, LINE_SEPARATOR); } /** * Returns the String representation of this command builder (i.e. what we * want to show to the user). * @param lineSeparator the String to be used to separate lines of the * command-builder. * @return the String representation of this command builder (i.e. what we * want to show to the user). */ public String toString(String lineSeparator) { return toString(false, lineSeparator); } /** * Returns the String representation of this command builder (i.e. what we * want to show to the user). * @param showObfuscated displays in clear the obfuscated values. * @param lineSeparator the String to be used to separate lines of the * command-builder. * @return the String representation of this command builder (i.e. what we * want to show to the user). */ private String toString(boolean showObfuscated, String lineSeparator) { StringBuilder builder = new StringBuilder(); builder.append(commandName); if (subcommandName != null) { builder.append(" "+subcommandName); } for (Argument arg : args) { // This CLI is always using SSL, and the argument has been removed from // the user interface if (arg.getName().equals("useSSL") ) { continue; } String argName; if (arg.getLongIdentifier() != null) { argName = "--"+arg.getLongIdentifier(); } else { argName = "-"+arg.getShortIdentifier(); } if (arg instanceof BooleanArgument) { builder.append(lineSeparator+argName); } else if (arg instanceof FileBasedArgument) { for (String value : ((FileBasedArgument)arg).getNameToValueMap().keySet()) { builder.append(lineSeparator+argName+" "); if (isObfuscated(arg) && !showObfuscated) { value = OBFUSCATED_VALUE; } else { value = escapeValue(value); } builder.append(value); } } else { for (String value : arg.getValues()) { builder.append(lineSeparator+argName+" "); if (isObfuscated(arg) && !showObfuscated) { value = OBFUSCATED_VALUE; } else { value = escapeValue(value); } builder.append(value); } } } return builder.toString(); } /** * Clears the arguments. */ public void clearArguments() { args.clear(); obfuscatedArgs.clear(); } /** * Returns the list of arguments. * @return the list of arguments. */ public List getArguments() { return args; } /** * Tells whether the provided argument's values must be obfuscated or not. * @param argument the argument to handle. * @return true if the attribute's values must be obfuscated and * false otherwise. */ public boolean isObfuscated(Argument argument) { return obfuscatedArgs.contains(argument); } // Chars that require special treatment when passing them to command-line. private final static char[] charsToEscape = {' ', '\t', '\n', '|', ';', '<', '>', '(', ')', '$', '`', '\\', '"', '\''}; /** * This method simply takes a value and tries to transform it (with escape or * '"') characters so that it can be used in a command line. * @param value the String to be treated. * @return the transformed value. */ public static String escapeValue(String value) { StringBuilder b = new StringBuilder(); if (SetupUtils.isUnix()) { for (int i=0 ; i