1. added J2sePlatform for StandardLuaJVM to use J2SE DebugNetSupportImpl

This commit is contained in:
Shu Lei
2007-12-07 19:51:06 +00:00
parent 9cf85debad
commit f19fa165b9
11 changed files with 218 additions and 4 deletions

View File

@@ -91,10 +91,10 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
if (debugSupport != null)
setDebugSupport(debugSupport);
else
System.out.println("Warning: DebugNetSupportBase is not implemented.");
System.out.println("Warning: DebugNetSupport is missing. Cannot communicate with a debugging client.");
} catch (IOException e) {
// no debug client can talk to VM, but VM can continue functioning
System.out.println("Warning: no debug client support due to error: " + e.getMessage());
System.out.println("Warning: cannot communicate with a debugging client due to error: " + e.getMessage());
}
}

View File

@@ -66,6 +66,7 @@ public class DebugMessageType extends EnumType {
public static final DebugMessageType disconnected = new DebugMessageType("disconnected", 34);
public static final DebugMessageType sessionId = new DebugMessageType("sessionId", 35);
public static final DebugMessageType debugServiceDown = new DebugMessageType("debugServiceDown", 36);
public static final DebugMessageType outputRedirect = new DebugMessageType("outputRedirect", 37);
protected static DebugMessageType[] ENUMS = new DebugMessageType[] {
start,
@@ -104,7 +105,8 @@ public class DebugMessageType extends EnumType {
clientRequestGlobalReply,
disconnected,
sessionId,
debugServiceDown
debugServiceDown,
outputRedirect
};
protected DebugMessageType(String name, int ordinal) {

View File

@@ -0,0 +1,57 @@
package org.luaj.debug;
import java.io.IOException;
import java.io.OutputStream;
import org.luaj.debug.event.DebugEventListener;
import org.luaj.debug.event.DebugEventOutputRedirect;
public class RedirectOutputStream extends OutputStream {
protected DebugEventListener listener;
protected int count;
protected byte[] buffer;
public RedirectOutputStream(DebugEventListener listener) {
this(listener, 1024);
}
public RedirectOutputStream(DebugEventListener listener, int count) {
this.listener = listener;
this.count = 0;
this.buffer = new byte[count];
}
public void close() throws IOException {
flushBuffer();
}
public synchronized void flush() throws IOException {
flushBuffer();
}
public void write(byte[] b, int off, int len) throws IOException {
super.write(b, off, len);
flushBuffer();
}
public void write(byte[] b) throws IOException {
super.write(b);
flushBuffer();
}
public synchronized void write(int b) throws IOException {
if (count >= buffer.length) {
flushBuffer();
}
buffer[count++] = (byte)b;
}
protected synchronized void flushBuffer(){
if (count > 0) {
String msg = new String(buffer, 0, this.count);
listener.notifyDebugEvent(new DebugEventOutputRedirect(msg));
count = 0;
}
}
}

View File

@@ -8,6 +8,7 @@ import java.io.IOException;
import org.luaj.debug.event.DebugEventBreakpoint;
import org.luaj.debug.event.DebugEventError;
import org.luaj.debug.event.DebugEventOutputRedirect;
import org.luaj.debug.request.DebugRequestDisconnect;
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
import org.luaj.debug.request.DebugRequestStack;
@@ -59,6 +60,7 @@ public class SerializationHelper {
static final int SERIAL_TYPE_DebugResponseVariables = 12;
static final int SERIAL_TYPE_DebugResponseStack = 13;
static final int SERIAL_TYPE_DebugResponseSession = 14;
static final int SERIAL_TYPE_DebugEventOutputRedirect = 15;
public static void serialize(Serializable object, DataOutputStream dout)
throws IOException {
@@ -93,6 +95,9 @@ public class SerializationHelper {
} else if (object instanceof DebugEventError) {
dout.writeInt(SERIAL_TYPE_DebugEventError);
DebugEventError.serialize(dout, (DebugEventError) object);
} else if (object instanceof DebugEventOutputRedirect) {
dout.writeInt(SERIAL_TYPE_DebugEventOutputRedirect);
DebugEventOutputRedirect.serialize(dout, (DebugEventOutputRedirect) object);
} else if (object instanceof DebugResponseStack) {
dout.writeInt(SERIAL_TYPE_DebugResponseStack);
DebugResponseStack.serialize(dout, (DebugResponseStack) object);
@@ -152,6 +157,9 @@ public class SerializationHelper {
case SERIAL_TYPE_DebugEventError:
object = DebugEventError.deserialize(din);
break;
case SERIAL_TYPE_DebugEventOutputRedirect:
object = DebugEventOutputRedirect.deserialize(din);
break;
case SERIAL_TYPE_DebugResponseCallgraph:
object = DebugResponseCallgraph.deserialize(din);
break;

View File

@@ -0,0 +1,40 @@
package org.luaj.debug.event;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.luaj.debug.DebugMessage;
import org.luaj.debug.DebugMessageType;
public class DebugEventOutputRedirect extends DebugMessage {
protected String data;
public DebugEventOutputRedirect(String data) {
super(DebugMessageType.outputRedirect);
this.data = data;
}
public String getOutput() {
return this.data;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return type.toString() + ": " + this.data;
}
public static void serialize(DataOutputStream out, DebugEventOutputRedirect event)
throws IOException {
out.writeUTF(event.getOutput());
}
public static DebugMessage deserialize(DataInputStream in) throws IOException {
String data = in.readUTF();
return new DebugEventOutputRedirect(data);
}
}

View File

@@ -0,0 +1,37 @@
package org.luaj.debug.j2se;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import org.luaj.debug.net.j2se.DebugSupportImpl;
import org.luaj.vm.DebugNetSupport;
import org.luaj.vm.Platform;
public class J2sePlatform extends Platform {
public Reader createReader(InputStream inputStream) {
return new InputStreamReader(inputStream);
}
public InputStream openFile(String fileName) {
return getClass().getResourceAsStream("/" + fileName);
}
/**
* Assumes J2SE platform, return the corresponding system
* property
*/
public String getProperty(String propertyName) {
return System.getProperty(propertyName);
}
/**
* Provides a J2SE DebugSupport instance.
*/
public DebugNetSupport getDebugSupport() throws IOException {
int port = getDebugPort();
DebugSupportImpl debugSupport = new DebugSupportImpl(port);
return debugSupport;
}
}

View File

@@ -36,6 +36,7 @@ import org.luaj.vm.LValue;
import org.luaj.vm.LoadState;
import org.luaj.vm.LuaErrorException;
import org.luaj.vm.LuaState;
import org.luaj.vm.Platform;
/**
* StandardLuaJVM executes a lua program in normal run mode or debug mode.
@@ -170,7 +171,9 @@ public class StandardLuaJVM {
public void run() {
try {
// new lua debug state
// new lua debug state
Platform.setInstance(new J2sePlatform());
state = LuaState.newState();
init(state);

View File

@@ -10,9 +10,11 @@ import javax.microedition.io.SocketConnection;
import org.luaj.debug.DebugMessage;
import org.luaj.debug.DebugMessageType;
import org.luaj.debug.RedirectOutputStream;
import org.luaj.debug.SerializationHelper;
import org.luaj.debug.event.DebugEventListener;
import org.luaj.debug.response.DebugResponseSession;
import org.luaj.lib.BaseLib;
public class ClientConnectionTask implements Runnable, DebugEventListener {
private static final boolean TRACE = true; //(null != System.getProperty("TRACE"));
@@ -26,6 +28,8 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
protected DataInputStream inStream;
protected DataOutputStream outStream;
protected RedirectOutputStream redirectOutputStream;
public ClientConnectionTask(String host, int port, DebugSupportImpl debugSupport) {
this.host = host;
this.port = port;
@@ -59,6 +63,10 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
if ( TRACE )
System.out.println("LuaJ debug server connected to " + host + ":" + port);
// to redirect the print to the debug client console
this.redirectOutputStream = new RedirectOutputStream(this);
BaseLib.redirectOutput( redirectOutputStream );
// loop for incoming requests
while ( !isDisconnected() ) {
byte[] data = null;
@@ -85,6 +93,13 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
debugSupport.disconnect(1);
} finally {
try {
redirectOutputStream.close();
} catch (IOException ignore) {}
// restore the print output
BaseLib.restoreStandardOutput();
dispose();
}
}

View File

@@ -8,9 +8,11 @@ import java.net.Socket;
import org.luaj.debug.DebugMessage;
import org.luaj.debug.DebugMessageType;
import org.luaj.debug.RedirectOutputStream;
import org.luaj.debug.SerializationHelper;
import org.luaj.debug.event.DebugEventListener;
import org.luaj.debug.response.DebugResponseSession;
import org.luaj.lib.BaseLib;
public class ClientConnectionTask implements Runnable, DebugEventListener {
private static final boolean TRACE = (null != System.getProperty("TRACE"));
@@ -23,6 +25,7 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
protected DataOutputStream eventWriter;
protected DebugSupportImpl debugSupport;
protected boolean isDisposed = false;
protected RedirectOutputStream redirectOutputStream;
public ClientConnectionTask(DebugSupportImpl debugSupport, Socket socket)
throws IOException {
@@ -60,6 +63,10 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
public void run() {
try {
// to redirect the print to the debug client console
this.redirectOutputStream = new RedirectOutputStream(this);
BaseLib.redirectOutput( redirectOutputStream );
// loop for incoming requests
while (!isDisconnected()) {
byte[] data = null;
@@ -87,6 +94,13 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
debugSupport.disconnect(getSessionId());
} finally {
try {
redirectOutputStream.close();
} catch (IOException ignore) {}
// restore the print output
BaseLib.restoreStandardOutput();
dispose();
}
}

View File

@@ -5,6 +5,7 @@ import java.io.IOException;
import junit.framework.TestCase;
import org.luaj.debug.event.DebugEventBreakpoint;
import org.luaj.debug.event.DebugEventOutputRedirect;
public class DebugEventTest extends TestCase {
public void testDebugEventSerialization() {
@@ -34,4 +35,17 @@ public class DebugEventTest extends TestCase {
fail(e.getMessage());
}
}
public void testDebugEventOutputRedirectSerialization() {
try {
String msg = "This is a testing message";
DebugEventOutputRedirect redirectEvent = new DebugEventOutputRedirect(msg);
byte[] data = SerializationHelper.serialize(redirectEvent);
DebugEventOutputRedirect redirectEventOut = (DebugEventOutputRedirect)
SerializationHelper.deserialize(data);
assertEquals(msg, redirectEventOut.getOutput());
} catch (IOException e) {
fail(e.getMessage());
}
}
}

View File

@@ -0,0 +1,24 @@
package org.luaj.debug;
import java.io.PrintWriter;
import junit.framework.TestCase;
import org.luaj.debug.event.DebugEventListener;
public class RedirectOutputStreamTest extends TestCase {
public void testRedirectOutputStream() {
RedirectOutputStream redirectOut = new RedirectOutputStream(
new DebugEventListener(){
public void notifyDebugEvent(DebugMessage event) {
assertEquals(event.toString(), "outputRedirect: true\r\na");
}
});
PrintWriter writer = new PrintWriter(redirectOut);
writer.print(true);
writer.println();
writer.print('a');
writer.close();
}
}