/*
*
* * RHQ Management Platform
* * Copyright (C) 2005-2015 Red Hat, Inc.
* * All rights reserved.
* *
* * This program is free software; you can redistribute it and/or modify
* * it under the terms of the GNU General Public License, version 2, as
* * published by the Free Software Foundation, and/or the GNU Lesser
* * General Public License, version 2.1, also as published by the Free
* * Software Foundation.
* *
* * 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 and the GNU Lesser General Public License
* * for more details.
* *
* * You should have received a copy of the GNU General Public License
* * and the GNU Lesser General Public License along with this program;
* * if not, write to the Free Software Foundation, Inc.,
* * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package org.rhq.server.control.util;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.Executor;
import org.apache.commons.exec.PumpStreamHandler;
import org.rhq.core.util.exec.ProcessExecutionOutputStream;
@SuppressWarnings("rawtypes")
public class ExecutorAssist {
private static ExecutorAssist defaultAssit;
private static ExecutorAssist silentAssist;
/**
* @return default executor assist
*/
public static ExecutorAssist getDefault() {
if (defaultAssit == null) {
defaultAssit = new ExecutorAssist();
}
return defaultAssit;
}
/**
* @return silent executor assist (does not capture child process output streams)
*/
public static ExecutorAssist getSilent() {
if (silentAssist == null) {
silentAssist = new ExecutorAssist();
silentAssist.executor.setStreamHandler(
new PumpStreamHandler(
new ProcessExecutionOutputStream(0, false),
new ProcessExecutionOutputStream(0, false)));
}
return silentAssist;
}
private final Executor executor;
private ExecutorAssist() {
executor = new DefaultExecutor();
executor.setStreamHandler(new PumpStreamHandler());
}
public int exec(final File workingDir, final CommandLine commandLine) throws IOException {
return exec(workingDir, commandLine, null);
}
public int exec(final File workingDir, final CommandLine commandLine, final Map environment) throws IOException {
int rValue = 0;
try {
// Synchronized to prevent two threads from setting different workingDirectory at the same time..
synchronized(executor) {
executor.setWorkingDirectory(workingDir);
// null environment is fine in both cases, DefaultExecutor will use default environment in that case
rValue = executor.execute(commandLine, environment);
}
} catch(ExecuteException e) {
// DefaultExecutor has no detailed exception text, safe to ignore
rValue = Math.max(e.getExitValue(), rValue);
}
return rValue;
}
// static methods for compatibility (using default ExecutorAssist)
public Future<Integer> execAsync(final File workingDir, final CommandLine commandLine, final Map environment) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
return executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return exec(workingDir, commandLine, environment);
}
});
}
public static int execute(final File workingDir, final CommandLine commandLine, final Map environment)
throws IOException {
return getDefault().exec(workingDir, commandLine, environment);
}
public static Future<Integer> executeAsync(final File workingDir, final CommandLine commandLine,
final Map environment) {
return getDefault().execAsync(workingDir, commandLine, environment);
}
public static int execute(final File workingDir, final CommandLine commandLine) throws IOException {
return getDefault().exec(workingDir, commandLine);
}
}