|
From: <caw...@us...> - 2007-05-21 15:50:19
|
Revision: 2503
http://svn.sourceforge.net/rubyeclipse/?rev=2503&view=rev
Author: cawilliams
Date: 2007-05-21 08:50:14 -0700 (Mon, 21 May 2007)
Log Message:
-----------
make launches private, add flag to tell if we want an interactive process/console 9some we don't want to really let user know anything like listing local gems or grabbing environment), clean up code a little.
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-21 14:48:27 UTC (rev 2502)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/gems/GemManager.java 2007-05-21 15:50:14 UTC (rev 2503)
@@ -7,7 +7,6 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
@@ -30,9 +29,9 @@
import org.eclipse.core.internal.resources.XMLWriter;
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.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
@@ -41,12 +40,8 @@
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IProcess;
-import org.eclipse.debug.core.model.IStreamMonitor;
-import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.ui.IDebugUIConstants;
-import org.eclipse.osgi.service.environment.Constants;
import org.rubypeople.rdt.launching.IRubyLaunchConfigurationConstants;
import org.rubypeople.rdt.launching.IVMInstall;
import org.rubypeople.rdt.launching.RubyRuntime;
@@ -63,27 +58,41 @@
public class GemManager implements IGemManager {
private static final String LOCAL_SWITCH = "-l";
+
private static final String LIST_COMMAND = "list";
+
private static final String INSTALL_COMMAND = "install";
+
private static final String VERSION_SWITCH = "-v";
+
private static final String UNINSTALL_COMMAND = "uninstall";
+
private static final String UPDATE_COMMAND = "update";
+
private static final String EXECUTABLE = "ruby";
+
private static final String VM_ARGS = "-e STDOUT.sync=true -e STDERR.sync=true -e load(ARGV.shift)";
private static final int TIMEOUT = 30000;
+
private static final String TIMEOUT_MSG = "Installing gem took more than 30 seconds, intentionally broke out to avoid infinite loop";
-
+
private static final String REMOTE_GEMS_CACHE_FILE = "remote_gems.xml";
+
private static final String LOCAL_GEMS_CACHE_FILE = "local_gems.xml";
+
private static final String GEM_INDEX_URL = "http://gems.rubyforge.org/yaml.Z";
private static IGemManager fgInstance;
private Set<Gem> gems;
+
private Set<Gem> remoteGems;
+
private Set<GemListener> listeners;
-
+
+ private String fGemInstallPath;
+
private GemManager() {
gems = new HashSet<Gem>();
// FIXME Somehow allow user to refresh remote gem list
@@ -97,7 +106,8 @@
remoteGems = loadLocalCache(getConfigFile(REMOTE_GEMS_CACHE_FILE));
if (remoteGems.isEmpty()) {
remoteGems = loadRemoteGems();
- storeGemCache(remoteGems, getConfigFile(REMOTE_GEMS_CACHE_FILE));
+ storeGemCache(remoteGems,
+ getConfigFile(REMOTE_GEMS_CACHE_FILE));
}
return Status.OK_STATUS;
}
@@ -111,7 +121,7 @@
gems = loadLocalCache(getConfigFile(LOCAL_GEMS_CACHE_FILE));
if (gems.isEmpty()) {
gems = loadLocalGems();
- storeGemCache(gems, getConfigFile(LOCAL_GEMS_CACHE_FILE));
+ storeGemCache(gems, getConfigFile(LOCAL_GEMS_CACHE_FILE));
}
synchronized (listeners) {
for (GemListener listener : listeners) {
@@ -173,14 +183,15 @@
}
private File getConfigFile(String fileName) {
- return AptanaRDTPlugin.getDefault().getStateLocation().append(
- fileName).toFile();
+ return AptanaRDTPlugin.getDefault().getStateLocation().append(fileName)
+ .toFile();
}
/**
* Writes each server configuration to file in XML format.
- * @param gems
*
+ * @param gems
+ *
* @param out
* the writer to use
*/
@@ -199,7 +210,7 @@
}
private Set<Gem> loadRemoteGems() {
-
+
try {
List<String> lines = new ArrayList<String>();
try {
@@ -232,8 +243,7 @@
if (version.charAt(version.length() - 1) == '"')
version = version.substring(0, version.length() - 1);
nextIsRealVersion = false;
- } else if (line.trim().equals(
- "version: !ruby/object:Gem::Version")) {
+ } else if (line.trim().equals("version: !ruby/object:Gem::Version")) {
nextIsRealVersion = true;
}
if (line.trim().startsWith("name:")) {
@@ -261,7 +271,8 @@
return gems;
}
- private List<String> getContents() throws MalformedURLException, IOException, DataFormatException {
+ private List<String> getContents() throws MalformedURLException,
+ IOException, DataFormatException {
// XXX Make sure this algorithm is returning same number of gems!!!!!
List<String> lines = new ArrayList<String>();
URL url = new URL(GEM_INDEX_URL);
@@ -273,34 +284,40 @@
int bytesToRead = content.available();
byte[] tmp = new byte[bytesToRead];
int length = content.read(tmp);
- if (length == -1) break;
- while ((index + length) > input.length) { // if we'll overflow the array, we need to expand it
+ if (length == -1)
+ break;
+ while ((index + length) > input.length) { // if we'll overflow the
+ // array, we need to
+ // expand it
byte[] newInput = new byte[input.length * 2];
System.arraycopy(input, 0, newInput, 0, input.length);
input = newInput;
- }
+ }
System.arraycopy(tmp, 0, input, index, length);
index += length;
- }
-
-// Decompress the bytes
- Inflater decompresser = new Inflater();
- decompresser.setInput(input);
- byte[] result = new byte[input.length * 20]; // XXX This is a hack. I have no idea what the length should be here
- int resultLength = decompresser.inflate(result);
- decompresser.end();
+ }
- // Decode the bytes into a String
- String outputString = new String(result, 0, resultLength);
- String[] lineArray = outputString.split("\n");
- for (int i = 0; i < lineArray.length; i++) {
- lines.add(lineArray[i]);
- }
- return lines;
+ // Decompress the bytes
+ Inflater decompresser = new Inflater();
+ decompresser.setInput(input);
+ byte[] result = new byte[input.length * 20]; // XXX This is a hack. I
+ // have no idea what the
+ // length should be here
+ int resultLength = decompresser.inflate(result);
+ decompresser.end();
+
+ // Decode the bytes into a String
+ String outputString = new String(result, 0, resultLength);
+ String[] lineArray = outputString.split("\n");
+ for (int i = 0; i < lineArray.length; i++) {
+ lines.add(lineArray[i]);
+ }
+ return lines;
}
private Set<Gem> loadLocalGems() {
- List<String> lines = launchAndRead(LIST_COMMAND + " " + LOCAL_SWITCH);
+ ILaunchConfiguration config = createGemLaunchConfiguration(LIST_COMMAND + " " + LOCAL_SWITCH, false);
+ List<String> lines = readOutput(config);
if (lines.size() > 2) {
lines.remove(0); // Remove first 3 lines from local list
lines.remove(0);
@@ -309,56 +326,6 @@
return parseOutGems(lines);
}
- private List<String> launchAndRead(String command) {
- try {
- ILaunchConfiguration config = createGemLaunchConfiguration(command);
- ILaunch launch = config.launch(ILaunchManager.RUN_MODE, null);
- IProcess[] processes = launch.getProcesses();
- IProcess p = processes[0];
- IStreamsProxy proxy = p.getStreamsProxy();
- final StringBuffer output = new StringBuffer();
- IStreamMonitor monitor = proxy.getOutputStreamMonitor();
- monitor.addListener(new IStreamListener() {
- public void streamAppended(String text, IStreamMonitor monitor) {
- output.append(text);
- }
-
- });
- long start = System.currentTimeMillis();
- String lastOut = null;
- while (!p.isTerminated() || output.length() == 0) {
- Thread.yield();
- if (lastOut != null && !lastOut.equals(output.toString())) {
- start = System.currentTimeMillis(); // restart timeout if we
- // have changes in
- // output
- }
- lastOut = output.toString();
- if (System.currentTimeMillis() > start + TIMEOUT) {
- AptanaRDTPlugin.log(new Exception(TIMEOUT_MSG));
- break;
- }
- }
-
- BufferedReader reader = new BufferedReader(new StringReader(output
- .toString()));
- String line = null;
- try {
- List<String> lines = new ArrayList<String>();
- while ((line = reader.readLine()) != null) {
- lines.add(line);
- }
- return lines;
- } catch (IOException e) {
- AptanaRDTPlugin.log(e);
- }
-
- } catch (CoreException e) {
- AptanaRDTPlugin.log(e);
- }
- return new ArrayList<String>();
- }
-
private Set<Gem> parseOutGems(List<String> lines) {
Set<Gem> gems = new HashSet<Gem>();
for (int i = 0; i < lines.size();) {
@@ -384,13 +351,15 @@
return gems;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#update(com.aptana.rdt.internal.gems.Gem)
*/
public boolean update(Gem gem) {
try {
String command = UPDATE_COMMAND + " " + gem.getName();
- ILaunchConfiguration config = createGemLaunchConfiguration(command);
+ ILaunchConfiguration config = createGemLaunchConfiguration(command, true);
config.launch(ILaunchManager.RUN_MODE, null);
} catch (CoreException e) {
AptanaRDTPlugin.log(e);
@@ -408,7 +377,7 @@
return DebugPlugin.getDefault().getLaunchManager();
}
- private ILaunchConfiguration createGemLaunchConfiguration(String arguments) {
+ private ILaunchConfiguration createGemLaunchConfiguration(String arguments, boolean interactive) {
String gemPath = getGemScriptPath();
ILaunchConfiguration config = null;
try {
@@ -428,19 +397,29 @@
wc.setAttribute(
IRubyLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
arguments);
- wc
- .setAttribute(
- IRubyLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
- VM_ARGS);
+ wc.setAttribute(
+ IRubyLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
+ VM_ARGS);
Map<String, String> map = new HashMap<String, String>();
- map
- .put(IRubyLaunchConfigurationConstants.ATTR_RUBY_COMMAND,
- EXECUTABLE);
+ map.put(IRubyLaunchConfigurationConstants.ATTR_RUBY_COMMAND,
+ EXECUTABLE);
wc
.setAttribute(
IRubyLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP,
map);
- wc.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
+ wc.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);
+ if (!interactive) {
+ wc.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND,
+ true);
+ wc.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE,
+ false);
+ IPath outFilePath = AptanaRDTPlugin.getDefault()
+ .getStateLocation();
+ outFilePath = outFilePath.append(System.currentTimeMillis()
+ + ".txt");
+ wc.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE,
+ outFilePath.toPortableString());
+ }
config = wc.doSave();
} catch (CoreException ce) {
// ignore for now
@@ -455,84 +434,20 @@
return path + File.separator + "bin" + File.separator + "gem";
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#installGem(com.aptana.rdt.internal.gems.Gem)
*/
public boolean installGem(Gem gem) {
try {
String command = INSTALL_COMMAND + " " + gem.getName();
- if (gem.getVersion() != null && gem.getVersion().trim().length() > 0) {
+ if (gem.getVersion() != null
+ && gem.getVersion().trim().length() > 0) {
command += " " + VERSION_SWITCH + " " + gem.getVersion();
}
- ILaunchConfiguration config = createGemLaunchConfiguration(command);
- ILaunch launch = config.launch(ILaunchManager.RUN_MODE, null);
- IProcess[] processes = launch.getProcesses();
- IProcess p = processes[0];
- IStreamMonitor monitor = p.getStreamsProxy()
- .getOutputStreamMonitor();
- final StringBuffer buffer = new StringBuffer();
- monitor.addListener(new IStreamListener() {
-
- public void streamAppended(String text, IStreamMonitor monitor) {
- buffer.append(text);
- }
-
- });
- String contents = null;
- boolean wroteSelection = false;
- long start = System.currentTimeMillis();
- String lastOut = null;
- while (!p.isTerminated()) {
- contents = buffer.toString();
- if (contents != null && contents.trim().length() > 0
- && !wroteSelection) {
- // System.out.println(contents);
- if (contents.contains("Select which gem")) {
- // Parse out options
- Map<String, String> options = new HashMap<String, String>();
-
- String[] lines = contents.split("\n");
- for (int i = 0; i < lines.length; i++) {
- String line = lines[i].trim();
- if (Character.isDigit(line.charAt(0))) {
- String number = line.substring(0, line
- .indexOf('.'));
- int parenIndex = line.indexOf('(');
- if (parenIndex == -1)
- continue; // Skip or cancel option
- String platform = line.substring(
- parenIndex + 1, line.lastIndexOf(')'));
- options.put(platform, number);
- }
- }
- // Automatically select the option which matches this
- // platform.
- String myPlatform = Gem.RUBY_PLATFORM;
- if (Platform.getOS().equals(Constants.OS_WIN32)) {
- myPlatform = Gem.MSWIN32_PLATFORM;
- }
- try {
- p.getStreamsProxy().write(
- options.get(myPlatform) + "\r\n");
- wroteSelection = true;
- } catch (IOException e) {
- AptanaRDTPlugin.log(e);
- }
- }
- } else {
- Thread.yield();
- if (lastOut != null && !lastOut.equals(buffer.toString())) {
- start = System.currentTimeMillis(); // restart timeout
- // if we have
- // changes in output
- }
- if (System.currentTimeMillis() > start + TIMEOUT) {
- AptanaRDTPlugin.log(new Exception(TIMEOUT_MSG));
- break;
- }
- }
-
- }
+ ILaunchConfiguration config = createGemLaunchConfiguration(command, true);
+ config.launch(ILaunchManager.RUN_MODE, null);
} catch (CoreException e) {
AptanaRDTPlugin.log(e);
return false;
@@ -543,16 +458,19 @@
return true;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#removeGem(com.aptana.rdt.internal.gems.Gem)
*/
public boolean removeGem(Gem gem) {
try {
String command = UNINSTALL_COMMAND + " " + gem.getName();
- if (gem.getVersion() != null && gem.getVersion().trim().length() > 0) {
+ if (gem.getVersion() != null
+ && gem.getVersion().trim().length() > 0) {
command += " " + VERSION_SWITCH + " " + gem.getVersion();
}
- ILaunchConfiguration config = createGemLaunchConfiguration(command);
+ ILaunchConfiguration config = createGemLaunchConfiguration(command, true);
config.launch(ILaunchManager.RUN_MODE, null);
} catch (CoreException e) {
AptanaRDTPlugin.log(e);
@@ -564,7 +482,9 @@
return true;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#getGems()
*/
public Set<Gem> getGems() {
@@ -577,7 +497,9 @@
return fgInstance;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#refresh()
*/
public boolean refresh() {
@@ -593,14 +515,18 @@
return false;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#addGemListener(com.aptana.rdt.internal.gems.GemManager.GemListener)
*/
public synchronized void addGemListener(GemListener listener) {
listeners.add(listener);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#getRemoteGems()
*/
public Set<Gem> getRemoteGems() {
@@ -619,51 +545,75 @@
return Collections.unmodifiableSortedSet(logical);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#gemInstalled(java.lang.String)
*/
public boolean gemInstalled(String gemName) {
Set<Gem> gems = getGems();
for (Gem gem : gems) {
- if (gem.getName().equalsIgnoreCase(gemName)) return true;
+ if (gem.getName().equalsIgnoreCase(gemName))
+ return true;
}
return false;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see com.aptana.rdt.internal.gems.IGemManager#removeGemListener(com.aptana.rdt.internal.gems.GemManager.GemListener)
*/
public synchronized void removeGemListener(GemListener listener) {
- listeners.remove(listener);
+ listeners.remove(listener);
}
public String getGemInstallPath() {
+ if (fGemInstallPath == null) {
+ ILaunchConfiguration config = createGemLaunchConfiguration("environment", false);
+ List<String> lines = readOutput(config);
+ if (lines == null || lines.size() < 3) return null;
+ String path = lines.get(2);
+ path = path.substring(path.indexOf("INSTALLATION DIRECTORY:") + 23);
+ fGemInstallPath = path.trim();
+ }
+ return fGemInstallPath;
+ }
+
+ private List<String> readOutput(ILaunchConfiguration config) {
+ List<String> lines = new ArrayList<String>();
+ File file = null;
+ BufferedReader reader = null;
try {
- ILaunchConfiguration config = createGemLaunchConfiguration("environment");
ILaunch launch = config.launch(ILaunchManager.RUN_MODE, null);
IProcess[] processes = launch.getProcesses();
IProcess p = processes[0];
- IStreamMonitor monitor = p.getStreamsProxy()
- .getOutputStreamMonitor();
- final StringBuffer buffer = new StringBuffer();
- monitor.addListener(new IStreamListener() {
-
- public void streamAppended(String text, IStreamMonitor monitor) {
- buffer.append(text);
- }
-
- });
while (!p.isTerminated()) {
Thread.yield();
}
- String contents = buffer.toString();
- int index = contents.indexOf("INSTALLATION DIRECTORY:");
- int endIndex = contents.indexOf("\n", index);
- String path = contents.substring(index + 23, endIndex);
- return path.trim();
+ file = new File(launch
+ .getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE));
+ reader = new BufferedReader(new FileReader(file));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ lines.add(line);
+ }
} catch(CoreException e) {
AptanaRDTPlugin.log(e);
- }
- return null;
+ } catch (FileNotFoundException e) {
+ AptanaRDTPlugin.log(e);
+ } catch (IOException e) {
+ AptanaRDTPlugin.log(e);
+ } finally {
+ try {
+ if (reader != null) reader.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ if (file != null) {
+ file.delete();
+ }
+ }
+ return lines;
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|