|
From: <caw...@us...> - 2007-01-29 19:17:33
|
Revision: 1895
http://svn.sourceforge.net/rubyeclipse/?rev=1895&view=rev
Author: cawilliams
Date: 2007-01-29 11:17:22 -0800 (Mon, 29 Jan 2007)
Log Message:
-----------
add experimental code to try and detect the default vms set up on *nix boxes (including Mac OSX). Calls out to "which ruby" and parses the answer for a Standard VM Type. (Need to have it handle a non path response!)
Modified Paths:
--------------
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMType.java
trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IVMInstallType.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/VMListener.java
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMType.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMType.java 2007-01-29 16:02:24 UTC (rev 1894)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardVMType.java 2007-01-29 19:17:22 UTC (rev 1895)
@@ -13,12 +13,14 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamsProxy;
+import org.eclipse.osgi.service.environment.Constants;
import org.rubypeople.rdt.launching.AbstractVMInstallType;
import org.rubypeople.rdt.launching.IVMInstall;
@@ -229,4 +231,79 @@
return paths;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.launching.IVMInstallType#detectInstallLocation()
+ */
+ public File detectInstallLocation() {
+ // do not detect on Windows
+ if (Platform.getOS().equals(Constants.OS_WIN32)) {
+ return null;
+ }
+
+ String[] cmdLine = new String[] { "which", "ruby" }; //$NON-NLS-1$ //$NON-NLS-2$
+ Process p = null;
+ File rubyExecutable = null;
+ try {
+ p = Runtime.getRuntime().exec(cmdLine);
+ IProcess process = DebugPlugin.newProcess(new Launch(null, ILaunchManager.RUN_MODE, null), p, "Standard Ruby VM Install Detection"); //$NON-NLS-1$
+ for (int i = 0; i < 200; i++) {
+ // Wait no more than 10 seconds (200 * 50 mils)
+ if (process.isTerminated()) {
+ break;
+ }
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {}
+ }
+ rubyExecutable = parseRubyExecutableLocation(process);
+ } catch (IOException ioe) {
+ LaunchingPlugin.log(ioe);
+ } finally {
+ if (p != null) {
+ p.destroy();
+ }
+ }
+
+ if (rubyExecutable == null) {
+ return null;
+ }
+
+ File bin= new File(rubyExecutable.getParent());
+ if (!bin.exists()) return null;
+ File rubyHome = bin.getParentFile();
+ if (!rubyHome.exists()) return null;
+ if (!canDetectDefaultSystemLibraries(rubyHome, rubyExecutable)) {
+ return null;
+ }
+
+ return rubyHome;
+ }
+
+ /**
+ * Parses the output from 'Standard Ruby VM Install Detector'.
+ */
+ protected File parseRubyExecutableLocation(IProcess process) {
+ IStreamsProxy streamsProxy = process.getStreamsProxy();
+ String text = null;
+ if (streamsProxy != null) {
+ text = streamsProxy.getOutputStreamMonitor().getContents();
+ }
+ BufferedReader reader = new BufferedReader(new StringReader(text));
+ List<String> lines = new ArrayList<String>();
+ try {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ lines.add(line);
+ }
+ } catch (IOException e) {
+ LaunchingPlugin.log(e);
+ }
+ if (lines.size() > 0) {
+ String location = lines.remove(0);
+ File executable = new File(location);
+ if (executable.isFile() && executable.exists()) return executable;
+ }
+ return null;
+ }
+
}
Added: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/VMListener.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/VMListener.java (rev 0)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/VMListener.java 2007-01-29 19:17:22 UTC (rev 1895)
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 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.internal.launching;
+
+import org.rubypeople.rdt.launching.IVMInstall;
+import org.rubypeople.rdt.launching.IVMInstallChangedListener;
+import org.rubypeople.rdt.launching.PropertyChangeEvent;
+
+/**
+ * Simple VM listener that reports whether VM settings have changed.
+ *
+ * @since 0.9.0
+ *
+ */
+public class VMListener implements IVMInstallChangedListener {
+
+ private boolean fChanged = false;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.launching.IVMInstallChangedListener#defaultVMInstallChanged(org.eclipse.jdt.launching.IVMInstall, org.eclipse.jdt.launching.IVMInstall)
+ */
+ public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {
+ fChanged = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmAdded(org.eclipse.jdt.launching.IVMInstall)
+ */
+ public void vmAdded(IVMInstall vm) {
+ fChanged = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmChanged(org.eclipse.jdt.launching.PropertyChangeEvent)
+ */
+ public void vmChanged(PropertyChangeEvent event) {
+ fChanged = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmRemoved(org.eclipse.jdt.launching.IVMInstall)
+ */
+ public void vmRemoved(IVMInstall vm) {
+ fChanged = true;
+ }
+
+ public boolean isChanged() {
+ return fChanged;
+ }
+
+}
Modified: trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IVMInstallType.java
===================================================================
--- trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IVMInstallType.java 2007-01-29 16:02:24 UTC (rev 1894)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/IVMInstallType.java 2007-01-29 19:17:22 UTC (rev 1895)
@@ -7,22 +7,104 @@
public interface IVMInstallType {
+ /**
+ * Finds the VM with the given name.
+ *
+ * @param name the VM name
+ * @return a VM instance, or <code>null</code> if not found
+ * @since 0.9.0
+ */
IVMInstall findVMInstallByName(String vmName);
+ /**
+ * Returns the globally unique id of this VM type.
+ * Clients are responsible for providing a unique id.
+ *
+ * @return the id of this IVMInstallType
+ */
String getId();
+ /**
+ * Returns all VM instances managed by this VM type.
+ *
+ * @return the list of VM instances managed by this VM type
+ */
IVMInstall[] getVMInstalls();
+ /**
+ * Validates the given location of a VM installation.
+ * <p>
+ * For example, an implementation might check whether the VM executable
+ * is present.
+ * </p>
+ *
+ * @param installLocation the root directory of a potential installation for
+ * this type of VM
+ * @return a status object describing whether the install location is valid
+ */
IStatus validateInstallLocation(File installLocation);
+ /**
+ * Finds the VM with the given id.
+ *
+ * @param id the VM id
+ * @return a VM instance, or <code>null</code> if not found
+ */
IVMInstall findVMInstall(String id);
+ /**
+ * Returns a collection of <code>IPath</code>s that represent the
+ * default system libraries of this VM install type, if a VM was installed
+ * at the given <code>installLocation</code>.
+ * The returned <code>IPath</code>s may not exist if the
+ * <code>installLocation</code> is not a valid install location.
+ *
+ * @param installLocation home location
+ * @see IVMInstallType#validateInstallLocation(File)
+ *
+ * @return default library locations based on the given <code>installLocation</code>.
+ * @since 0.9.0
+ */
IPath[] getDefaultLibraryLocations(File installLocation);
+ /**
+ * Returns the display name of this VM type.
+ *
+ * @return the name of this IVMInstallType
+ */
String getName();
+ /**
+ * Remove the VM associated with the given id from the set of VMs managed by
+ * this VM type. Has no effect if a VM with the given id is not currently managed
+ * by this type.
+ * A VM install that is disposed may not be used anymore.
+ *
+ * @param id the id of the VM to be disposed.
+ */
void disposeVMInstall(String id);
+ /**
+ * Creates a new instance of this VM Install type.
+ * The newly created IVMInstall is managed by this IVMInstallType.
+ *
+ * @param id An id String that must be unique within this IVMInstallType.
+ *
+ * @return the newly created VM instance
+ *
+ * @throws IllegalArgumentException If the id exists already.
+ */
IVMInstall createVMInstall(String id);
+
+ /**
+ * Tries to detect an installed VM that matches this VM install type.
+ * Typically, this method will detect the VM installation found by "which ruby" on *nix systems.
+ * Implementers should return <code>null</code> if they
+ * can't assure that a given vm install matches this IVMInstallType.
+ * @return The location of an VM installation that can be used
+ * with this VM install type, or <code>null</code> if unable
+ * to locate an installed VM.
+ */
+ public File detectInstallLocation();
}
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-29 16:02:24 UTC (rev 1894)
+++ trunk/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/launching/RubyRuntime.java 2007-01-29 19:17:22 UTC (rev 1895)
@@ -49,6 +49,7 @@
import org.rubypeople.rdt.internal.launching.RuntimeLoadpathEntryResolver;
import org.rubypeople.rdt.internal.launching.RuntimeLoadpathProvider;
import org.rubypeople.rdt.internal.launching.VMDefinitionsContainer;
+import org.rubypeople.rdt.internal.launching.VMListener;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -329,10 +330,30 @@
vmDefs = new VMDefinitionsContainer();
// 2. add persisted VMs
setPref = addPersistedVMs(vmDefs);
-
- // 3. load contributed VM installs
+// 3. if there are none, detect the eclipse runtime
+ if (vmDefs.getValidVMList().isEmpty()) {
+ // calling out to detectDefaultVMs() could allow clients to change
+ // VM settings (i.e. call back into change VM settings).
+ VMListener listener = new VMListener();
+ addVMInstallChangedListener(listener);
+ setPref = true;
+ VMStandin runtime = detectDefaultVMs();
+ removeVMInstallChangedListener(listener);
+ if (!listener.isChanged()) {
+ if (runtime != null) {
+ vmDefs.addVM(runtime);
+ vmDefs.setDefaultVMInstallCompositeID(getCompositeIdFromVM(runtime));
+ }
+ } else {
+ // VMs were changed - reflect current settings
+ addPersistedVMs(vmDefs);
+ vmDefs.setDefaultVMInstallCompositeID(fgDefaultVMId);
+
+ }
+ }
+ // 4. load contributed VM installs
addVMExtensions(vmDefs);
- // 4. verify default VM is valid
+ // 5. verify default VM is valid
String defId = vmDefs.getDefaultVMInstallCompositeID();
boolean validDef = false;
if (defId != null) {
@@ -402,6 +423,45 @@
}
/**
+ * Detect the VM that is used by the system by default.
+ *
+ * @return a VM standin representing the VM that Eclipse is running on, or
+ * <code>null</code> if unable to detect the runtime VM
+ */
+ private static VMStandin detectDefaultVMs() {
+ VMStandin detectedVMStandin = null;
+ // Try to detect a VM for each declared VM type
+ IVMInstallType[] vmTypes= getVMInstallTypes();
+ for (int i = 0; i < vmTypes.length; i++) {
+
+ File detectedLocation= vmTypes[i].detectInstallLocation();
+ if (detectedLocation != null && detectedVMStandin == null) {
+
+ // Make sure the VM id is unique
+ long unique = System.currentTimeMillis();
+ IVMInstallType vmType = vmTypes[i];
+ while (vmType.findVMInstall(String.valueOf(unique)) != null) {
+ unique++;
+ }
+
+ // Create a standin for the detected VM and add it to the result collector
+ String vmID = String.valueOf(unique);
+ detectedVMStandin = new VMStandin(vmType, vmID);
+ detectedVMStandin.setInstallLocation(detectedLocation);
+ detectedVMStandin.setName(generateDetectedVMName(detectedVMStandin));
+ }
+ }
+ return detectedVMStandin;
+ }
+
+ /**
+ * Make the name of a detected VM stand out.
+ */
+ private static String generateDetectedVMName(IVMInstall vm) {
+ return vm.getInstallLocation().getName();
+ }
+
+ /**
* Initializes vm type extensions.
*/
private static void initializeVMTypeExtensions() {
@@ -485,7 +545,7 @@
*
* @param vm the instance of IVMInstallType to be identified
*
- * @since 2.1
+ * @since 0.9.0
*/
public static String getCompositeIdFromVM(IVMInstall vm) {
if (vm == null) {
@@ -499,7 +559,7 @@
/**
* Loads contributed VM installs
- * @since 3.2
+ * @since 0.9.0
*/
private static void addVMExtensions(VMDefinitionsContainer vmDefs) {
IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(LaunchingPlugin.PLUGIN_ID, RubyRuntime.EXTENSION_POINT_VM_INSTALLS);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|