package com.smtscript.debug; import java.awt.Dimension; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import javax.swing.JFrame; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.Kit; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.tools.debugger.Dim; import org.mozilla.javascript.tools.debugger.ScopeProvider; import org.mozilla.javascript.tools.debugger.SourceProvider; import org.mozilla.javascript.tools.debugger.SwingGui; import org.mozilla.javascript.tools.shell.Global; public class ScriptDebuggerGui { private Dim dim; private SwingGui debugGui; public ScriptDebuggerGui(String title) { this.dim = new Dim(); this.debugGui = new SwingGui(this.dim, title); } public JFrame getDebugFrame() { return this.debugGui; } public void doBreak() { this.dim.setBreak(); } public void clearAllBreakpoints() { this.dim.clearAllBreakpoints(); } public void go() { this.dim.go(); } public void setScope(Scriptable scope) { setScopeProvider(IProxy.newScopeProvider(scope)); } public void setScopeProvider(ScopeProvider p) { this.dim.setScopeProvider(p); } public void setSourceProvider(SourceProvider sourceProvider) { this.dim.setSourceProvider(sourceProvider); } public void setExitAction(Runnable r) { this.debugGui.setExitAction(r); } public void pack() { this.debugGui.pack(); } public void setSize(int w, int h) { this.debugGui.setSize(w, h); } public void setVisible(boolean flag) { this.debugGui.setVisible(flag); } public boolean isVisible() { return this.debugGui.isVisible(); } public void dispose() { clearAllBreakpoints(); this.dim.go(); this.debugGui.dispose(); this.dim = null; } public void attachTo(ContextFactory factory) { this.dim.attachTo(factory); } public void detach() { this.dim.detach(); } public static ScriptDebuggerGui mainEmbedded(String title, String fileName, String code) throws Exception { ContextFactory factory = ContextFactory.getGlobal(); Global global = new Global(); global.init(factory); return mainEmbedded(factory, (Scriptable)global, title, fileName, code); } public static ScriptDebuggerGui mainEmbedded(ContextFactory factory, Scriptable scope, String title, String file, String code) throws Exception { return mainEmbeddedImpl(factory, scope, title, file, code); } public static ScriptDebuggerGui mainEmbedded(ContextFactory factory, ScopeProvider scopeProvider, String title, String fileName, String code) throws Exception { return mainEmbeddedImpl(factory, scopeProvider, title, fileName, code); } private static ScriptDebuggerGui mainEmbeddedImpl(ContextFactory factory, Object scopeProvider, String title, String fileName, String code) throws Exception { if (title == null) { title = "Rhino JavaScript Debugger (embedded usage)"; } ScriptDebuggerGui main = new ScriptDebuggerGui(title); main.doBreak(); main.setExitAction(new IProxy(1)); main.attachTo(factory); if (scopeProvider instanceof ScopeProvider) { main.setScopeProvider((ScopeProvider)scopeProvider); } else { Scriptable scope = (Scriptable)scopeProvider; main.setScope(scope); } main.pack(); main.setSize(600, 460); main.setVisible(true); Class clzRunProxy = Class.forName("org.mozilla.javascript.tools.debugger.RunProxy"); Constructor constRunProxy = clzRunProxy.getDeclaredConstructor(new Class[]{SwingGui.class, int.class}); constRunProxy.setAccessible(true); Object objRunProxy = constRunProxy.newInstance(new Object[]{main.debugGui, 2}); setClzField(objRunProxy, "fileName", fileName); setClzField(objRunProxy, "text", code); (new Thread((Runnable)objRunProxy)).start(); return main; } private static void setClzField(Object objRunProxy, String fieldName, Object value) throws Exception { Field field = objRunProxy.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(objRunProxy, value); } public void setSize(Dimension dimension) { this.debugGui.setSize(dimension.width, dimension.height); } public void setOptimizationLevel(int level) {} public void contextEntered(Context cx) { throw new IllegalStateException(); } public void contextExited(Context cx) { throw new IllegalStateException(); } public void contextCreated(Context cx) { throw new IllegalStateException(); } public void contextReleased(Context cx) { throw new IllegalStateException(); } private static class IProxy implements Runnable, ScopeProvider { private final int type; private Scriptable scope; public IProxy(int type) { this.type = type; } public static ScopeProvider newScopeProvider(Scriptable scope) { IProxy scopeProvider = new IProxy(2); scopeProvider.scope = scope; return scopeProvider; } public void run() { if (this.type != 1) Kit.codeBug(); System.exit(0); } public Scriptable getScope() { if (this.type != 2) Kit.codeBug(); if (this.scope == null) Kit.codeBug(); return this.scope; } } }