blob: 676bba3f342055c334cf10813c45861b0e0ea60f [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.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IScriptModelMarker;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IExecutionEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.internal.launching.DLTKLaunchingPlugin;
import org.eclipse.dltk.internal.launching.InterpreterRuntimeBuildpathEntryResolver;
import org.eclipse.dltk.launching.debug.DebuggingEngineManager;
import com.ibm.icu.text.MessageFormat;
/**
* Abstract implementation of a Script launch configuration delegate. Provides
* convenience methods for accessing and verifying launch configuration
* attributes.
* <p>
* Clients implementing Script launch configuration delegates should subclass
* this class.
* </p>
*/
public abstract class AbstractScriptLaunchConfigurationDelegate extends
LaunchConfigurationDelegate {
/**
* A list of prerequisite projects ordered by their build order.
*/
private IProject[] fOrderedProjects;
/**
* Convenience method to get the launch manager.
*
* @return the launch manager
*/
protected ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
/**
* Throws a core exception with an error status object built from the given
* message, lower level exception, and error code.
*
* @param message
* the status message
* @param exception
* lower level exception associated with the error, or
* <code>null</code> if none
* @param code
* error code
* @throws CoreException
* the "abort" core 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));
}
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));
}
/**
* Returns the Interpreter install specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the Interpreter install specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public IInterpreterInstall getInterpreterInstall(
ILaunchConfiguration configuration) throws CoreException {
return ScriptRuntime.computeInterpreterInstall(configuration);
}
/**
* Verifies the Interpreter install specified by the given launch
* configuration exists and returns the Interpreter install.
*
* @param configuration
* launch configuration
* @return the Interpreter install specified by the given launch
* configuration
* @exception CoreException
* if unable to retrieve the attribute, the attribute is
* unspecified, or if the home location is unspecified or
* does not exist
*/
public IInterpreterInstall verifyInterpreterInstall(
ILaunchConfiguration configuration) throws CoreException {
IInterpreterInstall interpreter = getInterpreterInstall(configuration);
if (interpreter == null) {
abort(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_The_specified_InterpreterEnvironment_installation_does_not_exist_4,
null,
ScriptLaunchConfigurationConstants.ERR_INTERPRETER_INSTALL_DOES_NOT_EXIST);
}
IFileHandle location = interpreter.getInstallLocation();
if (location == null) {
abort(
MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_InterpreterEnvironment_home_directory_not_specified_for__0__5,
new String[] { interpreter.getName() }),
null,
ScriptLaunchConfigurationConstants.ERR_INTERPRETER_INSTALL_DOES_NOT_EXIST);
}
if (!location.exists()) {
abort(
MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_InterpreterEnvironment_home_directory_for__0__does_not_exist___1__6,
new String[] { interpreter.getName(),
location.toURI().toString() }),
null,
ScriptLaunchConfigurationConstants.ERR_INTERPRETER_INSTALL_DOES_NOT_EXIST);
}
return interpreter;
}
/**
* Returns the Interpreter connector identifier specified by the given
* launch configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the Interpreter connector identifier specified by the given
* launch configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public String getDebugConnectorId(ILaunchConfiguration configuration)
throws CoreException {
return configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_DEBUG_CONNECTOR,
(String) null);
}
/**
* Returns the entries that should appear on the user portion of the
* buildpath as specified by the given launch configuration, as an array of
* resolved strings. The returned array is empty if no buildpath is
* specified.
*
* @param configuration
* launch configuration
* @return the buildpath specified by the given launch configuration,
* possibly an empty array
* @exception CoreException
* if unable to retrieve the attribute
*/
public String[] getBuildpath(ILaunchConfiguration configuration)
throws CoreException {
// Get entries
IRuntimeBuildpathEntry[] entries = ScriptRuntime
.computeUnresolvedRuntimeBuildpath(configuration);
entries = ScriptRuntime.resolveRuntimeBuildpath(entries, configuration);
// Get USER_ENTRY
Set userEntries = new HashSet();
for (int i = 0; i < entries.length; i++) {
if (entries[i].getBuildpathProperty() == IRuntimeBuildpathEntry.USER_ENTRY) {
userEntries.add(entries[i].getLocation());
}
}
return (String[]) userEntries.toArray(new String[userEntries.size()]);
}
/**
* Returns entries that should appear on the bootstrap portion of the
* buildpath as specified by the given launch configuration, as an array of
* resolved strings. The returned array is <code>null</code> if all entries
* are standard (i.e. appear by default), or empty to represent an empty
* bootpath.
*
* @param configuration
* launch configuration
* @return the bootpath specified by the given launch configuration. An
* empty bootpath is specified by an empty array, and
* <code>null</code> represents a default bootpath.
* @exception CoreException
* if unable to retrieve the attribute
*/
public String[] getBootpath(ILaunchConfiguration configuration)
throws CoreException {
String[][] paths = getBootpathExt(configuration);
String[] pre = paths[0];
String[] main = paths[1];
String[] app = paths[2];
if (pre == null && main == null && app == null) {
// default
return null;
}
IRuntimeBuildpathEntry[] entries = ScriptRuntime
.computeUnresolvedRuntimeBuildpath(configuration);
entries = ScriptRuntime.resolveRuntimeBuildpath(entries, configuration);
List bootEntries = new ArrayList(entries.length);
boolean empty = true;
boolean allStandard = true;
for (int i = 0; i < entries.length; i++) {
if (entries[i].getBuildpathProperty() != IRuntimeBuildpathEntry.USER_ENTRY) {
String location = entries[i].getLocation();
if (location != null) {
empty = false;
bootEntries.add(location);
allStandard = allStandard
&& entries[i].getBuildpathProperty() == IRuntimeBuildpathEntry.STANDARD_ENTRY;
}
}
}
if (empty) {
return new String[0];
} else if (allStandard) {
return null;
} else {
return (String[]) bootEntries
.toArray(new String[bootEntries.size()]);
}
}
/**
* Returns three sets of entries which represent the boot buildpath
* specified in the launch configuration, as an array of three arrays of
* resolved strings. The first array represents the buildpath that should be
* prepended to the boot buildpath. The second array represents the main
* part of the boot buildpath -<code>null</code> represents the default
* bootbuildpath. The third array represents the buildpath that should be
* appended to the boot buildpath.
*
* @param configuration
* launch configuration
* @return a description of the boot buildpath specified by the given launch
* configuration.
* @exception CoreException
* if unable to retrieve the attribute
*
*/
public String[][] getBootpathExt(ILaunchConfiguration configuration)
throws CoreException {
String[][] bootpathInfo = new String[3][];
IRuntimeBuildpathEntry[] entries = ScriptRuntime
.computeUnresolvedRuntimeBuildpath(configuration);
List bootEntriesPrepend = new ArrayList();
int index = 0;
IRuntimeBuildpathEntry interpreterEnvironmentEntry = null;
IScriptProject project = getScriptProject(configuration);
IEnvironment environment = EnvironmentManager.getEnvironment(project);
while (interpreterEnvironmentEntry == null && index < entries.length) {
IRuntimeBuildpathEntry entry = entries[index++];
if (entry.getBuildpathProperty() == IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY
|| entry.getBuildpathProperty() == IRuntimeBuildpathEntry.STANDARD_ENTRY) {
if (ScriptRuntime.isInterpreterInstallReference(
getLanguageId(), environment.getId(), entry)) {
interpreterEnvironmentEntry = entry;
} else {
bootEntriesPrepend.add(entry);
}
}
}
IRuntimeBuildpathEntry[] bootEntriesPrep = ScriptRuntime
.resolveRuntimeBuildpath(
(IRuntimeBuildpathEntry[]) bootEntriesPrepend
.toArray(new IRuntimeBuildpathEntry[bootEntriesPrepend
.size()]), configuration);
String[] entriesPrep = null;
if (bootEntriesPrep.length > 0) {
entriesPrep = new String[bootEntriesPrep.length];
for (int i = 0; i < bootEntriesPrep.length; i++) {
entriesPrep[i] = bootEntriesPrep[i].getLocation();
}
}
if (interpreterEnvironmentEntry != null) {
List bootEntriesAppend = new ArrayList();
for (; index < entries.length; index++) {
IRuntimeBuildpathEntry entry = entries[index];
if (entry.getBuildpathProperty() == IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY) {
bootEntriesAppend.add(entry);
}
}
bootpathInfo[0] = entriesPrep;
IRuntimeBuildpathEntry[] bootEntriesApp = ScriptRuntime
.resolveRuntimeBuildpath(
(IRuntimeBuildpathEntry[]) bootEntriesAppend
.toArray(new IRuntimeBuildpathEntry[bootEntriesAppend
.size()]), configuration);
if (bootEntriesApp.length > 0) {
bootpathInfo[2] = new String[bootEntriesApp.length];
for (int i = 0; i < bootEntriesApp.length; i++) {
bootpathInfo[2][i] = bootEntriesApp[i].getLocation();
}
}
IInterpreterInstall install = getInterpreterInstall(configuration);
LibraryLocation[] libraryLocations = install.getLibraryLocations();
if (libraryLocations != null) {
// determine if explicit bootpath should be used
// TODO: this test does not tell us if the bootpath entries are
// different (could still be
// the same, as a non-bootpath entry on the
// InterpreterEnvironment may have been removed/added)
// We really need a way to ask a Interpreter type for its
// default bootpath library locations and
// compare that to the resolved entries for the
// "InterpreterEnvironmentEntry" to see if they
// are different (requires explicit bootpath)
if (!InterpreterRuntimeBuildpathEntryResolver
.isSameArchives(
libraryLocations,
install
.getInterpreterInstallType()
.getDefaultLibraryLocations(
install.getInstallLocation(),
install
.getEnvironmentVariables(),
null))) {
// resolve bootpath entries in InterpreterEnvironment entry
IRuntimeBuildpathEntry[] bootEntries = null;
if (interpreterEnvironmentEntry.getType() == IRuntimeBuildpathEntry.CONTAINER) {
IRuntimeBuildpathEntry bootEntry = ScriptRuntime
.newRuntimeContainerBuildpathEntry(
interpreterEnvironmentEntry.getPath(),
IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY,
getScriptProject(configuration));
bootEntries = ScriptRuntime
.resolveRuntimeBuildpathEntry(bootEntry,
configuration);
} else {
bootEntries = ScriptRuntime
.resolveRuntimeBuildpathEntry(
interpreterEnvironmentEntry,
configuration);
}
// non-default InterpreterEnvironment libraries - use
// explicit bootpath only
String[] bootpath = new String[bootEntriesPrep.length
+ bootEntries.length + bootEntriesApp.length];
if (bootEntriesPrep.length > 0) {
System.arraycopy(bootpathInfo[0], 0, bootpath, 0,
bootEntriesPrep.length);
}
int dest = bootEntriesPrep.length;
for (int i = 0; i < bootEntries.length; i++) {
bootpath[dest] = bootEntries[i].getLocation();
dest++;
}
if (bootEntriesApp.length > 0) {
System.arraycopy(bootpathInfo[2], 0, bootpath, dest,
bootEntriesApp.length);
}
bootpathInfo[0] = null;
bootpathInfo[1] = bootpath;
bootpathInfo[2] = null;
}
}
} else {
if (entriesPrep == null) {
bootpathInfo[1] = new String[0];
} else {
bootpathInfo[1] = entriesPrep;
}
}
return bootpathInfo;
}
/**
* Returns the Script project specified by the given launch configuration,
* or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the Script project specified by the given launch configuration,
* or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public static IScriptProject getScriptProject(
ILaunchConfiguration configuration) throws CoreException {
String projectName = getScriptProjectName(configuration);
if (projectName != null) {
projectName = projectName.trim();
if (projectName.length() > 0) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(projectName);
IScriptProject scriptProject = DLTKCore.create(project);
if (scriptProject != null && scriptProject.exists()) {
return scriptProject;
}
}
}
return null;
}
/**
* Returns the Script project name specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the Script project name specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public static String getScriptProjectName(ILaunchConfiguration configuration)
throws CoreException {
return configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME,
(String) null);
}
/**
* Returns the main type name specified by the given launch configuration,
* or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the main type name specified by the given launch configuration,
* or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public static String getMainScriptName(ILaunchConfiguration configuration)
throws CoreException {
String script = configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME,
(String) null);
if (script == null) {
return null;
}
return VariablesPlugin.getDefault().getStringVariableManager()
.performStringSubstitution(script);
}
/**
* Returns the program arguments specified by the given launch
* configuration, as a string. The returned string is empty if no program
* arguments are specified.
*
* @param configuration
* launch configuration
* @return the program arguments specified by the given launch
* configuration, possibly an empty string
* @exception CoreException
* if unable to retrieve the attribute
*/
public String[] getScriptArguments(ILaunchConfiguration configuration)
throws CoreException {
String arguments = configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_SCRIPT_ARGUMENTS, ""); //$NON-NLS-1$
String args = VariablesPlugin.getDefault().getStringVariableManager()
.performStringSubstitution(arguments);
return DebugPlugin.parseArguments(args);
}
/**
* Returns the Interpreter arguments specified by the given launch
* configuration, as a string. The returned string is empty if no
* Interpreter arguments are specified.
*
* @param configuration
* launch configuration
* @return the Interpreter arguments specified by the given launch
* configuration, possibly an empty string
* @exception CoreException
* if unable to retrieve the attribute
*/
protected final String[] getInterpreterArguments(
ILaunchConfiguration configuration) throws CoreException {
String arguments = configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_INTERPRETER_ARGUMENTS,
""); //$NON-NLS-1$
String args = VariablesPlugin.getDefault().getStringVariableManager()
.performStringSubstitution(arguments);
return DebugPlugin.parseArguments(args);
}
/**
* Returns the Map of Interpreter-specific attributes specified by the given
* launch configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the <code>Map</code> of Interpreter-specific attributes
* @exception CoreException
* if unable to retrieve the attribute
*/
public Map getInterpreterSpecificAttributesMap(
ILaunchConfiguration configuration) throws CoreException {
Map map = configuration
.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_INTERPRETER_INSTALL_TYPE_SPECIFIC_ATTRS_MAP,
(Map) null);
return map;
}
/**
* Returns the working directory specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the working directory specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public String getWorkingDirectory(ILaunchConfiguration configuration,
IEnvironment environment) throws CoreException {
return verifyWorkingDirectory(configuration, environment);
}
/**
* Returns the working directory path specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the working directory path specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public IPath getWorkingDirectoryPath(ILaunchConfiguration configuration)
throws CoreException {
String path = configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null);
if (path != null) {
if (path.trim().length() == 0) {
return null;
}
IStringVariableManager manager = VariablesPlugin.getDefault()
.getStringVariableManager();
try {
path = manager.performStringSubstitution(path, false);
return new Path(path);
} catch (CoreException e) {
DLTKLaunchingPlugin.log(e);
}
}
return null;
}
/**
* Verifies the working directory specified by the given launch
* configuration exists, and returns the working directory, or
* <code>null</code> if none is specified.
*
* @param configuration
* launch configuration
* @return the working directory specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public String verifyWorkingDirectory(ILaunchConfiguration configuration,
IEnvironment environment) throws CoreException {
IPath path = getWorkingDirectoryPath(configuration);
if (path == null) {
IPath dirPath = getDefaultWorkingDirectory(configuration);
IFileHandle dir = environment.getFile(dirPath);
if (dir != null) {
if (!dir.isDirectory()) {
abort(
MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
new String[] { dir.toString() }),
null,
ScriptLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
}
return dir.toOSString();
}
} else {
if (path.isAbsolute()) {
IFileHandle dir = environment.getFile(path);
if (dir.isDirectory()) {
return dir.toOSString();
}
// This may be a workspace relative path returned by a variable.
// However variable paths start with a slash and thus are
// thought to
// be absolute
IResource res = ResourcesPlugin.getWorkspace().getRoot()
.findMember(path);
if (res instanceof IContainer && res.exists()) {
return res.getLocation().toOSString();
}
abort(
MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
new String[] { path.toString() }),
null,
ScriptLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
} else {
IResource res = ResourcesPlugin.getWorkspace().getRoot()
.findMember(path);
if (res instanceof IContainer && res.exists()) {
return res.getLocation().toOSString();
}
abort(
MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
new String[] { path.toString() }),
null,
ScriptLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
}
}
return null;
}
/**
* Verifies a main script name is specified by the given launch
* configuration, and returns the script type name.
*
* @param configuration
* launch configuration
* @return the main type name specified by the given launch configuration
* @exception CoreException
* if unable to retrieve the attribute or the attribute is
* unspecified
*/
public String verifyMainScriptName(ILaunchConfiguration configuration)
throws CoreException {
final String name = getMainScriptName(configuration);
if (name == null) {
abort(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Main_type_not_specified_11,
null,
ScriptLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_SCRIPT);
}
return name;
}
// Project path + script path
protected String getScriptLaunchPath(ILaunchConfiguration configuration,
IEnvironment scriptEnvironment) throws CoreException {
String mainScriptName = verifyMainScriptName(configuration);
if (mainScriptName.length() == 0) {
return null;
}
String loc = getProjectLocation(configuration);
IPath environmentLocation = new Path(loc).append(mainScriptName);
IFileHandle file = scriptEnvironment.getFile(environmentLocation);
if (file.exists()) {
return file.toOSString();
}
return environmentLocation.toOSString();
}
// Should be overriden in for any language
protected InterpreterConfig createInterpreterConfig(
ILaunchConfiguration configuration, ILaunch launch)
throws CoreException {
// Validation already included
IEnvironment scriptEnvironment = getScriptEnvironment(configuration);
IExecutionEnvironment scriptExecEnvironment = (IExecutionEnvironment) scriptEnvironment
.getAdapter(IExecutionEnvironment.class);
String scriptLaunchPath = getScriptLaunchPath(configuration,
scriptEnvironment);
// if (scriptLaunchPath == null) {
// return null;
// }
final IPath workingDirectory = new Path(getWorkingDirectory(
configuration, scriptEnvironment));
IPath mainScript = null;//
if (scriptLaunchPath != null) {
mainScript = new Path(scriptLaunchPath);
}
InterpreterConfig config = new InterpreterConfig(scriptEnvironment,
mainScript, workingDirectory);
// Script arguments
String[] scriptArgs = getScriptArguments(configuration);
config.addScriptArgs(scriptArgs);
// Interpreter argument
String[] interpreterArgs = getInterpreterArguments(configuration);
config.addInterpreterArgs(interpreterArgs);
// Environment
// config.addEnvVars(DebugPlugin.getDefault().getLaunchManager()
// .getNativeEnvironmentCasePreserved());
Map configEnv = configuration.getAttribute(
ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, new HashMap());
// build base environment
Map env = scriptExecEnvironment.getEnvironmentVariables(false);
boolean append = configuration.getAttribute(
ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
if (configEnv != null) {
for (Iterator iterator = configEnv.keySet().iterator(); iterator
.hasNext();) {
String name = (String) iterator.next();
if (!env.containsKey(name) || !append) {
env.put(name, configEnv.get(name));
}
}
}
config.addEnvVars(env);
return config;
}
private IEnvironment getScriptEnvironment(ILaunchConfiguration configuration)
throws CoreException {
IScriptProject scriptProject = AbstractScriptLaunchConfigurationDelegate
.getScriptProject(configuration);
return EnvironmentManager.getEnvironment(scriptProject);
}
protected void validateLaunchConfiguration(
ILaunchConfiguration configuration, String mode, IProject project)
throws CoreException {
// Validation of available debugging engine
if (ILaunchManager.DEBUG_MODE.equals(mode)) {
if (!DebuggingEngineManager.getInstance()
.hasSelectedDebuggingEngine(project,
getNatureId(configuration))) {
abort(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_debuggingEngineNotSelected,
null,
ScriptLaunchConfigurationConstants.ERR_NO_DEFAULT_DEBUGGING_ENGINE);
}
}
}
public void launch(ILaunchConfiguration configuration, String mode,
ILaunch launch, IProgressMonitor monitor) throws CoreException {
try {
IProject project = ScriptRuntime.getScriptProject(configuration)
.getProject();
if (monitor == null) {
monitor = new NullProgressMonitor();
}
monitor
.beginTask(
MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_startingLaunchConfiguration,
new Object[] { configuration
.getName() }), 10);
if (monitor.isCanceled()) {
return;
}
monitor
.subTask(MessageFormat
.format(
LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_validatingLaunchConfiguration,
new Object[] { configuration.getName() }));
validateLaunchConfiguration(configuration, mode, project);
monitor.worked(1);
if (monitor.isCanceled()) {
return;
}
// Getting InterpreterConfig
monitor
.subTask(LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_generatingInterpreterConfiguration);
final InterpreterConfig config = createInterpreterConfig(
configuration, launch);
if (config == null) {
monitor.setCanceled(true);
return;
}
if (monitor.isCanceled()) {
return;
}
monitor.worked(1);
// Getting IInterpreterRunner
monitor
.subTask(LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_gettingInterpreterRunner);
final IInterpreterRunner runner = getInterpreterRunner(
configuration, mode);
if (monitor.isCanceled()) {
return;
}
monitor.worked(1);
// Real run
monitor
.subTask(LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_executingRunner);
runRunner(configuration, runner, config, launch,
new SubProgressMonitor(monitor, 7));
} catch (CoreException e) {
tryHandleStatus(e, this);
} finally {
monitor.done();
}
}
protected static void tryHandleStatus(CoreException e, Object source)
throws CoreException {
final IStatus status = e.getStatus();
final IStatusHandler handler = DebugPlugin.getDefault()
.getStatusHandler(status);
if (handler == null) {
throw e;
}
handler.handleStatus(status, source);
}
protected void runRunner(ILaunchConfiguration configuration,
IInterpreterRunner runner, InterpreterConfig config,
ILaunch launch, IProgressMonitor monitor) throws CoreException {
try {
runner.run(config, launch, monitor);
} catch (CoreException e) {
tryHandleStatus(e, runner);
}
}
protected String getWorkingDir(ILaunchConfiguration configuration,
IEnvironment environment) throws CoreException {
return verifyWorkingDirectory(configuration, environment);
}
protected IPath[] createBuildPath(ILaunchConfiguration configuration)
throws CoreException {
List paths = new ArrayList();
// Buildpath
String[] buildpath = getBuildpath(configuration);
for (int i = 0; i < buildpath.length; i++) {
paths.add(new Path(buildpath[i]));
}
// Bootpath
String[] bootpath = getBootpath(configuration);
if (bootpath != null) {
// it may be null, if bootpath is standard
for (int i = 0; i < bootpath.length; i++) {
paths.add(new Path(bootpath[i]));
}
}
return (IPath[]) paths.toArray(new IPath[paths.size()]);
}
protected String createNativeBuildPath(IPath[] paths) {
// TODO: refactor this
StringBuffer sb = new StringBuffer();
for (int i = 0; i < paths.length; ++i) {
sb.append(paths[i].toOSString());
if (i < paths.length - 1) {
sb.append(Path.DEVICE_SEPARATOR);
}
}
return sb.toString();
}
protected IProject[] getBuildOrder(ILaunchConfiguration configuration,
String mode) throws CoreException {
return fOrderedProjects;
}
protected IProject[] getProjectsForProblemSearch(
ILaunchConfiguration configuration, String mode)
throws CoreException {
return fOrderedProjects;
}
protected boolean isLaunchProblem(IMarker problemMarker)
throws CoreException {
return super.isLaunchProblem(problemMarker)
&& problemMarker.getType().equals(
IScriptModelMarker.DLTK_MODEL_PROBLEM_MARKER);
}
public boolean preLaunchCheck(ILaunchConfiguration configuration,
String mode, IProgressMonitor monitor) throws CoreException {
if (monitor != null) {
monitor
.subTask(LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_20);
}
fOrderedProjects = null;
IScriptProject scriptProject = ScriptRuntime
.getScriptProject(configuration);
if (scriptProject != null) {
fOrderedProjects = computeReferencedBuildOrder(new IProject[] { scriptProject
.getProject() });
}
return super.preLaunchCheck(configuration, mode, monitor);
}
protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration) {
// TODO
return new IBreakpoint[] {};
}
/**
* Returns the Interpreter runner for the given launch mode to use when
* launching the given configuration.
*
* @param configuration
* launch configuration
* @param mode
* launch node
* @param project
* project containing the launched resource
* @return Interpreter runner to use when launching the given configuration
* in the given mode
* @throws CoreException
* if a Interpreter runner cannot be determined
*
*/
public IInterpreterRunner getInterpreterRunner(
ILaunchConfiguration configuration, String mode)
throws CoreException {
final IInterpreterInstall install = verifyInterpreterInstall(configuration);
final IInterpreterRunner runner = install.getInterpreterRunner(mode);
if (runner == null) {
abort(
MessageFormat.format(
LaunchingMessages.InterpreterRunnerDoesntExist,
new String[] { install.getName(), mode }),
null,
ScriptLaunchConfigurationConstants.ERR_INTERPRETER_RUNNER_DOES_NOT_EXIST);
}
return runner;
}
/**
* Returns an array of environment variables to be used when launching the
* given configuration or <code>null</code> if unspecified.
*
* @param configuration
* launch configuration
* @throws CoreException
* if unable to access associated attribute or if unable to
* resolve a variable in an environment variable's value
*
*/
public String[] getEnvironment(ILaunchConfiguration configuration)
throws CoreException {
return DebugPlugin.getDefault().getLaunchManager().getEnvironment(
configuration);
}
/**
* Returns the default working directory for the given launch configuration,
* or <code>null</code> if none. Subclasses may override as necessary.
*
* @param configuration
* @return default working directory or <code>null</code> if none
* @throws CoreException
* if an exception occurs computing the default working
* directory
*
*/
protected IPath getDefaultWorkingDirectory(
ILaunchConfiguration configuration) throws CoreException {
// default working directory is the project if this config has a project
IScriptProject scriptProject = getScriptProject(configuration);
if (scriptProject != null) {
// IProject project = scriptProject.getProject();
// URI uri = project.getLocationURI();
// IPath path = null;
// if (uri != null) {
// path = new Path(uri.getPath());
// }
// else {
// path = project.getLocation();
// }
IEnvironment environment = EnvironmentManager
.getEnvironment(scriptProject);
String mainScriptName = verifyMainScriptName(configuration);
if (mainScriptName.length() == 0) {
return new Path(getProjectLocation(configuration));
}
String loc = getProjectLocation(configuration);
IPath environmentLocation = new Path(loc).append(mainScriptName);
IFileHandle file = environment.getFile(environmentLocation);
if (file.exists()) {
return environmentLocation.removeLastSegments(1);
}
}
return null;
}
private String getProjectLocation(ILaunchConfiguration configuration)
throws CoreException {
IProject project = getScriptProject(configuration).getProject();
String loc = null;
URI location = project.getLocationURI();
if (location == null) {
loc = project.getLocation().toOSString();
return null;
} else {
loc = location.getPath();
}
return loc;
}
protected String getNatureId(ILaunchConfiguration configuration)
throws CoreException {
return configuration.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_SCRIPT_NATURE,
(String) null);
}
abstract public String getLanguageId();
public static ISourceModule getSourceModule(
ILaunchConfiguration configuration) throws CoreException {
String projectName = AbstractScriptLaunchConfigurationDelegate
.getScriptProjectName(configuration);
String mainScriptName = AbstractScriptLaunchConfigurationDelegate
.getMainScriptName(configuration);
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(
projectName);
IFile script = project.getFile(mainScriptName);
ISourceModule module = (ISourceModule) DLTKCore.create(script);
return module;
}
}