|
From: <mba...@us...> - 2007-01-31 22:28:41
|
Revision: 1901
http://svn.sourceforge.net/rubyeclipse/?rev=1901&view=rev
Author: mbarchfe
Date: 2007-01-31 14:28:36 -0800 (Wed, 31 Jan 2007)
Log Message:
-----------
Added better abstraction for debugger access since we need two socket connections for rubydebug
Added Paths:
-----------
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/AbstractDebuggerConnection.java
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/BreakpointCommand.java
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/ClassicDebuggerConnection.java
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/EvalCommand.java
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/GenericCommand.java
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/RubyDebugConnection.java
trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/StepCommand.java
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/AbstractDebuggerConnection.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/AbstractDebuggerConnection.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/AbstractDebuggerConnection.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,127 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.Socket;
+
+import org.rubypeople.rdt.internal.debug.core.DebuggerNotFoundException;
+import org.rubypeople.rdt.internal.debug.core.RdtDebugCorePlugin;
+import org.rubypeople.rdt.internal.debug.core.parsing.AbstractReadStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.MultiReaderStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.SuspensionReader;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+public abstract class AbstractDebuggerConnection {
+
+ private int commandPort;
+ private Socket commandSocket;
+ private PrintWriter writer;
+ private AbstractReadStrategy commandReadStrategy ;
+
+ public AbstractDebuggerConnection(int port) {
+ super();
+ this.commandPort = port;
+ }
+
+ /*
+ * connect to the debugger. After the connection is established the debugger
+ * listens for control commands
+ */
+ public abstract void connect() throws DebuggerNotFoundException, IOException;
+
+ /*
+ * start the debugger. Must be connected to start.
+ */
+ public abstract SuspensionReader start() throws DebuggerNotFoundException, IOException;
+
+
+ /*
+ * always call via Command.execute
+ */
+ protected AbstractReadStrategy sendCommand(AbstractCommand command) throws DebuggerNotFoundException, IOException {
+ if (!isCommandPortConnected()) {
+ throw new IllegalStateException(command + " could not be sent since command socket is not open") ;
+ }
+ RdtDebugCorePlugin.debug("Sending command: " + command.getCommand()) ;
+ getWriter().println(command.getCommand()) ;
+ return getCommandReadStrategy() ;
+ }
+
+ public AbstractReadStrategy getCommandReadStrategy() {
+ return commandReadStrategy ;
+ }
+
+ protected void createCommandConnection() throws DebuggerNotFoundException, IOException {
+ getSocket() ;
+ XmlPullParser xpp = createXpp(commandSocket) ;
+ commandReadStrategy = new MultiReaderStrategy(xpp) ;
+ }
+
+ public boolean isCommandPortConnected() {
+ return commandSocket != null ;
+ }
+
+ protected Socket getSocket() throws IOException, DebuggerNotFoundException {
+
+ if (commandSocket == null) {
+ commandSocket = acquireSocket(commandPort);
+ if (commandSocket == null) {
+ throw new DebuggerNotFoundException();
+ }
+ }
+ return commandSocket;
+ }
+
+
+ protected static Socket acquireSocket(int port) throws IOException {
+ Socket socket = null ;
+ int tryCount = 10;
+ for (int i = 0; i < tryCount; i++) {
+ try {
+ socket = new Socket("localhost", port);
+ break ;
+ } catch (IOException e) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e1) {}
+ }
+ }
+ return socket;
+
+ }
+
+ private PrintWriter getWriter() throws IOException, DebuggerNotFoundException {
+ if (writer == null) {
+ writer = new PrintWriter(commandSocket.getOutputStream(), true);
+ }
+ return writer;
+ }
+
+ protected static XmlPullParser createXpp(Socket socket) {
+ XmlPullParser xpp = null;
+ try {
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance("org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer", null);
+ xpp = factory.newPullParser();
+ xpp.setInput(socket.getInputStream(), "UTF-8");
+ } catch (XmlPullParserException e) {
+ // TODO: log
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return xpp;
+ }
+
+ public int getCommandPort() {
+ return commandPort;
+ }
+
+ public void exit() throws IOException {
+ if (commandSocket != null) {
+ commandSocket.close() ;
+ }
+ }
+
+}
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/BreakpointCommand.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/BreakpointCommand.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/BreakpointCommand.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,29 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import java.io.IOException;
+
+import org.rubypeople.rdt.internal.debug.core.DebuggerNotFoundException;
+import org.rubypeople.rdt.internal.debug.core.parsing.AbstractReadStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.BreakpointModificationReader;
+import org.rubypeople.rdt.internal.debug.core.parsing.XmlStreamReader;
+
+public class BreakpointCommand extends AbstractCommand {
+
+ public BreakpointCommand(String command) {
+ super(command, true) ;
+ }
+
+ @Override
+ protected XmlStreamReader createResultReader(AbstractReadStrategy readStrategy) {
+ return new BreakpointModificationReader(readStrategy) ;
+ }
+
+ public BreakpointModificationReader getBreakpointAddedReader() {
+ return (BreakpointModificationReader) getResultReader() ;
+ }
+
+ public int executeWithResult(AbstractDebuggerConnection connection) throws DebuggerNotFoundException, IOException {
+ execute(connection) ;
+ return getBreakpointAddedReader().readBreakpointNo() ;
+ }
+}
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/ClassicDebuggerConnection.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/ClassicDebuggerConnection.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/ClassicDebuggerConnection.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,26 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import java.io.IOException;
+
+import org.rubypeople.rdt.internal.debug.core.DebuggerNotFoundException;
+import org.rubypeople.rdt.internal.debug.core.parsing.SuspensionReader;
+
+public class ClassicDebuggerConnection extends AbstractDebuggerConnection {
+
+ public ClassicDebuggerConnection(int port) {
+ super(port);
+ }
+
+ @Override
+ public void connect() throws DebuggerNotFoundException, IOException {
+ createCommandConnection();
+ }
+
+ @Override
+ public SuspensionReader start() throws DebuggerNotFoundException, IOException {
+ StepCommand stepCommand = new StepCommand("cont");
+ stepCommand.execute(this) ;
+ return stepCommand.getSuspensionReader() ;
+ }
+
+}
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/EvalCommand.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/EvalCommand.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/EvalCommand.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,21 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import org.rubypeople.rdt.internal.debug.core.parsing.AbstractReadStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.EvalReader;
+import org.rubypeople.rdt.internal.debug.core.parsing.XmlStreamReader;
+
+public class EvalCommand extends AbstractCommand {
+
+ public EvalCommand(String command, boolean isControl) {
+ super(command, isControl);
+ }
+
+ @Override
+ protected XmlStreamReader createResultReader(AbstractReadStrategy readStrategy) {
+ return new EvalReader(readStrategy);
+ }
+
+ public EvalReader getEvalReader() {
+ return (EvalReader) getResultReader() ;
+ }
+}
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/GenericCommand.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/GenericCommand.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/GenericCommand.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,24 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import org.rubypeople.rdt.internal.debug.core.parsing.AbstractReadStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.XmlStreamReader;
+
+public class GenericCommand extends AbstractCommand {
+
+ private AbstractReadStrategy readStrategy;
+
+ public GenericCommand(String command, boolean isControl) {
+ super(command, isControl);
+ }
+
+ @Override
+ protected XmlStreamReader createResultReader(AbstractReadStrategy readStrategy) {
+ this.readStrategy = readStrategy;
+ return null;
+ }
+
+ public AbstractReadStrategy getReadStrategy() {
+ return readStrategy;
+ }
+
+}
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/RubyDebugConnection.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/RubyDebugConnection.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/RubyDebugConnection.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,109 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.Socket;
+
+import org.rubypeople.rdt.internal.debug.core.DebuggerNotFoundException;
+import org.rubypeople.rdt.internal.debug.core.RdtDebugCorePlugin;
+import org.rubypeople.rdt.internal.debug.core.model.RubyProcessingException;
+import org.rubypeople.rdt.internal.debug.core.parsing.AbstractReadStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.MultiReaderStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.SuspensionReader;
+import org.xmlpull.v1.XmlPullParser;
+
+public class RubyDebugConnection extends AbstractDebuggerConnection {
+
+ private Socket controlSocket ;
+ private MultiReaderStrategy controlReadStrategy;
+ private PrintWriter controlWriter;
+ private String rdebugExtensionPath ;
+ public RubyDebugConnection(String rdebugExtensionPath, int port) {
+ super(port);
+ this.rdebugExtensionPath = rdebugExtensionPath + File.separatorChar + "rdebugExtension.rb";
+ }
+
+ @Override
+ public void connect() throws DebuggerNotFoundException, IOException{
+ createControlConnection() ;
+
+ String expression = "eval require '" + rdebugExtensionPath + "'";
+ EvalCommand command = new EvalCommand(expression, true) ;
+ command.execute(this) ;
+ String evalResult = null;
+ try {
+ evalResult = command.getEvalReader().readEvalResult();
+ } catch (RubyProcessingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if (evalResult == null || !evalResult.equals("true")) {
+ // TODO: go on ?
+ throw new DebuggerNotFoundException("Could not add extension to ruby debug") ;
+ }
+ }
+
+ @Override
+ public SuspensionReader start() throws DebuggerNotFoundException, IOException {
+ createCommandConnection() ;
+ return new SuspensionReader(getCommandReadStrategy()) ;
+ }
+
+ @Override
+ public AbstractReadStrategy sendCommand(AbstractCommand command) throws DebuggerNotFoundException, IOException {
+ AbstractReadStrategy result = null ;
+ if (command.isControl()) {
+ result =sendControlCommand(command) ;
+ } else {
+ result = super.sendCommand(command);
+ }
+ return result ;
+ }
+
+ private AbstractReadStrategy sendControlCommand(AbstractCommand command) throws IOException {
+ if (!isControlPortConnected()) {
+ throw new IllegalStateException(command + " could not be executed since control socket is not opened.") ;
+ }
+ RdtDebugCorePlugin.debug("Sending control command: " + command.getCommand()) ;
+ getControlWriter().println(command.getCommand()) ;
+ return getControlReadStrategy() ;
+ }
+
+ private PrintWriter getControlWriter() throws IOException {
+ if (controlWriter == null) {
+ controlWriter = new PrintWriter(getControlSocket().getOutputStream(), true);
+ }
+ return controlWriter;
+ }
+
+ protected boolean isControlPortConnected() {
+ return controlReadStrategy != null;
+ }
+
+ protected void createControlConnection() throws DebuggerNotFoundException, IOException {
+ Socket socket = getControlSocket() ;
+ XmlPullParser xpp = createXpp(socket) ;
+ controlReadStrategy = new MultiReaderStrategy(xpp) ;
+ }
+
+ private Socket getControlSocket() throws IOException {
+ if (controlSocket == null) {
+ controlSocket = acquireSocket(getCommandPort() + 1) ;
+ }
+ return controlSocket ;
+ }
+
+ public MultiReaderStrategy getControlReadStrategy() {
+ return controlReadStrategy;
+ }
+
+ @Override
+ public void exit() throws IOException {
+ super.exit();
+ GenericCommand command = new GenericCommand("exit", true) ;
+ command.execute(this) ;
+ controlSocket.close() ;
+ }
+
+}
Added: trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/StepCommand.java
===================================================================
--- trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/StepCommand.java (rev 0)
+++ trunk/org.rubypeople.rdt.debug.core/src/org/rubypeople/rdt/internal/debug/core/commands/StepCommand.java 2007-01-31 22:28:36 UTC (rev 1901)
@@ -0,0 +1,34 @@
+package org.rubypeople.rdt.internal.debug.core.commands;
+
+import java.io.IOException;
+
+import org.rubypeople.rdt.internal.debug.core.DebuggerNotFoundException;
+import org.rubypeople.rdt.internal.debug.core.SuspensionPoint;
+import org.rubypeople.rdt.internal.debug.core.parsing.AbstractReadStrategy;
+import org.rubypeople.rdt.internal.debug.core.parsing.SuspensionReader;
+import org.rubypeople.rdt.internal.debug.core.parsing.XmlStreamReader;
+import org.rubypeople.rdt.internal.debug.core.parsing.XmlStreamReaderException;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class StepCommand extends AbstractCommand {
+
+
+ public StepCommand(String command) {
+ super(command, false);
+ }
+
+ @Override
+ protected XmlStreamReader createResultReader(AbstractReadStrategy readStrategy) {
+ return new SuspensionReader(readStrategy);
+ }
+
+ public SuspensionReader getSuspensionReader() {
+ return (SuspensionReader) getResultReader() ;
+ }
+
+ public SuspensionPoint readSuspension(AbstractDebuggerConnection debuggerConnection) throws DebuggerNotFoundException, IOException, XmlPullParserException, XmlStreamReaderException {
+ execute(debuggerConnection);
+ return getSuspensionReader().readSuspension() ;
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|