package codeine.servlets.command_backup;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import codeine.model.ExitStatus;
import codeine.model.Result;
import codeine.utils.ThreadUtils;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class ProcessExecuterBackup {
private static final Logger log = Logger.getLogger(ProcessExecuterBackup.class);
private List<String> cmd;
private long timeoutInMinutes;
private Function<String, Void> function;
private String runFromDir;
private Map<String, String> env;
private ProcessExecuterBackup(List<String> cmd, List<String> cmdForOutput, long timeoutInMinutes, Function<String, Void> function, String runFromDir, Map<String, String> env) {
super();
this.cmd = cmd;
this.timeoutInMinutes = timeoutInMinutes;
this.function = function;
this.runFromDir = runFromDir;
this.env = env;
}
public Result execute() {
log.debug("executing " + cmd);
Process process = null;
ProcessExecuterWorkerBackup worker = null;
try {
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.environment().putAll(env);
pb.directory(new File(runFromDir));
pb.redirectErrorStream(true);
process = pb.start();
worker = new ProcessExecuterWorkerBackup(process, function, cmd);
worker.start();
long timeout = TimeUnit.MINUTES.toMillis(timeoutInMinutes);
worker.join(timeout);
if (worker.exitStatus() != null) {
return new Result(worker.exitStatus(), worker.output());
} else {
ThreadUtils.sleep(100);
return new Result(ExitStatus.TIMEOUT, worker.output());
}
} catch (IOException e) {
String output = null == worker ? "" : worker.output();
return new Result(ExitStatus.IO_ERROR, output);
} catch (InterruptedException ex) {
worker.interrupt();
Thread.currentThread().interrupt();
throw new RuntimeException(ex);
} finally {
if (null != process) {
process.destroy();
}
}
}
public static class ProcessExecuterBuilderBackup{
private List<String> cmd;
private List<String> cmdForOutput;
private long timeoutInMinutes = 2;
private String runFromDir;
private Map<String, String> env = Maps.newHashMap();
@SuppressWarnings({ "unchecked", "rawtypes" })
private Function<String, Void> function = (Function)Functions.constant(null);
public ProcessExecuterBuilderBackup(List<String> cmd, String runFromDir) {
this.cmd = cmd;
this.cmdForOutput = cmd;
this.runFromDir = runFromDir;
}
public ProcessExecuterBuilderBackup(List<String> cmd) {
this(cmd, ".");
}
public ProcessExecuterBackup build(){
return new ProcessExecuterBackup(cmd, cmdForOutput, timeoutInMinutes, function, runFromDir, env);
}
public ProcessExecuterBuilderBackup cmd(List<String> cmd){
this.cmd = cmd;
return this;
}
public ProcessExecuterBuilderBackup env(Map<String, String> env){
this.env = env;
return this;
}
public ProcessExecuterBuilderBackup cmdForOutput(List<String> cmdForOutput){
this.cmdForOutput = cmdForOutput;
return this;
}
public ProcessExecuterBuilderBackup timeoutInMinutes(long timeoutInMinutes){
this.timeoutInMinutes = timeoutInMinutes;
return this;
}
public ProcessExecuterBuilderBackup function(Function<String, Void> function){
this.function = function;
return this;
}
}
public static Result execute(String cmd) {
List<String> cmdList = Lists.newArrayList(Splitter.on(" ").omitEmptyStrings().split(cmd));
return new ProcessExecuterBuilderBackup(cmdList).build().execute();
}
public static String executeSuccess(String cmd) {
Result r = execute(cmd);
if (!r.success()) {
throw new RuntimeException("fail with exit status " + r.exit());
}
return r.output();
}
// public static void main(String[] args) {
// ArrayList<String> cmd = Lists.newArrayList("/workarea/oshai/4_2_eclipse/workspace/codeintel/deployment/project/test_project/plugins/restart");
// Function<String, Void> f = new Function<String, Void>(){
// @Override
// public Void apply(String input){
// System.out.println(input);
// return null;
// }
// };
// new ProcessExecuter(cmd, cmd, 2, f).execute();
// }
}