/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* 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:
* Generoso Pagano - initial API and implementation
******************************************************************************/
package fr.inria.soctrace.framesoc.core.tools.management;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
/**
* Manager able to launch an external application capturing <i>stdout</i> and
* <i>stderr</i>.
*
* <p>
* The external process is launched within an Eclipse {@link Job} that the user
* can cancel.
*
* <p>
* After the execution of the process, a post execute method is called inside
* the {@link Job}.
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
public class ExternalToolExecutionManager {
private String name;
private String command;
/**
* Constructor
*
* @param name
* external tool name
* @param command
* external tool command
*/
public ExternalToolExecutionManager(String name, String command) {
this.name = name;
this.command = command;
}
/**
* Execute the tool within an Eclipse {@link Job}.
*
* @throws SoCTraceException
*/
public void execute() throws SoCTraceException {
ToolJob job = new ToolJob(name, command);
job.setUser(true);
job.schedule();
}
/**
* Optional operation to be performed before the process execution, still
* inside the Eclipse job.
*
*/
public void preExecute() {
// do nothing
}
/**
* Optional operation to be performed at the end of the process execution,
* still inside the Eclipse job.
*
* @param status
* the status that will be returned by the Eclipse job.
*/
public void postExecute(IStatus status) {
// do nothing
}
/**
* Eclipse {@link Job} able to launch a command inside a {@link Process}.
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
class ToolJob extends Job {
private String command;
public ToolJob(String name, String command) {
super(name);
this.command = command;
}
@Override
protected IStatus run(IProgressMonitor monitor) {
monitor.setTaskName(name);
monitor.beginTask(name, IProgressMonitor.UNKNOWN);
// before execution
preExecute();
try {
Process p = Runtime.getRuntime().exec(command);
boolean notExited = true;
while (!monitor.isCanceled() && notExited) {
try {
p.exitValue();
notExited = false;
} catch (IllegalThreadStateException e) {
Thread.sleep(500);
}
}
if (notExited) {
p.destroy();
}
// debug code
else {
String line;
BufferedReader bri = new BufferedReader(new InputStreamReader(
p.getInputStream()));
BufferedReader bre = new BufferedReader(new InputStreamReader(
p.getErrorStream()));
while ((line = bri.readLine()) != null) {
System.out.println(line);
}
bri.close();
while ((line = bre.readLine()) != null) {
System.err.println(line);
}
bre.close();
}
} catch (Exception e) {
System.err.println(e.getMessage());
postExecute(Status.CANCEL_STATUS);
return Status.CANCEL_STATUS;
}
monitor.done();
postExecute(Status.OK_STATUS);
return Status.OK_STATUS;
}
}
}