package com.smtscript.debug; import java.lang.reflect.Method; import java.net.Socket; import java.net.SocketAddress; import java.util.LinkedList; import java.util.Map; import java.util.concurrent.Semaphore; import org.mozilla.javascript.tools.debugger.Dim; import org.mozilla.javascript.tools.debugger.Dim.SourceInfo; import org.mozilla.javascript.tools.debugger.Dim.StackFrame; import com.smtscript.utils.Json; import com.smtscript.utils.JsonWriter; import com.smtscript.utils.SMTStatic; public class ScriptDebugSocketClient extends ScriptDebugSocketAbstract { protected static Map _mapName2Method; static { _mapName2Method = SMTStatic.newEventMethodMap("EVENT_", ScriptDebugSocketClient.class, new Class[]{String.class, Json.class}, "step_into", "RUN_CMD", "step_over", "RUN_CMD", "step_out", "RUN_CMD", "go", "RUN_CMD", "break", "RUN_CMD", "eval", "WATCH_CMD", "expr_list", "WATCH_CMD", "expr_add", "WATCH_CMD", "expr_expend", "WATCH_CMD", "set_breakpoint", "WATCH_CMD", "clear_breakpoint", "WATCH_CMD" ); } protected Object _lockRunCmd = new Object(); protected String _curRunCmd = null; protected Semaphore _semRecv = new Semaphore(0); protected LinkedList _listWatchCmd = new LinkedList(); public ScriptDebugSocketClient(SocketAddress addr) throws Exception { super(new Socket()); _socket.connect(addr); while(!_socket.isConnected()) { Thread.sleep(100); } this.startReceive(); } @Override protected void onReceive(String eventName, Json jsonRecv) throws Exception { if(dispatchReceive(_mapName2Method, eventName, jsonRecv)) return; } public void closeSocket() throws Exception { _socket.close(); } /** * dim的updateSourceText消息 * * @param sourceInfo - 源代码信息 */ public void onUpdateSourceText(SourceInfo sourceInfo) throws Exception { JsonWriter jsonWr = new JsonWriter(false); jsonWr.addKeyValue("event", "load_code"); jsonWr.addKeyValue("soruce", sourceInfo.source()); jsonWr.addKeyValue("url", sourceInfo.url()); this.sendSockRequest(jsonWr.getRootJson()); } /** * dim的enterInterrupt消息 * * @param lastFrame - 当前的frame * @param threadTitle - 线程信息 * @param alertMessage - 错误信息 */ public void onEnterInterrupt(StackFrame lastFrame, String threadTitle, String alertMessage) throws Exception { JsonWriter jsonWr = new JsonWriter(false); jsonWr.addKeyValue("event", "entry_interrupt"); jsonWr.addKeyValue("thread", threadTitle); jsonWr.addKeyValue("alert", alertMessage == null ? "" : alertMessage); Dim.ContextData contextData = lastFrame.contextData(); int frameCount = contextData.frameCount(); jsonWr.beginArray("frames"); for (int i = 0; i < frameCount; i++) { Dim.StackFrame frame = contextData.getFrame(i); jsonWr.beginMap(null); { writeStackFrameJson(frame, jsonWr); if(lastFrame.equals(frame)) jsonWr.addKeyValue("selected", true); } jsonWr.endMap(); } jsonWr.endArray(); this.sendSockRequest(jsonWr.getRootJson()); } /** * 生成frame的json返回信息 * * @param frame - 要生成的frame * @param jsonWr - 返回的json信息 */ private void writeStackFrameJson(StackFrame frame, JsonWriter jsonWr) { String funcName = frame.getFunctionName(); jsonWr.addKeyValue("line_no", frame.getLineNumber()); jsonWr.addKeyValue("url", frame.sourceInfo().url()); jsonWr.addKeyValue("func_name", funcName == null ? "" : funcName); } /** * 从接收队列里接收调试指令 * * @return Json - 查询指令 * String - 执行指令 * @throws InterruptedException */ public Object queryReceiveCmd() throws InterruptedException { _semRecv.acquire(); synchronized(_listWatchCmd) { if(_listWatchCmd.size() > 0) return _listWatchCmd.pollFirst(); } synchronized(_lockRunCmd) { if(_curRunCmd != null) { String ret = _curRunCmd; _curRunCmd = null; return ret; } } _semRecv.release(); return null; } /** * 将接收到的调试指令保存在缓存中 * * @param eventName - 调试指令 * @param jsonRecv - 未用 * @param response - 未用 */ public void EVENT_RUN_CMD(String eventName, Json jsonRecv) { synchronized(_lockRunCmd) { if(_curRunCmd == null) { _curRunCmd = eventName; _semRecv.release(); } } } /** * * @param eventName * @param jsonRecv * @param response */ public void EVENT_WATCH_CMD(String eventName, Json jsonRecv) { synchronized(_listWatchCmd) { _listWatchCmd.addLast(jsonRecv); _semRecv.release(); } } }