|
From: <caw...@us...> - 2007-01-19 20:07:34
|
Revision: 1817
http://svn.sourceforge.net/rubyeclipse/?rev=1817&view=rev
Author: cawilliams
Date: 2007-01-19 12:07:32 -0800 (Fri, 19 Jan 2007)
Log Message:
-----------
build still ain't broken - it's a miracle!
Modified Paths:
--------------
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingMessages.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingPlugin.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IRubyLaunchConfigurationConstants.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyRuntime.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/DefaultEntryResolver.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RuntimeLoadpathProvider.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/AbstractRubyLaunchConfigurationDelegate.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyLaunchDelegate.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/StandardLoadpathProvider.java
Added: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/DefaultEntryResolver.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/DefaultEntryResolver.java (rev 0)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/DefaultEntryResolver.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.launching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.rubypeople.rdt.core.ILoadpathEntry;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.launching.IRuntimeLoadpathEntry;
+import org.rubypeople.rdt.launching.IRuntimeLoadpathEntry2;
+import org.rubypeople.rdt.launching.IRuntimeLoadpathEntryResolver;
+import org.rubypeople.rdt.launching.IVMInstall;
+import org.rubypeople.rdt.launching.RubyRuntime;
+
+/**
+ * Default resolver for a contributed classpath entry
+ */
+public class DefaultEntryResolver implements IRuntimeLoadpathEntryResolver {
+ /* (non-Rubydoc)
+ * @see org.eclipse.jdt.launching.IRuntimeLoadpathEntryResolver#resolveRuntimeLoadpathEntry(org.eclipse.jdt.launching.IRuntimeLoadpathEntry, org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ public IRuntimeLoadpathEntry[] resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry entry, ILaunchConfiguration configuration) throws CoreException {
+ IRuntimeLoadpathEntry2 entry2 = (IRuntimeLoadpathEntry2)entry;
+ IRuntimeLoadpathEntry[] entries = entry2.getRuntimeLoadpathEntries(configuration);
+ List resolved = new ArrayList();
+ for (int i = 0; i < entries.length; i++) {
+ IRuntimeLoadpathEntry[] temp = RubyRuntime.resolveRuntimeLoadpathEntry(entries[i], configuration);
+ for (int j = 0; j < temp.length; j++) {
+ resolved.add(temp[j]);
+ }
+ }
+ return (IRuntimeLoadpathEntry[]) resolved.toArray(new IRuntimeLoadpathEntry[resolved.size()]);
+ }
+ /* (non-Rubydoc)
+ * @see org.eclipse.jdt.launching.IRuntimeLoadpathEntryResolver#resolveRuntimeLoadpathEntry(org.eclipse.jdt.launching.IRuntimeLoadpathEntry, org.eclipse.jdt.core.IRubyProject)
+ */
+ public IRuntimeLoadpathEntry[] resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry entry, IRubyProject project) throws CoreException {
+ IRuntimeLoadpathEntry2 entry2 = (IRuntimeLoadpathEntry2)entry;
+ IRuntimeLoadpathEntry[] entries = entry2.getRuntimeLoadpathEntries(null);
+ List resolved = new ArrayList();
+ for (int i = 0; i < entries.length; i++) {
+ IRuntimeLoadpathEntry[] temp = RubyRuntime.resolveRuntimeLoadpathEntry(entries[i], project);
+ for (int j = 0; j < temp.length; j++) {
+ resolved.add(temp[j]);
+ }
+ }
+ return (IRuntimeLoadpathEntry[]) resolved.toArray(new IRuntimeLoadpathEntry[resolved.size()]);
+ }
+
+ /* (non-Rubydoc)
+ * @see org.eclipse.jdt.launching.IRuntimeLoadpathEntryResolver#resolveVMInstall(org.eclipse.jdt.core.ILoadpathEntry)
+ */
+ public IVMInstall resolveVMInstall(ILoadpathEntry entry) throws CoreException {
+ return null;
+ }
+}
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingMessages.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingMessages.java 2007-01-19 19:13:42 UTC (rev 1816)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingMessages.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -67,6 +67,13 @@
public static String DefaultProjectLoadpathEntry_4;
public static String DefaultProjectLoadpathEntry_2;
public static String DefaultProjectLoadpathEntry_3;
+ public static String JavaRuntime_26;
+ public static String JavaRuntime_31;
+ public static String JavaRuntime_32;
+ public static String LaunchingPlugin_32;
+ public static String JavaRuntime_Classpath_references_non_existant_archive___0__4;
+ public static String JavaRuntime_Classpath_references_non_existant_project___0__3;
+ public static String JavaRuntime_Could_not_resolve_classpath_container___0__1;
private LaunchingMessages() {}
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingPlugin.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingPlugin.java 2007-01-19 19:13:42 UTC (rev 1816)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/LaunchingPlugin.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -6,6 +6,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -25,6 +26,8 @@
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
@@ -32,6 +35,7 @@
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
import org.rubypeople.rdt.core.RubyCore;
+import org.rubypeople.rdt.launching.IRuntimeLoadpathEntry2;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -45,6 +49,17 @@
public static final String PLUGIN_ID = "org.rubypeople.rdt.launching"; //$NON-NLS-1$
/**
+ * Runtime classpath extensions
+ */
+ private HashMap fClasspathEntryExtensions = null;
+
+ /**
+ * Identifier for 'runtimeLoadpathEntries' extension point
+ */
+ public static final String ID_EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRIES = "runtimeLoadpathEntries"; //$NON-NLS-1$
+
+
+ /**
* Mapping of top-level VM installation directories to library info for that
* VM.
*/
@@ -67,7 +82,7 @@
plugin = this;
}
- public static Plugin getDefault() {
+ public static LaunchingPlugin getDefault() {
return plugin;
}
@@ -383,4 +398,34 @@
}
return (String[])paths.toArray(new String[paths.size()]);
}
+
+ /**
+ * Returns a new runtime classpath entry of the specified type.
+ *
+ * @param id extension type id
+ * @return new uninitialized runtime classpath entry
+ * @throws CoreException if unable to create an entry
+ */
+ public IRuntimeLoadpathEntry2 newRuntimeLoadpathEntry(String id) throws CoreException {
+ if (fClasspathEntryExtensions == null) {
+ initializeRuntimeLoadpathExtensions();
+ }
+ IConfigurationElement config = (IConfigurationElement) fClasspathEntryExtensions.get(id);
+ if (config == null) {
+ abort(MessageFormat.format(LaunchingMessages.LaunchingPlugin_32, new String[]{id}), null);
+ }
+ return (IRuntimeLoadpathEntry2) config.createExecutableExtension("class"); //$NON-NLS-1$
+ }
+
+ /**
+ * Loads runtime classpath extensions
+ */
+ private void initializeRuntimeLoadpathExtensions() {
+ IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(LaunchingPlugin.PLUGIN_ID, ID_EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRIES);
+ IConfigurationElement[] configs= extensionPoint.getConfigurationElements();
+ fClasspathEntryExtensions = new HashMap(configs.length);
+ for (int i= 0; i < configs.length; i++) {
+ fClasspathEntryExtensions.put(configs[i].getAttribute("id"), configs[i]); //$NON-NLS-1$
+ }
+ }
}
Added: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RuntimeLoadpathProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RuntimeLoadpathProvider.java (rev 0)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RuntimeLoadpathProvider.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.launching;
+
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.rubypeople.rdt.launching.IRuntimeLoadpathEntry;
+import org.rubypeople.rdt.launching.IRuntimeLoadpathProvider;
+
+/**
+ * Proxy to a runtime classpath provider extension.
+ */
+public class RuntimeLoadpathProvider implements IRuntimeLoadpathProvider {
+
+ private IConfigurationElement fConfigurationElement;
+
+ private IRuntimeLoadpathProvider fDelegate;
+
+ /**
+ * Constructs a new resolver on the given configuration element
+ */
+ public RuntimeLoadpathProvider(IConfigurationElement element) {
+ fConfigurationElement = element;
+ }
+
+ /**
+ * Returns the resolver delegate (and creates if required)
+ */
+ protected IRuntimeLoadpathProvider getProvider() throws CoreException {
+ if (fDelegate == null) {
+ fDelegate = (IRuntimeLoadpathProvider)fConfigurationElement.createExecutableExtension("class"); //$NON-NLS-1$
+ }
+ return fDelegate;
+ }
+
+ public String getIdentifier() {
+ return fConfigurationElement.getAttribute("id"); //$NON-NLS-1$
+ }
+ /**
+ * @see IRuntimeLoadpathProvider#computeUnresolvedLoadpath(ILaunchConfiguration)
+ */
+ public IRuntimeLoadpathEntry[] computeUnresolvedLoadpath(ILaunchConfiguration configuration) throws CoreException {
+ return getProvider().computeUnresolvedLoadpath(configuration);
+ }
+
+ /**
+ * @see IRuntimeLoadpathProvider#resolveLoadpath(IRuntimeLoadpathEntry[], ILaunchConfiguration)
+ */
+ public IRuntimeLoadpathEntry[] resolveLoadpath(IRuntimeLoadpathEntry[] entries, ILaunchConfiguration configuration) throws CoreException {
+ return getProvider().resolveLoadpath(entries, configuration);
+ }
+
+}
Added: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/AbstractRubyLaunchConfigurationDelegate.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/AbstractRubyLaunchConfigurationDelegate.java (rev 0)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/AbstractRubyLaunchConfigurationDelegate.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -0,0 +1,437 @@
+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,
+ new String[]{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,
+ new String[]{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,
+ new String[]{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 = 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, new String[]{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,
+ new String[]{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,
+ new String[]{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 {
+ // TODO Verify file exists and is a file (not directory)
+ String name = getFileToLaunch(configuration);
+ if (name == null) {
+ abort(
+ LaunchingMessages.AbstractJavaLaunchConfigurationDelegate_Main_type_not_specified_11,
+ null,
+ IRubyLaunchConfigurationConstants.ERR_UNSPECIFIED_FILE_NAME);
+ }
+ return name;
+ }
+
+ /**
+ * 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 userEntries = new ArrayList(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 (String[]) userEntries.toArray(new String[userEntries.size()]);
+ }
+}
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IRubyLaunchConfigurationConstants.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IRubyLaunchConfigurationConstants.java 2007-01-19 19:13:42 UTC (rev 1816)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IRubyLaunchConfigurationConstants.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -6,11 +6,29 @@
/**
* Status code indicating a launch configuration does not
+ * specify a file to launch.
+ */
+ public static final int ERR_UNSPECIFIED_FILE_NAME = 101;
+
+ /**
+ * Status code indicating a launch configuration does not
* specify a VM Install
*/
public static final int ERR_UNSPECIFIED_VM_INSTALL = 103;
/**
+ * Status code indicating a launch configuration's VM install
+ * could not be found.
+ */
+ public static final int ERR_VM_INSTALL_DOES_NOT_EXIST = 105;
+
+ /**
+ * Status code indicating a VM runner could not be located
+ * for the VM install specified by a launch configuration.
+ */
+ public static final int ERR_VM_RUNNER_DOES_NOT_EXIST = 106;
+
+ /**
* Status code indicating the project associated with
* a launch configuration is not a Ruby project.
*/
@@ -92,4 +110,72 @@
*/
public static final String ATTR_VM_INSTALL_TYPE = LaunchingPlugin.getUniqueIdentifier() + ".VM_INSTALL_TYPE_ID"; //$NON-NLS-1$
+ /**
+ * Launch configuration attribute key. The value is a string specifying
+ * program arguments for a Ruby launch configuration, as they should appear
+ * on the command line.
+ */
+ public static final String ATTR_PROGRAM_ARGUMENTS = LaunchingPlugin.getUniqueIdentifier() + ".PROGRAM_ARGUMENTS"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is a string specifying
+ * VM arguments for a Ruby launch configuration, as they should appear
+ * on the command line.
+ */
+ public static final String ATTR_VM_ARGUMENTS = LaunchingPlugin.getUniqueIdentifier() + ".VM_ARGUMENTS"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is a string specifying a
+ * path to the working directory to use when launching a local VM.
+ * When specified as an absolute path, the path represents a path in the local
+ * file system. When specified as a full path, the path represents a workspace
+ * relative path. When unspecified, the working directory defaults to the project
+ * associated with a launch configuration. When no project is associated with a
+ * launch configuration, the working directory is inherited from the current
+ * process.
+ */
+ public static final String ATTR_WORKING_DIRECTORY = LaunchingPlugin.getUniqueIdentifier() + ".WORKING_DIRECTORY"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is a Map of attributes specific
+ * to a particular VM install type, used when launching a local Ruby
+ * application. The map is passed to a <code>VMRunner</code> via a <code>VMRunnerConfiguration</code>
+ * when launching a VM. The attributes in the map are implementation dependent
+ * and are limited to String keys and values.
+ */
+ public static final String ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP = LaunchingPlugin.getUniqueIdentifier() + "VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is a fully qualified name
+ * of a file to launch.
+ */
+ public static final String ATTR_FILE_NAME = LaunchingPlugin.getUniqueIdentifier() + ".FILE_NAME"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is an identifier of a
+ * classpath provider extension used to compute the classpath
+ * for a launch configuration. When unspecified, the default classpath
+ * provider is used - <code>StandardClasspathProvider</code>.
+ */
+ public static final String ATTR_CLASSPATH_PROVIDER = LaunchingPlugin.getUniqueIdentifier() + ".CLASSPATH_PROVIDER"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is a boolean specifying
+ * whether a default classpath should be used when launching a local
+ * Java application. When <code>false</code>, a classpath must be specified
+ * via the <code>ATTR_CLASSPATH</code> attribute. When <code>true</code> or
+ * unspecified, a classpath is computed by the classpath provider associated
+ * with a launch configuration.
+ */
+ public static final String ATTR_DEFAULT_CLASSPATH = LaunchingPlugin.getUniqueIdentifier() + ".DEFAULT_CLASSPATH"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The attribute value is an ordered list of strings
+ * which are mementos for runtime class path entries. When unspecified, a default
+ * classpath is generated by the classpath provider associated with a launch
+ * configuration (via the <code>ATTR_CLASSPATH_PROVIDER</code> attribute).
+ */
+ public static final String ATTR_CLASSPATH = LaunchingPlugin.getUniqueIdentifier() + ".CLASSPATH"; //$NON-NLS-1$
+
+
}
Added: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyLaunchDelegate.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyLaunchDelegate.java (rev 0)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyLaunchDelegate.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.launching;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.rubypeople.rdt.internal.launching.LaunchingMessages;
+
+/**
+ * A launch delegate for launching local Ruby applications.
+ * <p>
+ * Clients may subclass and instantiate this class.
+ * </p>
+ * @since 0.9.0
+ */
+public class RubyLaunchDelegate extends AbstractRubyLaunchConfigurationDelegate {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+
+ monitor.beginTask(MessageFormat.format("{0}...", new String[]{configuration.getName()}), 3); //$NON-NLS-1$
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ monitor.subTask(LaunchingMessages.JavaLocalApplicationLaunchConfigurationDelegate_Verifying_launch_attributes____1);
+
+ String mainTypeName = verifyFileToLaunch(configuration);
+ IVMRunner runner = getVMRunner(configuration, mode);
+
+ File workingDir = verifyWorkingDirectory(configuration);
+ String workingDirName = null;
+ if (workingDir != null) {
+ workingDirName = workingDir.getAbsolutePath();
+ }
+
+ // Environment variables
+ String[] envp= getEnvironment(configuration);
+
+ // Program & VM arguments
+ String pgmArgs = getProgramArguments(configuration);
+ String vmArgs = getVMArguments(configuration);
+ ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs);
+
+ // VM-specific attributes
+ Map vmAttributesMap = getVMSpecificAttributesMap(configuration);
+
+ // Loadpath
+ String[] classpath = getLoadpath(configuration);
+
+ // Create VM config
+ VMRunnerConfiguration runConfig = new VMRunnerConfiguration(mainTypeName, classpath);
+ runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
+ runConfig.setEnvironment(envp);
+ runConfig.setVMArguments(execArgs.getVMArgumentsArray());
+ runConfig.setWorkingDirectory(workingDirName);
+ runConfig.setVMSpecificAttributesMap(vmAttributesMap);
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ // done the verification phase
+ monitor.worked(1);
+
+ monitor.subTask(LaunchingMessages.JavaLocalApplicationLaunchConfigurationDelegate_Creating_source_locator____2);
+ // set the default source locator if required
+ setDefaultSourceLocator(launch, configuration);
+ monitor.worked(1);
+
+ // Launch the configuration - 1 unit of work
+ runner.run(runConfig, launch, monitor);
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ monitor.done();
+ }
+
+}
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyRuntime.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyRuntime.java 2007-01-19 19:13:42 UTC (rev 1816)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyRuntime.java 2007-01-19 20:07:32 UTC (rev 1817)
@@ -4,6 +4,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.StringReader;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
@@ -13,9 +14,12 @@
import java.util.Map;
import java.util.Set;
+import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
+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.IConfigurationElement;
@@ -29,17 +33,26 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
+import org.rubypeople.rdt.core.ILoadpathContainer;
import org.rubypeople.rdt.core.ILoadpathEntry;
import org.rubypeople.rdt.core.IRubyModel;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.internal.launching.CompositeId;
+import org.rubypeople.rdt.internal.launching.DefaultEntryResolver;
+import org.rubypeople.rdt.internal.launching.DefaultProjectLoadpathEntry;
import org.rubypeople.rdt.internal.launching.LaunchingMessages;
import org.rubypeople.rdt.internal.launching.LaunchingPlugin;
import org.rubypeople.rdt.internal.launching.ListenerList;
import org.rubypeople.rdt.internal.launching.RuntimeLoadpathEntry;
import org.rubypeople.rdt.internal.launching.RuntimeLoadpathEntryResolver;
+import org.rubypeople.rdt.internal.launching.RuntimeLoadpathProvider;
import org.rubypeople.rdt.internal.launching.VMDefinitionsContainer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
public class RubyRuntime {
@@ -92,6 +105,14 @@
* @since 0.9.0
*/
public static final String EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRY_RESOLVERS= "runtimeLoadpathEntryResolvers"; //$NON-NLS-1$
+
+ /**
+ * Simple identifier constant (value <code>"loadpathProviders"</code>) for the
+ * runtime loadpath providers extension point.
+ *
+ * @since 0.9.0
+ */
+ public static final String EXTENSION_POINT_RUNTIME_CLASSPATH_PROVIDERS= "loadpathProviders"; //$NON-NLS-1$
private static IVMInstallType[] fgVMTypes= null;
@@ -101,7 +122,25 @@
private static String fgDefaultVMId;
private static ListenerList fgVMListeners = new ListenerList(5);
private static String fgDefaultVMConnectorId;
+
+ /**
+ * Cache of already resolved projects in container entries. Used to avoid
+ * cycles in project dependencies when resolving classpath container entries.
+ * Counters used to know when entering/exiting to clear cache
+ */
+ private static ThreadLocal fgProjects = new ThreadLocal(); // Lists
+ private static ThreadLocal fgEntryCount = new ThreadLocal(); // Integers
+ /**
+ * Default loadpath provider.
+ */
+ private static IRuntimeLoadpathProvider fgDefaultClasspathProvider = new StandardLoadpathProvider();
+
+ /**
+ * Path providers keyed by id
+ */
+ private static Map fgPathProviders = null;
+
/**
* Set of IDs of VMs contributed via vmInstalls extension point.
*/
@@ -946,5 +985,612 @@
IPath path) {
ILoadpathEntry cpe = RubyCore.newVariableEntry(path);
return newRuntimeLoadpathEntry(cpe);
+ }
+
+ /**
+ * Computes and returns the unresolved class path for the given launch configuration.
+ * Variable and container entries are unresolved.
+ *
+ * @param configuration launch configuration
+ * @return unresolved runtime classpath entries
+ * @throws CoreException
+ * @exception CoreException if unable to compute the classpath
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry[] computeUnresolvedRuntimeLoadpath(
+ ILaunchConfiguration configuration) throws CoreException {
+ return getLoadpathProvider(configuration).computeUnresolvedLoadpath(configuration);
}
+
+ /**
+ * Returns the classpath provider for the given launch configuration.
+ *
+ * @param configuration launch configuration
+ * @return classpath provider
+ * @exception CoreException if unable to resolve the path provider
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathProvider getLoadpathProvider(ILaunchConfiguration configuration) throws CoreException {
+ String providerId = configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, (String)null);
+ IRuntimeLoadpathProvider provider = null;
+ if (providerId == null) {
+ provider = fgDefaultClasspathProvider;
+ } else {
+ provider = (IRuntimeLoadpathProvider)getLoadpathProviders().get(providerId);
+ if (provider == null) {
+ abort(MessageFormat.format(LaunchingMessages.JavaRuntime_26, new String[]{providerId}), null);
+ }
+ }
+ return provider;
+ }
+
+ /**
+ * Returns all registered classpath providers.
+ */
+ private static Map getLoadpathProviders() {
+ if (fgPathProviders == null) {
+ initializeProviders();
+ }
+ return fgPathProviders;
+ }
+
+ private static void initializeProviders() {
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(LaunchingPlugin.PLUGIN_ID, EXTENSION_POINT_RUNTIME_CLASSPATH_PROVIDERS);
+ IConfigurationElement[] extensions = point.getConfigurationElements();
+ fgPathProviders = new HashMap(extensions.length);
+ for (int i = 0; i < extensions.length; i++) {
+ RuntimeLoadpathProvider res = new RuntimeLoadpathProvider(extensions[i]);
+ fgPathProviders.put(res.getIdentifier(), res);
+ }
+ }
+
+ /**
+ * Returns a runtime classpath entry constructed from the given memento.
+ *
+ * @param memento a memento for a runtime classpath entry
+ * @return runtime classpath entry
+ * @exception CoreException if unable to construct a runtime classpath entry
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry newRuntimeLoadpathEntry(String memento) throws CoreException {
+ try {
+ Element root = null;
+ DocumentBuilder parser = LaunchingPlugin.getParser();
+ StringReader reader = new StringReader(memento);
+ InputSource source = new InputSource(reader);
+ root = parser.parse(source).getDocumentElement();
+
+ String id = root.getAttribute("id"); //$NON-NLS-1$
+ if (id == null || id.length() == 0) {
+ // assume an old format
+ return new RuntimeLoadpathEntry(root);
+ }
+ // get the extension & create a new one
+ IRuntimeLoadpathEntry2 entry = LaunchingPlugin.getDefault().newRuntimeLoadpathEntry(id);
+ NodeList list = root.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node node = list.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = (Element)node;
+ if ("memento".equals(element.getNodeName())) { //$NON-NLS-1$
+ entry.initializeFrom(element);
+ }
+ }
+ }
+ return entry;
+ } catch (SAXException e) {
+ abort(LaunchingMessages.JavaRuntime_31, e);
+ } catch (IOException e) {
+ abort(LaunchingMessages.JavaRuntime_32, e);
+ }
+ return null;
+ }
+
+ /**
+ * Returns a runtime classpath entry identifying the JRE to use when launching the specified
+ * configuration or <code>null</code> if none is specified. The entry returned represents a
+ * either a classpath variable or classpath container that resolves to a JRE.
+ * <p>
+ * The entry is resolved as follows:
+ * <ol>
+ * <li>If the <code>ATTR_JRE_CONTAINER_PATH</code> is present, it is used to create
+ * a classpath container referring to a JRE.</li>
+ * <li>Next, if the <code>ATTR_VM_INSTALL_TYPE</code> and <code>ATTR_VM_INSTALL_NAME</code>
+ * attributes are present, they are used to create a classpath container.</li>
+ * <li>When none of the above attributes are specified, a default entry is
+ * created which refers to the JRE referenced by the build path of the configuration's
+ * associated Java project. This could be a classpath variable or classpath container.</li>
+ * <li>When there is no Java project associated with a configuration, the workspace
+ * default JRE is used to create a container path.</li>
+ * </ol>
+ * </p>
+ * @param configuration
+ * @return classpath container path identifying a JRE or <code>null</code>
+ * @exception org.eclipse.core.runtime.CoreException if an exception occurs retrieving
+ * attributes from the specified launch configuration
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry computeJREEntry(ILaunchConfiguration configuration) throws CoreException {
+ String jreAttr = configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, (String)null);
+ IPath containerPath = null;
+ if (jreAttr == null) {
+ String type = configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, (String)null);
+ if (type == null) {
+ // default JRE for the launch configuration
+ IRubyProject proj = getRubyProject(configuration);
+ if (proj == null) {
+ containerPath = newDefaultJREContainerPath();
+ } else {
+ return computeJREEntry(proj);
+ }
+ } else {
+ String name = configuration.getAttribute(IRubyLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, (String)null);
+ if (name != null) {
+ containerPath = newDefaultJREContainerPath().append(type).append(name);
+ }
+ }
+ } else {
+ containerPath = Path.fromPortableString(jreAttr);
+ }
+ if (containerPath != null) {
+ return newRuntimeContainerLoadpathEntry(containerPath, IRuntimeLoadpathEntry.STANDARD_CLASSES);
+ }
+ return null;
+ }
+
+ /**
+ * Returns a runtime classpath entry identifying the JRE referenced by the specified
+ * project, or <code>null</code> if none. The entry returned represents a either a
+ * classpath variable or classpath container that resolves to a JRE.
+ *
+ * @param project Java project
+ * @return JRE runtime classpath entry or <code>null</code>
+ * @exception org.eclipse.core.runtime.CoreException if an exception occurs
+ * accessing the project's classpath
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry computeJREEntry(IRubyProject project) throws CoreException {
+ ILoadpathEntry[] rawClasspath = project.getRawLoadpath();
+ IRuntimeLoadpathEntryResolver2 resolver = null;
+ for (int i = 0; i < rawClasspath.length; i++) {
+ ILoadpathEntry entry = rawClasspath[i];
+ switch (entry.getEntryKind()) {
+ case ILoadpathEntry.CPE_VARIABLE:
+ resolver = getVariableResolver(entry.getPath().segment(0));
+ if (resolver != null) {
+ if (resolver.isVMInstallReference(entry)) {
+ return newRuntimeLoadpathEntry(entry);
+ }
+ }
+ break;
+ case ILoadpathEntry.CPE_CONTAINER:
+ resolver = getContainerResolver(entry.getPath().segment(0));
+ if (resolver != null) {
+ if (resolver.isVMInstallReference(entry)) {
+ ILoadpathContainer container = RubyCore.getLoadpathContainer(entry.getPath(), project);
+ if (container != null) {
+ switch (container.getKind()) {
+ case ILoadpathContainer.K_APPLICATION:
+ break;
+ case ILoadpathContainer.K_DEFAULT_SYSTEM:
+ return newRuntimeContainerLoadpathEntry(entry.getPath(), IRuntimeLoadpathEntry.STANDARD_CLASSES);
+ case ILoadpathContainer.K_SYSTEM:
+ return newRuntimeContainerLoadpathEntry(entry.getPath(), IRuntimeLoadpathEntry.BOOTSTRAP_CLASSES);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Returns a path for the JRE classpath container identifying the
+ * default VM install.
+ *
+ * @return classpath container path
+ * @since 0.9.0
+ */
+ public static IPath newDefaultJREContainerPath() {
+ return new Path(RUBY_CONTAINER);
+ }
+
+ /**
+ * Returns a runtime classpath entry for the given container path with the given
+ * classpath property.
+ *
+ * @param path container path
+ * @param classpathProperty the type of entry - one of <code>USER_CLASSES</code>,
+ * <code>BOOTSTRAP_CLASSES</code>, or <code>STANDARD_CLASSES</code>
+ * @return runtime classpath entry
+ * @exception CoreException if unable to construct a runtime classpath entry
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry newRuntimeContainerLoadpathEntry(IPath path, int classpathProperty) throws CoreException {
+ return newRuntimeContainerLoadpathEntry(path, classpathProperty, null);
+ }
+
+ /**
+ * Computes and returns the default unresolved runtime classpath for the
+ * given project.
+ *
+ * @return runtime classpath entries
+ * @exception CoreException if unable to compute the runtime classpath
+ * @see IRuntimeClasspathEntry
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry[] computeUnresolvedRuntimeLoadpath(IRubyProject project) throws CoreException {
+ ILoadpathEntry[] entries = project.getRawLoadpath();
+ List classpathEntries = new ArrayList(3);
+ for (int i = 0; i < entries.length; i++) {
+ ILoadpathEntry entry = entries[i];
+ switch (entry.getEntryKind()) {
+ case ILoadpathEntry.CPE_CONTAINER:
+ ILoadpathContainer container = RubyCore.getLoadpathContainer(entry.getPath(), project);
+ if (container != null) {
+ switch (container.getKind()) {
+ case ILoadpathContainer.K_APPLICATION:
+ // don't look at application entries
+ break;
+ case ILoadpathContainer.K_DEFAULT_SYSTEM:
+ classpathEntries.add(newRuntimeContainerLoadpathEntry(container.getPath(), IRuntimeLoadpathEntry.STANDARD_CLASSES, project));
+ break;
+ case ILoadpathContainer.K_SYSTEM:
+ classpathEntries.add(newRuntimeContainerLoadpathEntry(container.getPath(), IRuntimeLoadpathEntry.BOOTSTRAP_CLASSES, project));
+ break;
+ }
+ }
+ break;
+ case ILoadpathEntry.CPE_VARIABLE:
+ if (RUBYLIB_VARIABLE.equals(entry.getPath().segment(0))) {
+ IRuntimeLoadpathEntry jre = newVariableRuntimeLoadpathEntry(entry.getPath());
+ jre.setLoadpathProperty(IRuntimeLoadpathEntry.STANDARD_CLASSES);
+ classpathEntries.add(jre);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ classpathEntries.add(newDefaultProjectLoadpathEntry(project));
+ return (IRuntimeLoadpathEntry[]) classpathEntries.toArray(new IRuntimeLoadpathEntry[classpathEntries.size()]);
+ }
+
+ /**
+ * Returns a new runtime classpath entry containing the default classpath
+ * for the specified Ruby project.
+ *
+ * @param project Ruby project
+ * @return runtime classpath entry
+ * @since 0.9.0
+ */
+ public static IRuntimeLoadpathEntry newDefaultProjectLoadpathEntry(IRubyProject project) {
+ return new DefaultProjectLoadpathEntry(project);
+ }
+
+ /**
+ * Returns resolved entries for the given entry in the context of the given
+ * launch configuration. If the entry is of kind
+ * <code>VARIABLE</code> or <code>CONTAINER</code>, variable and container
+ * resolvers are consulted. If the entry is of kind <code>PROJECT</code>,
+ * and the associated Java project specifies non-default output locations,
+ * the corresponding output locations are returned. Otherwise, the given
+ * entry is returned.
+ * <p>
+ * If the given entry is a variable entry, and a resolver is not registered,
+ * the entry itself is returned. If the given entry is a container, and a
+ * resolver is not registered, resolved runtime classpath entries are calculated
+ * from the associated container classpath entries, in the context of the project
+ * associated with the given launch configuration.
+ * </p>
+ * @param entry runtime classpath entry
+ * @param configuration launch configuration
+ * @return resolved runtime classpath entry
+ * @exception CoreException if unable to resolve
+ * @see IRuntimeClasspathEntryResolver
+ * @since 2.0
+ */
+ public static IRuntimeLoadpathEntry[] resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry entry, ILaunchConfiguration configuration) throws CoreException {
+ switch (entry.getType()) {
+ case IRuntimeLoadpathEntry.PROJECT:
+ // if the project has multiple output locations, they must be returned
+ IResource resource = entry.getResource();
+ if (resource instanceof IProject) {
+ IProject p = (IProject)resource;
+ IRubyProject project = RubyCore.create(p);
+ if (project == null || !p.isOpen() || !project.exists()) {
+ return new IRuntimeLoadpathEntry[0];
+ }
+ IRuntimeLoadpathEntry[] entries = resolveOutputLocations(project, entry.getLoadpathProperty());
+ if (entries != null) {
+ return entries;
+ }
+ } else {
+ // could not resolve project
+ abort(MessageFormat.format(LaunchingMessages.JavaRuntime_Classpath_references_non_existant_project___0__3, new String[]{entry.getPath().lastSegment()}), null);
+ }
+ break;
+ case IRuntimeLoadpathEntry.VARIABLE:
+ IRuntimeLoadpathEntryResolver resolver = getVariableResolver(entry.getVariableName());
+ if (resolver == null) {
+ IRuntimeLoadpathEntry[] resolved = resolveVariableEntry(entry, null, configuration);
+ if (resolved != null) {
+ return resolved;
+ }
+ break;
+ }
+ return resolver.resolveRuntimeLoadpathEntry(entry, configuration);
+ case IRuntimeLoadpathEntry.CONTAINER:
+ resolver = getContainerResolver(entry.getVariableName());
+ if (resolver == null) {
+ return computeDefaultContainerEntries(entry, configuration);
+ }
+ return resolver.resolveRuntimeLoadpathEntry(entry, configuration);
+ case IRuntimeLoadpathEntry.ARCHIVE:
+ // verify the archive exists
+ String location = entry.getLocation();
+ if (location == null) {
+ abort(MessageFormat.format(LaunchingMessages.JavaRuntime_Classpath_references_non_existant_archive___0__4, new String[]{entry.getPath().toString()}), null);
+ }
+ File file = new File(location);
+ if (!file.exists()) {
+ abort(MessageFormat.format(LaunchingMessages.JavaRuntime_Classpath_references_non_existant_archive___0__4, new String[]{entry.getPath().toString()}), null);
+ }
+ break;
+ case IRuntimeLoadpathEntry.OTHER:
+ resolver = getContributedResolver(((IRuntimeLoadpathEntry2)entry).getTypeId());
+ return resolver.resolveRuntimeLoadpathEntry(entry, configuration);
+ default:
+ break;
+ }
+ return new IRuntimeLoadpathEntry[] {entry};
+ }
+
+ /**
+ * Performs default resolution for a container entry.
+ * Delegates to the Ruby model.
+ */
+ private static IRuntimeLoadpathEntry[] computeDefaultContainerEntries(IRuntimeLoadpathEntry entry, ILaunchConfiguration config) throws CoreException {
+ IRubyProject project = entry.getRubyProject();
+ if (project == null) {
+ project = getRubyProject(config);
+ }
+ return computeDefaultContainerEntries(entry, project);
+ }
+
+ /**
+ * Performs default resolution for a container entry.
+ * Delegates to the Java model.
+ */
+ private static IRuntimeLoadpathEntry[] computeDefaultContainerEntries(IRuntimeLoadpathEntry entry, IRubyProject project) throws CoreException {
+ if (project == null || entry == null) {
+ // cannot resolve without entry or project context
+ return new IRuntimeLoadpathEntry[0];
+ }
+ ILoadpathContainer container = RubyCore.getLoadpathContainer(entry.getPath(), project);
+ if (container == null) {
+ abort(MessageFormat.format(LaunchingMessages.JavaRuntime_Could_not_resolve_classpath_container___0__1, new String[]{entry.getPath().toString()}), null);
+ // execution will not reach here - exception will be thrown
+ return null;
+ }
+ ILoadpathEntry[] cpes = container.getLoadpathEntries();
+ int property = -1;
+ switch (container.getKind()) {
+ case ILoadpathContainer.K_APPLICATION:
+ property = IRuntimeLoadpathEntry.USER_CLASSES;
+ break;
+ case ILoadpathContainer.K_DEFAULT_SYSTEM:
+ property = IRuntimeLoadpathEntry.STANDARD_CLASSES;
+ break;
+ case ILoadpathContainer.K_SYSTEM:
+ property = IRuntimeLoadpathEntry.BOOTSTRAP_CLASSES;
+ break;
+ }
+ List resolved = new ArrayList(cpes.length);
+ List projects = (List) fgProjects.get();
+ Integer count = (Integer) fgEntryCount.get();
+ if (projects == null) {
+ projects = new ArrayList();
+ fgProjects.set(projects);
+ count = new Integer(0);
+ }
+ int intCount = count.intValue();
+ intCount++;
+ fgEntryCount.set(new Integer(intCount));
+ try {
+ for (int i = 0; i < cpes.length; i++) {
+ ILoadpathEntry cpe = cpes[i];
+ if (cpe.getEntryKind() == ILoadpathEntry.CPE_PROJECT) {
+ IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(cpe.getPath().segment(0));
+ IRubyProject jp = RubyCore.create(p);
+ if (!projects.contains(jp)) {
+ projects.add(jp);
+ IRuntimeLoadpathEntry classpath = newDefaultProjectLoadpathEntry(jp);
+ IRuntimeLoadpathEntry[] entries = resolveRuntimeLoadpathEntry(classpath, jp);
+ for (int j = 0; j < entries.length; j++) {
+ IRuntimeLoadpathEntry e = entries[j];
+ if (!resolved.contains(e)) {
+ resolved.add(entries[j]);
+ }
+ }
+ }
+ } else {
+ IRuntimeLoadpathEntry e = newRuntimeLoadpathEntry(cpe);
+ if (!resolved.contains(e)) {
+ resolved.add(e);
+ }
+ }
+ }
+ } finally {
+ intCount--;
+ if (intCount == 0) {
+ fgProjects.set(null);
+ fgEntryCount.set(null);
+ } else {
+ fgEntryCount.set(new Integer(intCount));
+ }
+ }
+ // set classpath property
+ IRuntimeLoadpathEntry[] result = new IRuntimeLoadpathEntry[resolved.size()];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = (IRuntimeLoadpathEntry) resolved.get(i);
+ result[i].setLoadpathProperty(property);
+ }
+ return result;
+ }
+
+ /**
+ * Default resolution for a classpath variable - resolve to an archive. Only
+ * one of project/configuration can be non-null.
+ *
+ * @param entry
+ * @param project the project context or <code>null</code>
+ * @param configuration configuration context or <code>null</code>
+ * @return IRuntimeLoadpathEntry[]
+ * @throws CoreException
+ */
+ private static IRuntimeLoadpathEntry[] resolveVariableEntry(IRuntimeLoadpathEnt...
[truncated message content] |