package org.rubypeople.rdt.internal.debug.core.commands; import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import org.rubypeople.rdt.debug.core.RdtDebugCorePlugin; 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.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 ; private String host; public AbstractDebuggerConnection(int port) { this("localhost", port); } public AbstractDebuggerConnection(String host, int port) { super(); this.host = host; 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; public abstract boolean isStarted() ; /* * 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(host, commandPort); if (commandSocket == null) { throw new DebuggerNotFoundException("Could not connect to debugger on port " + commandPort); } } return commandSocket; } protected static Socket acquireSocket(String host, int port) throws IOException { Socket socket = null ; int tryCount = 50; for (int i = 0; i < tryCount; i++) { try { socket = new Socket(host, 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() ; } } }