001/* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020package org.sonar.api.utils.command; 021 022import com.google.common.base.Joiner; 023import com.google.common.base.Preconditions; 024import com.google.common.collect.ImmutableList; 025import com.google.common.collect.ImmutableMap; 026import com.google.common.collect.Lists; 027import com.google.common.collect.Maps; 028import org.apache.commons.lang.StringUtils; 029import org.apache.commons.lang.SystemUtils; 030 031import java.io.File; 032import java.util.Collections; 033import java.util.List; 034import java.util.Map; 035 036/** 037 * @since 2.7 038 */ 039public class Command { 040 private final String executable; 041 private final List<String> arguments = Lists.newArrayList(); 042 private final Map<String, String> env = Maps.newHashMap(System.getenv()); 043 private File directory; 044 private boolean newShell = false; 045 046 private Command(String executable) { 047 Preconditions.checkArgument(!StringUtils.isBlank(executable), "Command executable can not be blank"); 048 this.executable = executable; 049 } 050 051 public String getExecutable() { 052 return executable; 053 } 054 055 public List<String> getArguments() { 056 return ImmutableList.copyOf(arguments); 057 } 058 059 public Command addArgument(String arg) { 060 arguments.add(arg); 061 return this; 062 } 063 064 public Command addArguments(List<String> args) { 065 arguments.addAll(args); 066 return this; 067 } 068 069 public Command addArguments(String[] args) { 070 Collections.addAll(arguments, args); 071 return this; 072 } 073 074 public File getDirectory() { 075 return directory; 076 } 077 078 /** 079 * Sets working directory. 080 */ 081 public Command setDirectory(File d) { 082 this.directory = d; 083 return this; 084 } 085 086 /** 087 * @see {@link org.sonar.api.utils.command.Command#getEnvironmentVariables()} 088 * @since 3.2 089 */ 090 public Command setEnvironmentVariable(String name, String value) { 091 this.env.put(name, value); 092 return this; 093 } 094 095 /** 096 * Environment variables that are propagated during command execution. 097 * The initial value is a copy of the environment of the current process. 098 * 099 * @return a non-null and immutable map of variables 100 * @since 3.2 101 */ 102 public Map<String, String> getEnvironmentVariables() { 103 return ImmutableMap.copyOf(env); 104 } 105 106 /** 107 * <code>true</code> if a new shell should be used to execute the command. 108 * The default behavior is to not use a new shell. 109 * 110 * @since 3.3 111 */ 112 public boolean isNewShell() { 113 return newShell; 114 } 115 116 /** 117 * Set to <code>true</code> if a new shell should be used to execute the command. 118 * This is useful when the executed command is a script with no execution rights (+x on unix). 119 * 120 * On windows, the command will be executed with <code>cmd /C executable</code>. 121 * On other platforms, the command will be executed with <code>sh executable</code>. 122 * 123 * @since 3.3 124 */ 125 public Command setNewShell(boolean b) { 126 this.newShell = b; 127 return this; 128 } 129 130 List<String> toStrings() { 131 ImmutableList.Builder<String> command = ImmutableList.builder(); 132 if (newShell) { 133 if (SystemUtils.IS_OS_WINDOWS) { 134 command.add("cmd", "/C", "call"); 135 } else { 136 command.add("sh"); 137 } 138 } 139 command.add(executable); 140 command.addAll(arguments); 141 return command.build(); 142 } 143 144 public String toCommandLine() { 145 return Joiner.on(" ").join(toStrings()); 146 } 147 148 @Override 149 public String toString() { 150 return toCommandLine(); 151 } 152 153 /** 154 * Create a command line without any arguments 155 * 156 * @param executable 157 */ 158 public static Command create(String executable) { 159 return new Command(executable); 160 } 161}