/*******************************************************************************
* Copyright (c) 2012, 2016, 2017 PDT Extension Group and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PDT Extension Group - initial API and implementation
* Kaloyan Raev - [501269] externalize strings
*******************************************************************************/
package org.eclipse.php.composer.core.launch.execution;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.exec.*;
import org.eclipse.php.composer.core.log.Logger;
/**
* Executes a PHP script using a specific {@link Environment}.
*
*
*/
public class ScriptExecutor {
private DefaultExecutor executor;
private ExecuteWatchdog watchdog;
private PumpStreamHandler streamHandler;
private LogOutputStream outStream;
private LogOutputStream errStream;
private StringBuilder outBuilder;
private StringBuilder errBuilder;
private int timeout = 60000;
private Set<ExecutionResponseListener> listeners = new HashSet<ExecutionResponseListener>();
private DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler() {
public void onProcessComplete(int exitValue) {
super.onProcessComplete(exitValue);
for (ExecutionResponseListener handler : listeners) {
handler.executionFinished(outBuilder.toString(), exitValue);
}
}
public void onProcessFailed(ExecuteException e) {
String response = errBuilder.toString();
String stdOutResponse = outBuilder.toString();
super.onProcessFailed(e);
for (ExecutionResponseListener handler : listeners) {
if (stdOutResponse.length() > 0) {
response = stdOutResponse;
}
handler.executionFailed(response, e);
}
}
};
public ScriptExecutor() {
outBuilder = new StringBuilder();
errBuilder = new StringBuilder();
errStream = new LogOutputStream() {
@Override
protected void processLine(String line, int level) {
if (!line.isEmpty()) {
errBuilder.append(line + "\n"); //$NON-NLS-1$
for (ExecutionResponseListener listener : listeners) {
listener.executionMessage(line);
}
}
}
};
outStream = new LogOutputStream() {
@Override
protected void processLine(String line, int level) {
if (!line.isEmpty()) {
outBuilder.append(line + "\n"); //$NON-NLS-1$
for (ExecutionResponseListener listener : listeners) {
listener.executionMessage(line);
}
}
}
};
streamHandler = new PumpStreamHandler(outStream, errStream);
executor = new DefaultExecutor();
executor.setStreamHandler(streamHandler);
}
public void addResponseListener(ExecutionResponseListener listener) {
listeners.add(listener);
}
public void removeResponseListener(ExecutionResponseListener listener) {
listeners.remove(listener);
}
public void setTimeout(long timeout) {
watchdog = new ExecuteWatchdog(timeout);
executor.setWatchdog(watchdog);
}
public void setExitValue(int exitValue) {
executor.setExitValue(exitValue);
}
public void execute(String cmd) throws ExecuteException, IOException, InterruptedException {
execute(CommandLine.parse(cmd));
}
public void execute(CommandLine cmd) {
execute(cmd, null);
}
public void execute(CommandLine cmd, Map<String, String> env) {
try {
for (ExecutionResponseListener handler : listeners) {
handler.executionAboutToStart();
}
Logger.debug("executing command using executable: " + cmd.getExecutable()); //$NON-NLS-1$
executor.setExitValue(0);
executor.execute(cmd, env, handler);
for (ExecutionResponseListener handler : listeners) {
handler.executionStarted();
}
handler.waitFor();
} catch (Exception e) {
for (ExecutionResponseListener handler : listeners) {
handler.executionFailed("", e); //$NON-NLS-1$
}
}
}
public void abort() {
if (watchdog != null) {
executor.setExitValues(new int[] { 0, 143 }); // we abort, so it's
// ok with 1 as exit
// value
watchdog.destroyProcess();
}
}
public void setWorkingDirectory(File dir) {
executor.setWorkingDirectory(dir);
}
public File getWorkingDirectory() {
return executor.getWorkingDirectory();
}
public void setTimeout(int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException(Messages.ScriptExecutor_NegativeTimeoutError);
}
this.timeout = timeout;
watchdog = new ExecuteWatchdog(timeout);
executor.setWatchdog(watchdog);
}
}