package org.rubypeople.rdt.launching;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IContainer;
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.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
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.model.LaunchConfigurationDelegate;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.internal.launching.LaunchingMessages;
import org.rubypeople.rdt.internal.launching.LaunchingPlugin;
public abstract class AbstractRubyLaunchConfigurationDelegate extends
LaunchConfigurationDelegate {
/**
* 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, LaunchingPlugin
.getUniqueIdentifier(), code, message, exception));
}
/**
* Returns the VM arguments specified by the given launch configuration, as
* a string. The returned string is empty if no VM arguments are specified.
*
* @param configuration
* launch configuration
* @return the VM arguments specified by the given launch configuration,
* possibly an empty string
* @exception CoreException
* if unable to retrieve the attribute
*/
public String getVMArguments(ILaunchConfiguration configuration) throws CoreException {
String arguments = configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, ""); //$NON-NLS-1$
String args = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(arguments);
return args;
}
/**
* 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 getProgramArguments(ILaunchConfiguration configuration)
throws CoreException {
String arguments = configuration.getAttribute(
IRubyLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, ""); //$NON-NLS-1$
return VariablesPlugin.getDefault().getStringVariableManager()
.performStringSubstitution(arguments);
}
/**
* 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
* @since 0.9.0
*/
public String[] getEnvironment(ILaunchConfiguration configuration) throws CoreException {
return DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);
}
/**
* 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 File verifyWorkingDirectory(ILaunchConfiguration configuration)
throws CoreException {
IPath path = getWorkingDirectoryPath(configuration);
if (path == null) {
File dir = getDefaultWorkingDirectory(configuration);
if (dir != null) {
if (!dir.isDirectory()) {
abort(
MessageFormat.format(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
dir.toString()),
null,
IRubyLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
}
return dir;
}
} else {
if (path.isAbsolute()) {
File dir = new File(path.toOSString());
if (dir.isDirectory()) {
return dir;
}
// 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().toFile();
}
abort(
MessageFormat
.format(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
path.toString()),
null,
IRubyLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
} else {
IResource res = ResourcesPlugin.getWorkspace().getRoot()
.findMember(path);
if (res instanceof IContainer && res.exists()) {
return res.getLocation().toFile();
}
abort(
MessageFormat
.format(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
path.toString()),
null,
IRubyLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
}
}
return null;
}
/**
* 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(
IRubyLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null);
if (path != null && path.length() > 0) {
path = VariablesPlugin.getDefault().getStringVariableManager()
.performStringSubstitution(path);
return new Path(path);
}
return null;
}
/**
* 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
* @since 0.9.0
*/
protected File getDefaultWorkingDirectory(ILaunchConfiguration configuration) throws CoreException {
// default working directory is the project if this config has a project
IRubyProject rp = getRubyProject(configuration);
if (rp != null) {
IProject p = rp.getProject();
return p.getLocation().toFile();
}
return null;
}
/**
* Returns the Ruby project specified by the given launch configuration, or
* <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the Ruby project specified by the given launch configuration, or
* <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public IRubyProject getRubyProject(ILaunchConfiguration configuration)
throws CoreException {
String projectName = getRubyProjectName(configuration);
if (projectName != null) {
projectName = projectName.trim();
if (projectName.length() > 0) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(projectName);
IRubyProject rubyProject = RubyCore.create(project);
if (rubyProject != null && rubyProject.exists()) {
return rubyProject;
}
}
}
return null;
}
/**
* Returns the Ruby project name specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the Ruby project name specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public String getRubyProjectName(ILaunchConfiguration configuration)
throws CoreException {
return configuration.getAttribute(
IRubyLaunchConfigurationConstants.ATTR_PROJECT_NAME,
(String) null);
}
/**
* Returns the Map of VM-specific attributes specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the <code>Map</code> of VM-specific attributes
* @exception CoreException
* if unable to retrieve the attribute
*/
public Map getVMSpecificAttributesMap(ILaunchConfiguration configuration)
throws CoreException {
Map map = configuration
.getAttribute(
IRubyLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP,
(Map) null);
return map;
}
/**
* Returns the VM runner for the given launch mode to use when launching the
* given configuration.
*
* @param configuration launch configuration
* @param mode launch node
* @return VM runner to use when launching the given configuration in the given mode
* @throws CoreException if a VM runner cannot be determined
* @since 0.9.0
*/
public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException {
IVMInstall vm = verifyVMInstall(configuration);
IVMRunner runner = vm.getVMRunner(mode);
if (runner == null) {
abort(MessageFormat.format(LaunchingMessages.JavaLocalApplicationLaunchConfigurationDelegate_0, vm.getName(), mode), null, IRubyLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST);
}
return runner;
}
/**
* Verifies the VM install specified by the given launch configuration
* exists and returns the VM install.
*
* @param configuration
* launch configuration
* @return the VM 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 IVMInstall verifyVMInstall(ILaunchConfiguration configuration)
throws CoreException {
IVMInstall vm = getVMInstall(configuration);
if (vm == null) {
abort(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_The_specified_JRE_installation_does_not_exist_4,
null,
IRubyLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST);
}
File location = vm.getInstallLocation();
if (location == null) {
abort(
MessageFormat
.format(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_JRE_home_directory_not_specified_for__0__5,
vm.getName()),
null,
IRubyLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST);
}
if (!location.exists()) {
abort(
MessageFormat
.format(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_JRE_home_directory_for__0__does_not_exist___1__6,
vm.getName(), location.getAbsolutePath()),
null,
IRubyLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST);
}
return vm;
}
/**
* Returns the VM install specified by the given launch configuration, or
* <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the VM install specified by the given launch configuration, or
* <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public IVMInstall getVMInstall(ILaunchConfiguration configuration)
throws CoreException {
return RubyRuntime.computeVMInstall(configuration);
}
/**
* Verifies a main type name is specified by the given launch configuration,
* and returns the main 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 verifyFileToLaunch(ILaunchConfiguration configuration) throws CoreException {
String name = getFileToLaunch(configuration);
if (name == null) {
abort(
LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Main_type_not_specified_11,
null,
IRubyLaunchConfigurationConstants.ERR_UNSPECIFIED_FILE_NAME);
}
File file = new File(name);
if (file.exists() && !file.isDirectory()) { // it was an absolute path and the file exists, so just return it
return name;
}
IPath workingDir = getWorkingDirectoryPath(configuration);
if (workingDir != null) {
IPath fileToLaunch = workingDir.append(name);
file = fileToLaunch.toFile();
if (file.exists() && !file.isDirectory())
return name;
}
IRubyProject project = getRubyProject(configuration);
if (project != null) {
IPath fileToLaunch = project.getProject().getLocation().append(name);
file = fileToLaunch.toFile();
if (file.exists() && !file.isDirectory())
return fileToLaunch.toOSString();
}
abort(
"File to launch does not exist: '" + name + "'",
null,
IRubyLaunchConfigurationConstants.ERR_UNSPECIFIED_FILE_NAME);
return 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 String getFileToLaunch(ILaunchConfiguration configuration)
throws CoreException {
String mainType = configuration.getAttribute(
IRubyLaunchConfigurationConstants.ATTR_FILE_NAME,
(String) null);
if (mainType == null) {
return null;
}
return VariablesPlugin.getDefault().getStringVariableManager()
.performStringSubstitution(mainType);
}
protected void setDefaultSourceLocator(ILaunch launch,
ILaunchConfiguration configuration) {
// TODO Actually set up the source locator!
}
/**
* Returns the entries that should appear on the user portion of the
* classpath as specified by the given launch configuration, as an array of
* resolved strings. The returned array is empty if no classpath is
* specified.
*
* @param configuration
* launch configuration
* @return the classpath specified by the given launch configuration,
* possibly an empty array
* @exception CoreException
* if unable to retrieve the attribute
*/
public String[] getLoadpath(ILaunchConfiguration configuration)
throws CoreException {
IRuntimeLoadpathEntry[] entries = RubyRuntime
.computeUnresolvedRuntimeLoadpath(configuration);
entries = RubyRuntime.resolveRuntimeLoadpath(entries, configuration);
List<String> userEntries = new ArrayList<String>(entries.length);
for (int i = 0; i < entries.length; i++) {
if (entries[i].getLoadpathProperty() == IRuntimeLoadpathEntry.USER_CLASSES) {
String location = entries[i].getLocation();
if (location != null) {
userEntries.add(location);
}
}
}
return userEntries.toArray(new String[userEntries.size()]);
}
public boolean getIsSudo(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_IS_SUDO, false);
}
public String getSudoMessage(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_SUDO_MESSAGE, (String) null);
}
/**
* Returns the VM connector identifier specified by the given launch
* configuration, or <code>null</code> if none.
*
* @param configuration
* launch configuration
* @return the VM connector identifier specified by the given launch
* configuration, or <code>null</code> if none
* @exception CoreException
* if unable to retrieve the attribute
*/
public String getVMConnectorId(ILaunchConfiguration configuration)
throws CoreException {
return configuration.getAttribute(
IRubyLaunchConfigurationConstants.ATTR_VM_CONNECTOR,
(String) null);
}
}