blob: 681ec0ec17ece82ba862f85e619f49fabf118a50 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation 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
*
*******************************************************************************/
package org.eclipse.dltk.launching;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.dltk.internal.launching.DLTKLaunchingPlugin;
import org.eclipse.dltk.internal.launching.InterpreterMessages;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.MessageFormat;
/**
* Abstract implementation of a interpreter runner.
* <p>
* Clients implementing interpreter runners should subclass this class.
* </p>
*
* @see IInterpreterRunner
*
*/
public abstract class AbstractInterpreterRunner implements IInterpreterRunner {
private IInterpreterInstall interpreterInstall;
protected IInterpreterInstall getInstall() {
return interpreterInstall;
}
private static String renderProcessLabel(String[] commandLine) {
String format = LaunchingMessages.StandardInterpreterRunner;
String timestamp = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM).format(new Date(System.currentTimeMillis()));
return MessageFormat.format(format, new String[] { commandLine[0],
timestamp });
}
/**
* String representation of the command line
*
* @param commandLine
* @return
*/
private static String renderCommandLineLabel(String[] commandLine) {
if (commandLine.length < 1)
return ""; //$NON-NLS-1$
StringBuffer buf = new StringBuffer();
for (int i = 0; i < commandLine.length; i++) {
buf.append(' ');
char[] characters = commandLine[i].toCharArray();
StringBuffer command = new StringBuffer();
boolean containsSpace = false;
for (int j = 0; j < characters.length; j++) {
char character = characters[j];
if (character == '\"') {
command.append('\\');
} else if (character == ' ') {
containsSpace = true;
}
command.append(character);
}
if (containsSpace) {
buf.append('\"');
buf.append(command.toString());
buf.append('\"');
} else {
buf.append(command.toString());
}
}
return buf.toString();
}
protected String renderCommandLineLabel(InterpreterConfig config) {
String[] cmdLine = renderCommandLine(config);
return renderCommandLineLabel(cmdLine);
}
protected void abort(String message, Throwable exception)
throws CoreException {
throw new CoreException(new Status(IStatus.ERROR,
DLTKLaunchingPlugin.PLUGIN_ID,
ScriptLaunchConfigurationConstants.ERR_INTERNAL_ERROR, message,
exception));
}
protected void abort(String message, Throwable exception, int code)
throws CoreException {
throw new CoreException(new Status(IStatus.ERROR,
DLTKLaunchingPlugin.PLUGIN_ID, code, message, exception));
}
// Execution helpers
protected Process exec(String[] cmdLine, File workingDirectory)
throws CoreException {
return DebugPlugin.exec(cmdLine, workingDirectory);
}
//
protected Map getDefaultProcessMap() {
Map map = new HashMap();
map.put(IProcess.ATTR_PROCESS_TYPE, getProcessType());
return map;
}
protected String getProcessType() {
return ScriptLaunchConfigurationConstants.ID_SCRIPT_PROCESS_TYPE;
}
protected AbstractInterpreterRunner(IInterpreterInstall install) {
this.interpreterInstall = install;
}
protected void checkConfig(InterpreterConfig config) throws CoreException {
File dir = new File(config.getWorkingDirectoryPath().toOSString());
if (!dir.exists()) {
abort(
MessageFormat
.format(
InterpreterMessages.errDebuggingEngineWorkingDirectoryDoesntExist,
new Object[] { dir.toString() }), null);
}
File script = new File(config.getScriptFilePath().toOSString());
if (!script.exists()) {
abort(
MessageFormat
.format(
InterpreterMessages.errDebuggingEngineScriptFileDoesntExist,
new Object[] { script.toString() }), null);
}
}
/**
* Returns a new process aborting if the process could not be created.
*
* @param launch
* the launch the process is contained in
* @param p
* the system process to wrap
* @param label
* the label assigned to the process
* @param attributes
* values for the attribute map
* @return the new process
* @throws CoreException
* problems occurred creating the process
*
*/
private IProcess newProcess(ILaunch launch, Process p, String label,
Map attributes) throws CoreException {
IProcess process = DebugPlugin.newProcess(launch, p, label, attributes);
if (process == null) {
p.destroy();
abort(LaunchingMessages.AbstractInterpreterRunner_0, null);
}
return process;
}
protected String[] renderCommandLine(InterpreterConfig config) {
return config.renderCommandLine(interpreterInstall);
}
protected IProcess rawRun(ILaunch launch, InterpreterConfig config)
throws CoreException {
checkConfig(config);
String[] cmdLine = renderCommandLine(config);
File workingDirectory = config.getWorkingDirectoryPath().toFile();
String[] environment = config.getEnvironmentAsStringsIncluding(interpreterInstall.getEnvironmentVariables());
final String cmdLineLabel = renderCommandLineLabel(cmdLine);
final String processLabel = renderProcessLabel(cmdLine);
if (DLTKLaunchingPlugin.TRACE_EXECUTION) {
traceExecution(processLabel, cmdLineLabel, workingDirectory,
environment);
}
Process p = DebugPlugin.exec(cmdLine, workingDirectory, environment);
if (p == null) {
abort("Execution was cancelled", null);
}
launch.setAttribute(DLTKLaunchingPlugin.LAUNCH_COMMAND_LINE,
cmdLineLabel);
IProcess process = newProcess(launch, p, processLabel,
getDefaultProcessMap());
process.setAttribute(IProcess.ATTR_CMDLINE, cmdLineLabel);
return process;
}
private void traceExecution(String processLabel,
String cmdLineLabel, File workingDirectory, String[] environment) {
StringBuffer sb = new StringBuffer();
sb.append("-----------------------------------------------\n");
sb.append("Running ").append(processLabel).append('\n');
sb.append("Command line: ").append(cmdLineLabel).append('\n');
sb.append("Working directory: ").append(workingDirectory).append('\n');
sb.append("Environment:\n");
for (int i=0; i<environment.length; i++) {
sb.append('\t').append(environment[i]).append('\n');
}
sb.append("-----------------------------------------------\n");
System.out.println(sb);
}
public void run(InterpreterConfig config, ILaunch launch,
IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
try {
monitor.beginTask("Launching...", 5);
if (monitor.isCanceled()) {
return;
}
monitor.worked(1);
monitor.subTask("Running");
rawRun(launch, config);
monitor.worked(4);
} finally {
monitor.done();
}
// TODO: Handling of
// IDLTKLaunchConfigurationConstants.ATTR_USE_DLTK_OUTPUT
}
}