/** * Copyright (c) 2008-2016, XebiaLabs B.V., All rights reserved. * * * Overthere is licensed under the terms of the GPLv2 * <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most XebiaLabs Libraries. * There are special exceptions to the terms and conditions of the GPLv2 as it is applied to * this software, see the FLOSS License Exception * <http://github.com/xebialabs/overthere/blob/master/LICENSE>. * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; version 2 * of the License. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this * program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth * Floor, Boston, MA 02110-1301 USA */ package com.xebialabs.overthere; import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import static com.xebialabs.overthere.util.OverthereUtils.checkNotNull; import static com.xebialabs.overthere.util.OverthereUtils.checkState; import static com.xebialabs.overthere.CmdLineArgument.arg; import static com.xebialabs.overthere.CmdLineArgument.nested; import static com.xebialabs.overthere.CmdLineArgument.password; import static com.xebialabs.overthere.CmdLineArgument.raw; import static com.xebialabs.overthere.OperatingSystemFamily.UNIX; import static java.util.Collections.unmodifiableList; /** * Represents a command line. */ @SuppressWarnings("serial") public class CmdLine implements Serializable { List<CmdLineArgument> arguments = new ArrayList<CmdLineArgument>(); /** * Adds {@link CmdLineArgument#arg(String) a regular argument} to the command line. * * @param arg the argument string to add. * @return this. */ public CmdLine addArgument(String arg) { arguments.add(arg(arg)); return this; } /** * Adds {@link CmdLineArgument#password(String) a password argument} to the command line. * * @param arg the argument string to add. * @return this. */ public CmdLine addPassword(String arg) { arguments.add(password(arg)); return this; } /** * Adds {@link CmdLineArgument#raw(String) a raw argument} to the command line. * * @param arg the argument string to add. * @return this. */ public CmdLine addRaw(String arg) { arguments.add(raw(arg)); return this; } /** * Adds a {@link MessageFormat} compatible templated fragment to the command line as a series of {@link CmdLineArgument#arg(String) regular arguments}. * * @param template The {@link MessageFormat} compatible templated fragment. * @param variables The variables that are substituted in the template. * @return this. */ public CmdLine addTemplatedFragment(String template, Object... variables) { for (String arg : template.split("\\s+")) { if(arg.matches(".*\\{\\d+}\\.*")) { String fragment = MessageFormat.format(arg, variables); addArgument(fragment); } else { addRaw(arg); } } return this; } /** * Adds {@link CmdLineArgument#nested(CmdLine) a nested command line} to the command line. * * @param commandLine the command line to add. * @return this. */ public CmdLine addNested(CmdLine commandLine) { arguments.add(nested(commandLine)); return this; } /** * Adds an {@link CmdLineArgument argument}. * * @param arg the argument to add. * @return this. */ public CmdLine add(CmdLineArgument arg) { checkNotNull(arg, "Cannot add null CmdLineArgument"); arguments.add(arg); return this; } /** * Adds a list of {@link CmdLineArgument arguments}. * * @param args the arguments to add. * @return this. */ public CmdLine add(List<CmdLineArgument> args) { checkNotNull(args, "Cannot add null List<CmdLineArgument>"); arguments.addAll(args); return this; } /** * Returns the argument on this command line. * * @return the list of {@link CmdLineArgument arguments}. */ public List<CmdLineArgument> getArguments() { return unmodifiableList(arguments); } /** * Converts this command line to a string array. All arguments are * {@link CmdLineArgument#toString(OperatingSystemFamily, boolean) converted to their string representation} and * then returned as an array. * * @param os the operating system on which the result will be executed. * @param forLogging <code>true</code> if these string representations will be used for logging. * @return an array with the string representations of the command line arguments. */ public String[] toCommandArray(final OperatingSystemFamily os, final boolean forLogging) { checkState(arguments.size() > 0, "Cannot encode empty command line"); String[] args = new String[arguments.size()]; for (int i = 0; i < arguments.size(); i++) { args[i] = arguments.get(i).toString(os, forLogging); } return args; } /** * Converts this command line to a single String for execution on (or logging to) a specific target operating * system. * * @param os the operating system on which the result will be executed. * @param forLogging <code>true</code> if the created command line will be used for logging. * @return the command line as a single string */ public String toCommandLine(final OperatingSystemFamily os, final boolean forLogging) { checkState(arguments.size() > 0, "Cannot encode empty command line"); StringBuilder sb = new StringBuilder(); for (CmdLineArgument a : arguments) { if (sb.length() > 0) { sb.append(' '); } a.buildString(os, forLogging, sb); } return sb.toString(); } /** * Returns a string representation of this command line. All passwords are hidden. */ @Override public String toString() { return toCommandLine(UNIX, true); } /** * Builds a simple command line from one or more strings. For each string, a regular argument is created. * * @param args the regular arguments * @return the created command line */ public static CmdLine build(String... args) { CmdLine cmdLine = new CmdLine(); for (String s : args) { cmdLine.addArgument(s); } return cmdLine; } }