diff --git a/lib/rhino.jar b/lib/rhino.jar index 0d7132a2..194e5923 100644 Binary files a/lib/rhino.jar and b/lib/rhino.jar differ diff --git a/src/helma/doc/DocFunction.java b/src/helma/doc/DocFunction.java index 19af77e3..895883fa 100644 --- a/src/helma/doc/DocFunction.java +++ b/src/helma/doc/DocFunction.java @@ -47,7 +47,7 @@ public class DocFunction extends DocResourceElement { DocFunction func = new DocFunction(name, res, parent, ACTION); String rawComment = ""; try { - TokenStream ts = getTokenStream (res); + DockenStream ts = getDockenStream (res); Point p = getPoint (ts); ts.getToken(); rawComment = Util.getStringFromFile(res, p, getPoint(ts)); @@ -90,7 +90,7 @@ public class DocFunction extends DocResourceElement { String functionName = null; String context = null; - TokenStream ts = getTokenStream (res); + DockenStream ts = getDockenStream (res); while (!ts.eof()) { @@ -101,7 +101,7 @@ public class DocFunction extends DocResourceElement { lastToken = token; // now get a new token - // regular expression syntax is troublesome for the TokenStream + // regular expression syntax is troublesome for the DockenStream // we can safely ignore syntax errors in regular expressions here try { token = ts.getToken(); @@ -208,7 +208,7 @@ public class DocFunction extends DocResourceElement { token = ts.getToken(); int level = (token == Token.LC) ? 1 : 0; while (!ts.eof() && level > 0) { - // regular expression syntax is troublesome for the TokenStream + // regular expression syntax is troublesome for the DockenStream // we don't need them here, so we just ignore such an error try { token = ts.getToken(); @@ -250,7 +250,7 @@ public class DocFunction extends DocResourceElement { /** * creates a rhino token stream for a given file */ - protected static TokenStream getTokenStream (Resource res) throws IOException { + protected static DockenStream getDockenStream (Resource res) throws IOException { Reader reader = null; try { reader = new InputStreamReader(res.getInputStream()); @@ -258,18 +258,20 @@ public class DocFunction extends DocResourceElement { fnfe.printStackTrace(); throw new DocException (fnfe.toString()); } - String name = res.getName(); - int line = 0; + // String name = res.getName(); + Integer line = new Integer(0); CompilerEnvirons compilerEnv = new CompilerEnvirons(); compilerEnv.initFromContext(Context.getCurrentContext()); - return new TokenStream (compilerEnv, reader, null, name, line); + ErrorReporter errorReporter = Context.getCurrentContext().getErrorReporter(); + Parser parser = new Parser(compilerEnv, errorReporter); + return new DockenStream (parser, reader, null, line); } /** - * returns a pointer to the current position in the TokenStream + * returns a pointer to the current position in the DockenStream */ - protected static Point getPoint (TokenStream ts) { + protected static Point getPoint (DockenStream ts) { return new Point (ts.getOffset(), ts.getLineno()); } diff --git a/src/helma/doc/DockenStream.java b/src/helma/doc/DockenStream.java new file mode 100644 index 00000000..67e53600 --- /dev/null +++ b/src/helma/doc/DockenStream.java @@ -0,0 +1,112 @@ +/* + * Copyright 2006 Hannes Wallnoefer + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package helma.doc; + +import java.lang.reflect.Method; +import java.lang.reflect.Constructor; +import java.io.Reader; + +import org.mozilla.javascript.*; + +public class DockenStream { + + Object tokenStream; + static Constructor cnst; + static String[] names = new String[] + { "getToken", "getString", "getOffset", "getLineno", "eof" }; + static Method[] methods = new Method[5]; + final static Class[] noclass = new Class[0]; + final static Object[] noargs = new Object[0]; + + int peek; + boolean peeked; + + static { + try { + Class clazz = Class.forName("org.mozilla.javascript.TokenStream"); + cnst = clazz.getDeclaredConstructor(new Class[] {Parser.class, Reader.class, String.class, Integer.TYPE}); + for (int i = 0; i < 5; i++) { + methods[i] = clazz.getDeclaredMethod(names[i], noclass); + } + cnst.setAccessible(true); + Method.setAccessible(methods, true); + } catch (Exception x) { + x.printStackTrace(); + } + } + + public DockenStream(Parser parser, Reader reader, String name, Integer lineno) { + try { + tokenStream = cnst.newInstance(new Object[] {parser, reader, name, lineno}); + } catch (Exception x) { + throw new RuntimeException(x); + } + } + + public int getToken() { + if (peeked) { + peeked = false; + return peek; + } + try { + return ((Integer) methods[0].invoke(tokenStream, noargs)).intValue(); + } catch (Exception x) { + throw new RuntimeException(x); + } + } + + public String getString() { + try { + return (String) methods[1].invoke(tokenStream, noargs); + } catch (Exception x) { + throw new RuntimeException(x); + } + } + + public int getOffset() { + try { + return ((Integer) methods[2].invoke(tokenStream, noargs)).intValue(); + } catch (Exception x) { + throw new RuntimeException(x); + } + } + + public int getLineno() { + try { + return ((Integer) methods[3].invoke(tokenStream, noargs)).intValue(); + } catch (Exception x) { + throw new RuntimeException(x); + } + } + + public int peekToken() { + if (!peeked) { + peek = getToken(); + peeked = true; + } + return peek; + } + + public boolean eof() { + try { + return ((Boolean) methods[4].invoke(tokenStream, noargs)).booleanValue(); + } catch (Exception x) { + throw new RuntimeException(x); + } + } +} + diff --git a/src/helma/scripting/rhino/RhinoCore.java b/src/helma/scripting/rhino/RhinoCore.java index c64a4a27..1cf14561 100644 --- a/src/helma/scripting/rhino/RhinoCore.java +++ b/src/helma/scripting/rhino/RhinoCore.java @@ -18,7 +18,6 @@ package helma.scripting.rhino; import helma.scripting.rhino.extensions.*; import helma.scripting.rhino.debug.HelmaDebugger; -import helma.scripting.rhino.debug.ScopeProvider; import helma.framework.core.*; import helma.framework.repository.Resource; import helma.objectmodel.*; @@ -29,6 +28,7 @@ import helma.util.SystemMap; import helma.util.WrappedMap; import helma.util.WeakCacheMap; import org.mozilla.javascript.*; +import org.mozilla.javascript.tools.debugger.ScopeProvider; import java.io.*; import java.text.*; @@ -72,6 +72,11 @@ public final class RhinoCore implements ScopeProvider { // as the app remains unchanged long updateSnooze = 500; + static { + ContextFactory.initGlobal(new HelmaContextFactory()); + } + + /** * Create a Rhino evaluator for the given application and request evaluator. */ @@ -104,7 +109,6 @@ public final class RhinoCore implements ScopeProvider { app.logError("Invalid rhino optlevel: " + opt); } } - context.setOptimizationLevel(optLevel); try { @@ -148,25 +152,24 @@ public final class RhinoCore implements ScopeProvider { throw new RuntimeException(e.getMessage()); } finally { Context.exit(); - - if (debugger != null) { - debugger.contextExited(context); - debugger.contextReleased(context); - } } } void initDebugger(Context context) { + try { if (debugger == null) { debugger = new HelmaDebugger(app.getName()); debugger.setScopeProvider(this); - debugger.pack(); - debugger.setLocation(60, 60); + // debugger.setScope(global); + debugger.attachTo(context.getFactory()); + // debugger.pack(); + // debugger.getDebugFrame().setLocation(60, 60); + } + // if (!debugger.isVisible()) + // debugger.setVisible(true); + } catch (Exception x) { + x.printStackTrace(); } - if (!debugger.isVisible()) - debugger.setVisible(true); - debugger.contextCreated(context); - debugger.contextEntered(context); } /** @@ -1078,3 +1081,12 @@ public final class RhinoCore implements ScopeProvider { } } + +class HelmaContextFactory extends ContextFactory { + protected boolean hasFeature(Context cx, int featureIndex) { + if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) { + return true; + } + return super.hasFeature(cx, featureIndex); + } +} diff --git a/src/helma/scripting/rhino/RhinoEngine.java b/src/helma/scripting/rhino/RhinoEngine.java index a592cd50..cc1fcf3e 100644 --- a/src/helma/scripting/rhino/RhinoEngine.java +++ b/src/helma/scripting/rhino/RhinoEngine.java @@ -232,12 +232,6 @@ public class RhinoEngine implements ScriptingEngine { // core.global.unregisterScope(); thread = null; - // if visual debugger is on let it know we're exiting a context - if (core.debugger != null) { - core.debugger.contextExited(context); - core.debugger.contextReleased(context); - } - // loop through previous globals and unset them, if necessary. if (lastGlobals != null) { for (Iterator i = lastGlobals.keySet().iterator(); i.hasNext();) { diff --git a/src/helma/scripting/rhino/debug/AbstractCellEditor.java b/src/helma/scripting/rhino/debug/AbstractCellEditor.java deleted file mode 100644 index 0a7317d0..00000000 --- a/src/helma/scripting/rhino/debug/AbstractCellEditor.java +++ /dev/null @@ -1,63 +0,0 @@ - - package helma.scripting.rhino.debug; - import java.awt.Component; - -import java.awt.event.*; -import java.awt.AWTEvent; -import javax.swing.*; -import javax.swing.event.*; -import java.util.EventObject; -import java.io.Serializable; - -public class AbstractCellEditor implements CellEditor { - - protected EventListenerList listenerList = new EventListenerList(); - - public Object getCellEditorValue() { return null; } - public boolean isCellEditable(EventObject e) { return true; } - public boolean shouldSelectCell(EventObject anEvent) { return false; } - public boolean stopCellEditing() { return true; } - public void cancelCellEditing() {} - - public void addCellEditorListener(CellEditorListener l) { - listenerList.add(CellEditorListener.class, l); - } - - public void removeCellEditorListener(CellEditorListener l) { - listenerList.remove(CellEditorListener.class, l); - } - - /* - * Notify all listeners that have registered interest for - * notification on this event type. - * @see EventListenerList - */ - protected void fireEditingStopped() { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==CellEditorListener.class) { - ((CellEditorListener)listeners[i+1]).editingStopped(new ChangeEvent(this)); - } - } - } - - /* - * Notify all listeners that have registered interest for - * notification on this event type. - * @see EventListenerList - */ - protected void fireEditingCanceled() { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==CellEditorListener.class) { - ((CellEditorListener)listeners[i+1]).editingCanceled(new ChangeEvent(this)); - } - } - } -} diff --git a/src/helma/scripting/rhino/debug/AbstractTreeTableModel.java b/src/helma/scripting/rhino/debug/AbstractTreeTableModel.java deleted file mode 100644 index 31b91495..00000000 --- a/src/helma/scripting/rhino/debug/AbstractTreeTableModel.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * @(#)AbstractTreeTableModel.java 1.2 98/10/27 - * - * Copyright 1997, 1998 by Sun Microsystems, Inc., - * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. - * All rights reserved. - * - * This software is the confidential and proprietary information - * of Sun Microsystems, Inc. ("Confidential Information"). You - * shall not disclose such Confidential Information and shall use - * it only in accordance with the terms of the license agreement - * you entered into with Sun. - */ - - - package helma.scripting.rhino.debug; - import javax.swing.tree.*; - -import javax.swing.event.*; - -/** - * @version 1.2 10/27/98 - * An abstract implementation of the TreeTableModel interface, handling the list - * of listeners. - * @author Philip Milne - */ - -public abstract class AbstractTreeTableModel implements TreeTableModel { - protected Object root; - protected EventListenerList listenerList = new EventListenerList(); - - public AbstractTreeTableModel(Object root) { - this.root = root; - } - - // - // Default implmentations for methods in the TreeModel interface. - // - - public Object getRoot() { - return root; - } - - public boolean isLeaf(Object node) { - return getChildCount(node) == 0; - } - - public void valueForPathChanged(TreePath path, Object newValue) {} - - // This is not called in the JTree's default mode: use a naive implementation. - public int getIndexOfChild(Object parent, Object child) { - for (int i = 0; i < getChildCount(parent); i++) { - if (getChild(parent, i).equals(child)) { - return i; - } - } - return -1; - } - - public void addTreeModelListener(TreeModelListener l) { - listenerList.add(TreeModelListener.class, l); - } - - public void removeTreeModelListener(TreeModelListener l) { - listenerList.remove(TreeModelListener.class, l); - } - - /* - * Notify all listeners that have registered interest for - * notification on this event type. The event instance - * is lazily created using the parameters passed into - * the fire method. - * @see EventListenerList - */ - protected void fireTreeNodesChanged(Object source, Object[] path, - int[] childIndices, - Object[] children) { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - TreeModelEvent e = null; - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // Lazily create the event: - if (e == null) - e = new TreeModelEvent(source, path, - childIndices, children); - ((TreeModelListener)listeners[i+1]).treeNodesChanged(e); - } - } - } - - /* - * Notify all listeners that have registered interest for - * notification on this event type. The event instance - * is lazily created using the parameters passed into - * the fire method. - * @see EventListenerList - */ - protected void fireTreeNodesInserted(Object source, Object[] path, - int[] childIndices, - Object[] children) { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - TreeModelEvent e = null; - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // Lazily create the event: - if (e == null) - e = new TreeModelEvent(source, path, - childIndices, children); - ((TreeModelListener)listeners[i+1]).treeNodesInserted(e); - } - } - } - - /* - * Notify all listeners that have registered interest for - * notification on this event type. The event instance - * is lazily created using the parameters passed into - * the fire method. - * @see EventListenerList - */ - protected void fireTreeNodesRemoved(Object source, Object[] path, - int[] childIndices, - Object[] children) { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - TreeModelEvent e = null; - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // Lazily create the event: - if (e == null) - e = new TreeModelEvent(source, path, - childIndices, children); - ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e); - } - } - } - - /* - * Notify all listeners that have registered interest for - * notification on this event type. The event instance - * is lazily created using the parameters passed into - * the fire method. - * @see EventListenerList - */ - protected void fireTreeStructureChanged(Object source, Object[] path, - int[] childIndices, - Object[] children) { - // Guaranteed to return a non-null array - Object[] listeners = listenerList.getListenerList(); - TreeModelEvent e = null; - // Process the listeners last to first, notifying - // those that are interested in this event - for (int i = listeners.length-2; i>=0; i-=2) { - if (listeners[i]==TreeModelListener.class) { - // Lazily create the event: - if (e == null) - e = new TreeModelEvent(source, path, - childIndices, children); - ((TreeModelListener)listeners[i+1]).treeStructureChanged(e); - } - } - } - - // - // Default impelmentations for methods in the TreeTableModel interface. - // - - public Class getColumnClass(int column) { return Object.class; } - - /** By default, make the column with the Tree in it the only editable one. - * Making this column editable causes the JTable to forward mouse - * and keyboard events in the Tree column to the underlying JTree. - */ - public boolean isCellEditable(Object node, int column) { - return getColumnClass(column) == TreeTableModel.class; - } - - public void setValueAt(Object aValue, Object node, int column) {} - - - // Left to be implemented in the subclass: - - /* - * public Object getChild(Object parent, int index) - * public int getChildCount(Object parent) - * public int getColumnCount() - * public String getColumnName(Object node, int column) - * public Object getValueAt(Object node, int column) - */ -} diff --git a/src/helma/scripting/rhino/debug/HelmaDebugger.java b/src/helma/scripting/rhino/debug/HelmaDebugger.java index 4027ae6b..c4a2d19e 100644 --- a/src/helma/scripting/rhino/debug/HelmaDebugger.java +++ b/src/helma/scripting/rhino/debug/HelmaDebugger.java @@ -16,24 +16,30 @@ package helma.scripting.rhino.debug; +import org.mozilla.javascript.tools.debugger.Main; +import org.mozilla.javascript.tools.debugger.SwingGui; +import org.mozilla.javascript.tools.debugger.Dim; import org.mozilla.javascript.Context; import org.mozilla.javascript.debug.DebuggableScript; +import javax.swing.tree.*; import javax.swing.*; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionEvent; -import javax.swing.tree.*; -import java.awt.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.util.*; +import java.awt.*; import helma.util.StringUtils; -public class HelmaDebugger extends Main implements TreeSelectionListener { +public class HelmaDebugger extends Dim implements TreeSelectionListener { + + DebugGui gui; JTree tree; JList list; DebuggerTreeNode treeRoot; @@ -41,80 +47,22 @@ public class HelmaDebugger extends Main implements TreeSelectionListener { HashMap treeNodes = new HashMap(); HashMap scriptNames = new HashMap(); - public HelmaDebugger(String name) { - super(name); - Container contentPane = getContentPane(); - Component main = contentPane.getComponent(1); - contentPane.remove(main); - treeRoot = new DebuggerTreeNode(name); - tree = new JTree(treeRoot); - treeModel = new DefaultTreeModel(treeRoot); - tree.setModel(treeModel); - tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); - tree.addTreeSelectionListener(this); - // tree.setRootVisible(false); - // track double clicks - tree.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent evt) { - openScript(tree.getSelectionPath()); - } - }); - // track enter key - tree.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent evt) { - if (evt.getKeyCode() == KeyEvent.VK_ENTER) - openScript(tree.getSelectionPath()); - } - }); - JScrollPane treeScroller = new JScrollPane(tree); - treeScroller.setPreferredSize(new Dimension(180, 300)); - - list = new JList(); - // no bold font lists for me, thanks - list.setFont(list.getFont().deriveFont(Font.PLAIN)); - list.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent evt) { - openFunction((String) list.getSelectedValue()); - } - }); - list.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent evt) { - if (evt.getKeyCode() == KeyEvent.VK_ENTER) - openFunction((String) list.getSelectedValue()); - } - }); - JScrollPane listScroller = new JScrollPane(list); - listScroller.setPreferredSize(new Dimension(180, 200)); - - JSplitPane split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT); - split1.setTopComponent(treeScroller); - split1.setBottomComponent(listScroller); - split1.setOneTouchExpandable(true); - Main.setResizeWeight(split1, 0.66); - - JSplitPane split2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - split2.setLeftComponent(split1); - split2.setRightComponent(main); - split2.setOneTouchExpandable(true); - contentPane.add(split2, BorderLayout.CENTER); - } - - public void setVisible(boolean b) { - super.setVisible(b); - // hide console window - console.hide(); + public HelmaDebugger(String title) { + gui = new DebugGui(this, title); + gui.pack(); + gui.setVisible(true); } public void handleCompilationDone(Context cx, DebuggableScript fnOrScript, String source) { String sourceName = fnOrScript.getSourceName(); - FileWindow w = (FileWindow) fileWindows.get(sourceName); - super.handleCompilationDone(cx, fnOrScript, source); + // FileWindow w = (FileWindow) fileWindows.get(sourceName); + /* super.(cx, fnOrScript, source); if (!treeNodes.containsKey(sourceName)) { createTreeNode(sourceName); - } - if (w != null) { + } */ + /* if (w != null) { // renew existing file window int position = w.textArea.getCaretPosition(); // System.err.println(" VISIBLE: " + point); @@ -122,10 +70,10 @@ public class HelmaDebugger extends Main implements TreeSelectionListener { w.sourceInfo = (SourceInfo) sourceNames.get(sourceName); w.updateText(); w.textArea.setCaretPosition(position); - } + } */ } - void createTreeNode(String sourceName) { + void createTreeNode(String sourceName, Dim.SourceInfo sourceInfo) { String[] path = StringUtils.split(sourceName, ":/\\"); DebuggerTreeNode node = treeRoot; DebuggerTreeNode newNode = null; @@ -151,27 +99,13 @@ public class HelmaDebugger extends Main implements TreeSelectionListener { Object node = path.getLastPathComponent(); if (node == null) return; - String scriptName = (String) scriptNames.get(node); - if (scriptName == null) + String sourceName = (String) scriptNames.get(node); + if (sourceName == null) return; - JInternalFrame w = (JInternalFrame) fileWindows.get(scriptName); - if (w != null) { - try { - if (w.isIcon()) - w.setMaximum(true); - w.show(); - w.setSelected(true); - } catch (Exception exc) { - } - } else { - SourceInfo si = (SourceInfo) sourceNames.get(scriptName); - if (si == null) { - System.out.println("debugger error: Couldn't find source: " + scriptName); - } - swingInvoke(CreateFileWindow.action(this, si, -1)); - } + SourceInfo sourceInfo = sourceInfo(sourceName); + gui.showSourceText(sourceInfo); // display functions for opened script file - Vector functions = new Vector(); + /*Vector functions = new Vector(); Iterator it = functionNames.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); @@ -181,13 +115,13 @@ public class HelmaDebugger extends Main implements TreeSelectionListener { } } Collections.sort(functions); - list.setListData(functions); + list.setListData(functions); */ } void openFunction(String function) { if (function == null) return; - ScriptItem item = (ScriptItem) functionNames.get(function); + /* ScriptItem item = (ScriptItem) functionNames.get(function); if (item != null) { SourceInfo si = item.getSourceInfo(); String url = si.getUrl(); @@ -212,10 +146,12 @@ public class HelmaDebugger extends Main implements TreeSelectionListener { w.textArea.requestFocus(); } catch (Exception exc) { } - } + } */ } - public void valueChanged(TreeSelectionEvent e) { + + + public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); @@ -260,5 +196,78 @@ public class HelmaDebugger extends Main implements TreeSelectionListener { } } + class DebugGui extends SwingGui { + public DebugGui(Dim dim, String title) { + super(dim, title); + Container contentPane = getContentPane(); + Component main = contentPane.getComponent(1); + contentPane.remove(main); + + treeRoot = new DebuggerTreeNode(title); + tree = new JTree(treeRoot); + treeModel = new DefaultTreeModel(treeRoot); + tree.setModel(treeModel); + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.addTreeSelectionListener(HelmaDebugger.this); + // tree.setRootVisible(false); + // track double clicks + tree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent evt) { + openScript(tree.getSelectionPath()); + } + }); + // track enter key + tree.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + if (evt.getKeyCode() == KeyEvent.VK_ENTER) + openScript(tree.getSelectionPath()); + } + }); + JScrollPane treeScroller = new JScrollPane(tree); + treeScroller.setPreferredSize(new Dimension(180, 300)); + + list = new JList(); + // no bold font lists for me, thanks + list.setFont(list.getFont().deriveFont(Font.PLAIN)); + list.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent evt) { + openFunction((String) list.getSelectedValue()); + } + }); + list.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + if (evt.getKeyCode() == KeyEvent.VK_ENTER) + openFunction((String) list.getSelectedValue()); + } + }); + JScrollPane listScroller = new JScrollPane(list); + listScroller.setPreferredSize(new Dimension(180, 200)); + + JSplitPane split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + split1.setTopComponent(treeScroller); + split1.setBottomComponent(listScroller); + split1.setOneTouchExpandable(true); + split1.setResizeWeight(0.66); + + JSplitPane split2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + split2.setLeftComponent(split1); + split2.setRightComponent(main); + split2.setOneTouchExpandable(true); + contentPane.add(split2, BorderLayout.CENTER); + } + + public void updateSourceText(Dim.SourceInfo sourceInfo) { + // super.updateSourceText(sourceInfo); + String filename = sourceInfo.url(); + if (!treeNodes.containsKey(filename)) { + createTreeNode(filename, sourceInfo); + } + // System.err.println("UPDATE SOURCE TEXT CALLED: " + sourceInfo.url()); + } + + public void showSourceText(Dim.SourceInfo sourceInfo) { + super.updateSourceText(sourceInfo); + } + } } diff --git a/src/helma/scripting/rhino/debug/JTreeTable.java b/src/helma/scripting/rhino/debug/JTreeTable.java deleted file mode 100644 index f235086b..00000000 --- a/src/helma/scripting/rhino/debug/JTreeTable.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * @(#)JTreeTable.java 1.2 98/10/27 - * - * Copyright 1997, 1998 by Sun Microsystems, Inc., - * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. - * All rights reserved. - * - * This software is the confidential and proprietary information - * of Sun Microsystems, Inc. ("Confidential Information"). You - * shall not disclose such Confidential Information and shall use - * it only in accordance with the terms of the license agreement - * you entered into with Sun. - */ - - - package helma.scripting.rhino.debug; - import javax.swing.*; - -import javax.swing.event.*; -import javax.swing.tree.*; -import javax.swing.table.*; - -import java.awt.Dimension; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Rectangle; - -import java.awt.event.MouseEvent; - -import java.util.EventObject; - -/** - * This example shows how to create a simple JTreeTable component, - * by using a JTree as a renderer (and editor) for the cells in a - * particular column in the JTable. - * - * @version 1.2 10/27/98 - * - * @author Philip Milne - * @author Scott Violet - */ -public class JTreeTable extends JTable { - /** A subclass of JTree. */ - protected TreeTableCellRenderer tree; - - public JTreeTable(TreeTableModel treeTableModel) { - super(); - - // Create the tree. It will be used as a renderer and editor. - tree = new TreeTableCellRenderer(treeTableModel); - - // Install a tableModel representing the visible rows in the tree. - super.setModel(new TreeTableModelAdapter(treeTableModel, tree)); - - // Force the JTable and JTree to share their row selection models. - ListToTreeSelectionModelWrapper selectionWrapper = new - ListToTreeSelectionModelWrapper(); - tree.setSelectionModel(selectionWrapper); - setSelectionModel(selectionWrapper.getListSelectionModel()); - - // Install the tree editor renderer and editor. - setDefaultRenderer(TreeTableModel.class, tree); - setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor()); - - // No grid. - setShowGrid(false); - - // No intercell spacing - setIntercellSpacing(new Dimension(0, 0)); - - // And update the height of the trees row to match that of - // the table. - if (tree.getRowHeight() < 1) { - // Metal looks better like this. - setRowHeight(18); - } - } - - /** - * Overridden to message super and forward the method to the tree. - * Since the tree is not actually in the component hieachy it will - * never receive this unless we forward it in this manner. - */ - public void updateUI() { - super.updateUI(); - if(tree != null) { - tree.updateUI(); - } - // Use the tree's default foreground and background colors in the - // table. - LookAndFeel.installColorsAndFont(this, "Tree.background", - "Tree.foreground", "Tree.font"); - } - - /* Workaround for BasicTableUI anomaly. Make sure the UI never tries to - * paint the editor. The UI currently uses different techniques to - * paint the renderers and editors and overriding setBounds() below - * is not the right thing to do for an editor. Returning -1 for the - * editing row in this case, ensures the editor is never painted. - */ - public int getEditingRow() { - return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 : - editingRow; - } - - /** - * Overridden to pass the new rowHeight to the tree. - */ - public void setRowHeight(int rowHeight) { - super.setRowHeight(rowHeight); - if (tree != null && tree.getRowHeight() != rowHeight) { - tree.setRowHeight(getRowHeight()); - } - } - - /** - * Returns the tree that is being shared between the model. - */ - public JTree getTree() { - return tree; - } - - /** - * A TreeCellRenderer that displays a JTree. - */ - public class TreeTableCellRenderer extends JTree implements - TableCellRenderer { - /** Last table/tree row asked to renderer. */ - protected int visibleRow; - - public TreeTableCellRenderer(TreeModel model) { - super(model); - } - - /** - * updateUI is overridden to set the colors of the Tree's renderer - * to match that of the table. - */ - public void updateUI() { - super.updateUI(); - // Make the tree's cell renderer use the table's cell selection - // colors. - TreeCellRenderer tcr = getCellRenderer(); - if (tcr instanceof DefaultTreeCellRenderer) { - DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer)tcr); - // For 1.1 uncomment this, 1.2 has a bug that will cause an - // exception to be thrown if the border selection color is - // null. - // dtcr.setBorderSelectionColor(null); - dtcr.setTextSelectionColor(UIManager.getColor - ("Table.selectionForeground")); - dtcr.setBackgroundSelectionColor(UIManager.getColor - ("Table.selectionBackground")); - } - } - - /** - * Sets the row height of the tree, and forwards the row height to - * the table. - */ - public void setRowHeight(int rowHeight) { - if (rowHeight > 0) { - super.setRowHeight(rowHeight); - if (JTreeTable.this != null && - JTreeTable.this.getRowHeight() != rowHeight) { - JTreeTable.this.setRowHeight(getRowHeight()); - } - } - } - - /** - * This is overridden to set the height to match that of the JTable. - */ - public void setBounds(int x, int y, int w, int h) { - super.setBounds(x, 0, w, JTreeTable.this.getHeight()); - } - - /** - * Sublcassed to translate the graphics such that the last visible - * row will be drawn at 0,0. - */ - public void paint(Graphics g) { - g.translate(0, -visibleRow * getRowHeight()); - super.paint(g); - } - - /** - * TreeCellRenderer method. Overridden to update the visible row. - */ - public Component getTableCellRendererComponent(JTable table, - Object value, - boolean isSelected, - boolean hasFocus, - int row, int column) { - if(isSelected) - setBackground(table.getSelectionBackground()); - else - setBackground(table.getBackground()); - - visibleRow = row; - return this; - } - } - - - /** - * TreeTableCellEditor implementation. Component returned is the - * JTree. - */ - public class TreeTableCellEditor extends AbstractCellEditor implements - TableCellEditor { - public Component getTableCellEditorComponent(JTable table, - Object value, - boolean isSelected, - int r, int c) { - return tree; - } - - /** - * Overridden to return false, and if the event is a mouse event - * it is forwarded to the tree.

- * The behavior for this is debatable, and should really be offered - * as a property. By returning false, all keyboard actions are - * implemented in terms of the table. By returning true, the - * tree would get a chance to do something with the keyboard - * events. For the most part this is ok. But for certain keys, - * such as left/right, the tree will expand/collapse where as - * the table focus should really move to a different column. Page - * up/down should also be implemented in terms of the table. - * By returning false this also has the added benefit that clicking - * outside of the bounds of the tree node, but still in the tree - * column will select the row, whereas if this returned true - * that wouldn't be the case. - *

By returning false we are also enforcing the policy that - * the tree will never be editable (at least by a key sequence). - */ - public boolean isCellEditable(EventObject e) { - if (e instanceof MouseEvent) { - for (int counter = getColumnCount() - 1; counter >= 0; - counter--) { - if (getColumnClass(counter) == TreeTableModel.class) { - MouseEvent me = (MouseEvent)e; - MouseEvent newME = new MouseEvent(tree, me.getID(), - me.getWhen(), me.getModifiers(), - me.getX() - getCellRect(0, counter, true).x, - me.getY(), me.getClickCount(), - me.isPopupTrigger()); - tree.dispatchEvent(newME); - break; - } - } - } - return false; - } - } - - - /** - * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel - * to listen for changes in the ListSelectionModel it maintains. Once - * a change in the ListSelectionModel happens, the paths are updated - * in the DefaultTreeSelectionModel. - */ - class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel { - /** Set to true when we are updating the ListSelectionModel. */ - protected boolean updatingListSelectionModel; - - public ListToTreeSelectionModelWrapper() { - super(); - getListSelectionModel().addListSelectionListener - (createListSelectionListener()); - } - - /** - * Returns the list selection model. ListToTreeSelectionModelWrapper - * listens for changes to this model and updates the selected paths - * accordingly. - */ - ListSelectionModel getListSelectionModel() { - return listSelectionModel; - } - - /** - * This is overridden to set updatingListSelectionModel - * and message super. This is the only place DefaultTreeSelectionModel - * alters the ListSelectionModel. - */ - public void resetRowSelection() { - if(!updatingListSelectionModel) { - updatingListSelectionModel = true; - try { - super.resetRowSelection(); - } - finally { - updatingListSelectionModel = false; - } - } - // Notice how we don't message super if - // updatingListSelectionModel is true. If - // updatingListSelectionModel is true, it implies the - // ListSelectionModel has already been updated and the - // paths are the only thing that needs to be updated. - } - - /** - * Creates and returns an instance of ListSelectionHandler. - */ - protected ListSelectionListener createListSelectionListener() { - return new ListSelectionHandler(); - } - - /** - * If updatingListSelectionModel is false, this will - * reset the selected paths from the selected rows in the list - * selection model. - */ - protected void updateSelectedPathsFromSelectedRows() { - if(!updatingListSelectionModel) { - updatingListSelectionModel = true; - try { - // This is way expensive, ListSelectionModel needs an - // enumerator for iterating. - int min = listSelectionModel.getMinSelectionIndex(); - int max = listSelectionModel.getMaxSelectionIndex(); - - clearSelection(); - if(min != -1 && max != -1) { - for(int counter = min; counter <= max; counter++) { - if(listSelectionModel.isSelectedIndex(counter)) { - TreePath selPath = tree.getPathForRow - (counter); - - if(selPath != null) { - addSelectionPath(selPath); - } - } - } - } - } - finally { - updatingListSelectionModel = false; - } - } - } - - /** - * Class responsible for calling updateSelectedPathsFromSelectedRows - * when the selection of the list changse. - */ - class ListSelectionHandler implements ListSelectionListener { - public void valueChanged(ListSelectionEvent e) { - updateSelectedPathsFromSelectedRows(); - } - } - } -} diff --git a/src/helma/scripting/rhino/debug/Main.java b/src/helma/scripting/rhino/debug/Main.java deleted file mode 100644 index 06ad12b7..00000000 --- a/src/helma/scripting/rhino/debug/Main.java +++ /dev/null @@ -1,3640 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino JavaScript Debugger code, released - * November 21, 2000. - * - * The Initial Developer of the Original Code is SeeBeyond Corporation. - - * Portions created by SeeBeyond are - * Copyright (C) 2000 SeeBeyond Technology Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Christopher Oliver - * Matt Gould - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package helma.scripting.rhino.debug; - -import javax.swing.*; -import javax.swing.text.*; -import javax.swing.event.*; -import javax.swing.table.*; -import java.awt.*; -import java.awt.event.*; -import java.util.StringTokenizer; - -import org.mozilla.javascript.*; -import org.mozilla.javascript.debug.*; -import org.mozilla.javascript.tools.shell.ConsoleTextArea; -import java.util.*; -import java.io.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeCellRenderer; -import java.lang.reflect.Method; -import java.net.URL; - -class MessageDialogWrapper { - - static void showMessageDialog(Component parent, String msg, - String title, int flags) { - if (msg.length() > 60) { - StringBuffer buf = new StringBuffer(); - int len = msg.length(); - int j = 0; - int i; - for (i = 0; i < len; i++, j++) { - char c = msg.charAt(i); - buf.append(c); - if (Character.isWhitespace(c)) { - int remainder = len - i; - int k; - for (k = i + 1; k < len; k++) { - if (Character.isWhitespace(msg.charAt(k))) { - break; - } - } - if (k < len) { - int nextWordLen = k - i; - if (j + nextWordLen > 60) { - buf.append('\n'); - j = 0; - } - } - } - } - msg = buf.toString(); - } - JOptionPane.showMessageDialog(parent, msg, title, flags); - } -}; - -class EvalTextArea extends JTextArea implements KeyListener, -DocumentListener { - Main db; - private java.util.Vector history; - private int historyIndex = -1; - private int outputMark = 0; - - public void select(int start, int end) { - //requestFocus(); - super.select(start, end); - } - - public EvalTextArea(Main db) { - super(); - this.db = db; - history = new java.util.Vector(); - Document doc = getDocument(); - doc.addDocumentListener(this); - addKeyListener(this); - setLineWrap(true); - setFont(new Font("Monospaced", 0, 12)); - append("% "); - outputMark = doc.getLength(); - } - - synchronized void returnPressed() { - Document doc = getDocument(); - int len = doc.getLength(); - Segment segment = new Segment(); - try { - doc.getText(outputMark, len - outputMark, segment); - } catch (javax.swing.text.BadLocationException ignored) { - ignored.printStackTrace(); - } - String text = segment.toString(); - if (db.stringIsCompilableUnit(text)) { - if (text.trim().length() > 0) { - history.addElement(text); - historyIndex = history.size(); - } - append("\n"); - String result = db.eval(text); - if (result.length() > 0) { - append(result); - append("\n"); - } - append("% "); - outputMark = doc.getLength(); - } else { - append("\n"); - } - } - - public void keyPressed(KeyEvent e) { - int code = e.getKeyCode(); - if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) { - if (outputMark == getCaretPosition()) { - e.consume(); - } - } else if (code == KeyEvent.VK_HOME) { - int caretPos = getCaretPosition(); - if (caretPos == outputMark) { - e.consume(); - } else if (caretPos > outputMark) { - if (!e.isControlDown()) { - if (e.isShiftDown()) { - moveCaretPosition(outputMark); - } else { - setCaretPosition(outputMark); - } - e.consume(); - } - } - } else if (code == KeyEvent.VK_ENTER) { - returnPressed(); - e.consume(); - } else if (code == KeyEvent.VK_UP) { - historyIndex--; - if (historyIndex >= 0) { - if (historyIndex >= history.size()) { - historyIndex = history.size() -1; - } - if (historyIndex >= 0) { - String str = (String)history.elementAt(historyIndex); - int len = getDocument().getLength(); - replaceRange(str, outputMark, len); - int caretPos = outputMark + str.length(); - select(caretPos, caretPos); - } else { - historyIndex++; - } - } else { - historyIndex++; - } - e.consume(); - } else if (code == KeyEvent.VK_DOWN) { - int caretPos = outputMark; - if (history.size() > 0) { - historyIndex++; - if (historyIndex < 0) {historyIndex = 0;} - int len = getDocument().getLength(); - if (historyIndex < history.size()) { - String str = (String)history.elementAt(historyIndex); - replaceRange(str, outputMark, len); - caretPos = outputMark + str.length(); - } else { - historyIndex = history.size(); - replaceRange("", outputMark, len); - } - } - select(caretPos, caretPos); - e.consume(); - } - } - - public void keyTyped(KeyEvent e) { - int keyChar = e.getKeyChar(); - if (keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */) { - if (outputMark == getCaretPosition()) { - e.consume(); - } - } else if (getCaretPosition() < outputMark) { - setCaretPosition(outputMark); - } - } - - public synchronized void keyReleased(KeyEvent e) { - } - - public synchronized void write(String str) { - insert(str, outputMark); - int len = str.length(); - outputMark += len; - select(outputMark, outputMark); - } - - public synchronized void insertUpdate(DocumentEvent e) { - int len = e.getLength(); - int off = e.getOffset(); - if (outputMark > off) { - outputMark += len; - } - } - - public synchronized void removeUpdate(DocumentEvent e) { - int len = e.getLength(); - int off = e.getOffset(); - if (outputMark > off) { - if (outputMark >= off + len) { - outputMark -= len; - } else { - outputMark = off; - } - } - } - - public synchronized void postUpdateUI() { - // this attempts to cleanup the damage done by updateComponentTreeUI - //requestFocus(); - setCaret(getCaret()); - select(outputMark, outputMark); - } - - public synchronized void changedUpdate(DocumentEvent e) { - } -}; - -class EvalWindow extends JInternalFrame -implements ActionListener { - - EvalTextArea evalTextArea; - - public void setEnabled(boolean b) { - super.setEnabled(b); - evalTextArea.setEnabled(b); - } - - public EvalWindow(String name, Main db) { - super(name, true, false, true, true); - evalTextArea = new EvalTextArea(db); - evalTextArea.setRows(24); - evalTextArea.setColumns(80); - JScrollPane scroller = new JScrollPane(evalTextArea); - setContentPane(scroller); - //scroller.setPreferredSize(new Dimension(600, 400)); - pack(); - setVisible(true); - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - if (cmd.equals("Cut")) { - evalTextArea.cut(); - } else if (cmd.equals("Copy")) { - evalTextArea.copy(); - } else if (cmd.equals("Paste")) { - evalTextArea.paste(); - } - } -}; - -class JSInternalConsole extends JInternalFrame - implements ActionListener { - - ConsoleTextArea consoleTextArea; - - public InputStream getIn() { - return consoleTextArea.getIn(); - } - - public PrintStream getOut() { - return consoleTextArea.getOut(); - } - - public PrintStream getErr() { - return consoleTextArea.getErr(); - } - - public JSInternalConsole(String name) { - super(name, true, false, true, true); - consoleTextArea = new ConsoleTextArea(null); - consoleTextArea.setRows(24); - consoleTextArea.setColumns(80); - JScrollPane scroller = new JScrollPane(consoleTextArea); - setContentPane(scroller); - pack(); - addInternalFrameListener(new InternalFrameAdapter() { - public void internalFrameActivated(InternalFrameEvent e) { - // hack - if (consoleTextArea.hasFocus()) { - consoleTextArea.getCaret().setVisible(false); - consoleTextArea.getCaret().setVisible(true); - } - } - }); - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - if (cmd.equals("Cut")) { - consoleTextArea.cut(); - } else if (cmd.equals("Copy")) { - consoleTextArea.copy(); - } else if (cmd.equals("Paste")) { - consoleTextArea.paste(); - } - } - - -}; - -class FilePopupMenu extends JPopupMenu { - FileTextArea w; - int x, y; - - FilePopupMenu(FileTextArea w) { - super(); - this.w = w; - JMenuItem item; - add(item = new JMenuItem("Set Breakpoint")); - item.addActionListener(w); - add(item = new JMenuItem("Clear Breakpoint")); - item.addActionListener(w); - //add(item = new JMenuItem("Run to Cursor")); - //item.addActionListener(w); - add(item = new JMenuItem("Run")); - item.addActionListener(w); - } - - void show(JComponent comp, int x, int y) { - this.x = x; - this.y = y; - super.show(comp, x, y); - } -}; - -class FileTextArea extends JTextArea implements ActionListener, - PopupMenuListener, - KeyListener, - MouseListener { - FileWindow w; - FilePopupMenu popup; - - FileTextArea(FileWindow w) { - this.w = w; - popup = new FilePopupMenu(this); - popup.addPopupMenuListener(this); - addMouseListener(this); - addKeyListener(this); - setFont(new Font("Monospaced", 0, 12)); - } - - void select(int pos) { - if (pos >= 0) { - try { - int line = getLineOfOffset(pos); - Rectangle rect = modelToView(pos); - if (rect == null) { - select(pos, pos); - } else { - try { - Rectangle nrect = - modelToView(getLineStartOffset(line + 1)); - if (nrect != null) { - rect = nrect; - } - } catch (Exception exc) { - } - JViewport vp = (JViewport)getParent(); - Rectangle viewRect = vp.getViewRect(); - if (viewRect.y + viewRect.height > rect.y) { - // need to scroll up - select(pos, pos); - } else { - // need to scroll down - rect.y += (viewRect.height - rect.height)/2; - scrollRectToVisible(rect); - select(pos, pos); - } - } - } catch (BadLocationException exc) { - select(pos, pos); - //exc.printStackTrace(); - } - } - } - - - public void mousePressed(MouseEvent e) { - checkPopup(e); - } - public void mouseClicked(MouseEvent e) { - checkPopup(e); - requestFocus(); - getCaret().setVisible(true); - } - public void mouseEntered(MouseEvent e) { - } - public void mouseExited(MouseEvent e) { - } - public void mouseReleased(MouseEvent e) { - checkPopup(e); - } - - private void checkPopup(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(this, e.getX(), e.getY()); - } - } - - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - } - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - } - public void popupMenuCanceled(PopupMenuEvent e) { - } - public void actionPerformed(ActionEvent e) { - int pos = viewToModel(new Point(popup.x, popup.y)); - popup.setVisible(false); - String cmd = e.getActionCommand(); - int line = -1; - try { - line = getLineOfOffset(pos); - } catch (Exception exc) { - } - if (cmd.equals("Set Breakpoint")) { - w.setBreakPoint(line + 1); - } else if (cmd.equals("Clear Breakpoint")) { - w.clearBreakPoint(line + 1); - } else if (cmd.equals("Run to Cursor")) { - w.runToCursor(e); - } else if (cmd.equals("Run")) { - w.load(); - } - } - public void keyPressed(KeyEvent e) { - switch (e.getKeyCode()) { - case KeyEvent.VK_BACK_SPACE: - case KeyEvent.VK_ENTER: - case KeyEvent.VK_DELETE: - e.consume(); - break; - } - } - public void keyTyped(KeyEvent e) { - e.consume(); - } - public void keyReleased(KeyEvent e) { - e.consume(); - } -} - -class MoreWindows extends JDialog implements ActionListener { - - private String value = null; - private JList list; - Hashtable fileWindows; - JButton setButton; - JButton refreshButton; - JButton cancelButton; - - - public String showDialog(Component comp) { - value = null; - setLocationRelativeTo(comp); - setVisible(true); - return value; - } - - private void setValue(String newValue) { - value = newValue; - list.setSelectedValue(value, true); - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - if (cmd.equals("Cancel")) { - setVisible(false); - value = null; - } else if (cmd.equals("Select")) { - value = (String)list.getSelectedValue(); - setVisible(false); - JInternalFrame w = (JInternalFrame)fileWindows.get(value); - if (w != null) { - try { - w.show(); - w.setSelected(true); - } catch (Exception exc) { - } - } - } - } - - class MouseHandler extends MouseAdapter { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - setButton.doClick(); - } - } - }; - - MoreWindows(JFrame frame, Hashtable fileWindows, - String title, - String labelText) { - super(frame, title, true); - this.fileWindows = fileWindows; - //buttons - cancelButton = new JButton("Cancel"); - setButton = new JButton("Select"); - cancelButton.addActionListener(this); - setButton.addActionListener(this); - getRootPane().setDefaultButton(setButton); - - //main part of the dialog - list = new JList(new DefaultListModel()); - DefaultListModel model = (DefaultListModel)list.getModel(); - model.clear(); - //model.fireIntervalRemoved(model, 0, size); - Enumeration e = fileWindows.keys(); - while (e.hasMoreElements()) { - String data = e.nextElement().toString(); - model.addElement(data); - } - list.setSelectedIndex(0); - //model.fireIntervalAdded(model, 0, data.length); - setButton.setEnabled(true); - list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); - list.addMouseListener(new MouseHandler()); - JScrollPane listScroller = new JScrollPane(list); - listScroller.setPreferredSize(new Dimension(320, 240)); - //XXX: Must do the following, too, or else the scroller thinks - //XXX: it's taller than it is: - listScroller.setMinimumSize(new Dimension(250, 80)); - listScroller.setAlignmentX(LEFT_ALIGNMENT); - - //Create a container so that we can add a title around - //the scroll pane. Can't add a title directly to the - //scroll pane because its background would be white. - //Lay out the label and scroll pane from top to button. - JPanel listPane = new JPanel(); - listPane.setLayout(new BoxLayout(listPane, BoxLayout.Y_AXIS)); - JLabel label = new JLabel(labelText); - label.setLabelFor (list); - listPane.add(label); - listPane.add(Box.createRigidArea(new Dimension(0,5))); - listPane.add(listScroller); - listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); - - //Lay out the buttons from left to right. - JPanel buttonPane = new JPanel(); - buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); - buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); - buttonPane.add(Box.createHorizontalGlue()); - buttonPane.add(cancelButton); - buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); - buttonPane.add(setButton); - - //Put everything together, using the content pane's BorderLayout. - Container contentPane = getContentPane(); - contentPane.add(listPane, BorderLayout.CENTER); - contentPane.add(buttonPane, BorderLayout.SOUTH); - pack(); - addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent ke) { - int code = ke.getKeyCode(); - if (code == KeyEvent.VK_ESCAPE) { - ke.consume(); - value = null; - setVisible(false); - } - } - }); - } -}; - -class FindFunction extends JDialog implements ActionListener { - private String value = null; - private JList list; - Hashtable functionNames; - Main db; - JButton setButton; - JButton refreshButton; - JButton cancelButton; - - public String showDialog(Component comp) { - value = null; - setLocationRelativeTo(comp); - setVisible(true); - return value; - } - - private void setValue(String newValue) { - value = newValue; - list.setSelectedValue(value, true); - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - if (cmd.equals("Cancel")) { - setVisible(false); - value = null; - } else if (cmd.equals("Select")) { - if (list.getSelectedIndex() < 0) { - return; - } - try { - value = (String)list.getSelectedValue(); - } catch (ArrayIndexOutOfBoundsException exc) { - return; - } - setVisible(false); - ScriptItem item = (ScriptItem)functionNames.get(value); - if (item != null) { - SourceInfo si = item.getSourceInfo(); - String url = si.getUrl(); - int lineNumber = item.getFirstLine(); - FileWindow w = db.getFileWindow(url); - if (w == null) { - CreateFileWindow.action(db, si, lineNumber).run(); - w = db.getFileWindow(url); - w.setPosition(-1); - } - int start = w.getPosition(lineNumber-1); - int end = w.getPosition(lineNumber)-1; - w.textArea.select(start); - w.textArea.setCaretPosition(start); - w.textArea.moveCaretPosition(end); - try { - w.show(); - db.requestFocus(); - w.requestFocus(); - w.textArea.requestFocus(); - } catch (Exception exc) { - } - } - } - } - - class MouseHandler extends MouseAdapter { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - setButton.doClick(); - } - } - }; - - FindFunction(Main db, Hashtable functionNames, - String title, - String labelText) { - super(db, title, true); - this.functionNames = functionNames; - this.db = db; - - cancelButton = new JButton("Cancel"); - setButton = new JButton("Select"); - cancelButton.addActionListener(this); - setButton.addActionListener(this); - getRootPane().setDefaultButton(setButton); - - list = new JList(new DefaultListModel()); - DefaultListModel model = (DefaultListModel)list.getModel(); - model.clear(); - - Enumeration e = functionNames.keys(); - String[] a = new String[functionNames.size()]; - int i = 0; - while (e.hasMoreElements()) { - a[i++] = e.nextElement().toString(); - } - java.util.Arrays.sort(a); - for (i = 0; i < a.length; i++) { - model.addElement(a[i]); - } - list.setSelectedIndex(0); - - setButton.setEnabled(a.length > 0); - list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); - list.addMouseListener(new MouseHandler()); - JScrollPane listScroller = new JScrollPane(list); - listScroller.setPreferredSize(new Dimension(320, 240)); - listScroller.setMinimumSize(new Dimension(250, 80)); - listScroller.setAlignmentX(LEFT_ALIGNMENT); - - //Create a container so that we can add a title around - //the scroll pane. Can't add a title directly to the - //scroll pane because its background would be white. - //Lay out the label and scroll pane from top to button. - JPanel listPane = new JPanel(); - listPane.setLayout(new BoxLayout(listPane, BoxLayout.Y_AXIS)); - JLabel label = new JLabel(labelText); - label.setLabelFor (list); - listPane.add(label); - listPane.add(Box.createRigidArea(new Dimension(0,5))); - listPane.add(listScroller); - listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); - - //Lay out the buttons from left to right. - JPanel buttonPane = new JPanel(); - buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); - buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); - buttonPane.add(Box.createHorizontalGlue()); - buttonPane.add(cancelButton); - buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); - buttonPane.add(setButton); - - //Put everything together, using the content pane's BorderLayout. - Container contentPane = getContentPane(); - contentPane.add(listPane, BorderLayout.CENTER); - contentPane.add(buttonPane, BorderLayout.SOUTH); - pack(); - addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent ke) { - int code = ke.getKeyCode(); - if (code == KeyEvent.VK_ESCAPE) { - ke.consume(); - value = null; - setVisible(false); - } - } - }); - } -}; - -class FileHeader extends JPanel implements MouseListener { - private int pressLine = -1; - FileWindow fileWindow; - - public void mouseEntered(MouseEvent e) { - } - public void mousePressed(MouseEvent e) { - Font font = fileWindow.textArea.getFont(); - FontMetrics metrics = getFontMetrics(font); - int h = metrics.getHeight(); - pressLine = e.getY() / h; - } - public void mouseClicked(MouseEvent e) { - } - public void mouseExited(MouseEvent e) { - } - public void mouseReleased(MouseEvent e) { - if (e.getComponent() == this && - (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) - { - int x = e.getX(); - int y = e.getY(); - Font font = fileWindow.textArea.getFont(); - FontMetrics metrics = getFontMetrics(font); - int h = metrics.getHeight(); - int line = y/h; - if (line == pressLine) { - fileWindow.toggleBreakPoint(line + 1); - } - else { - pressLine = -1; - } - } - } - - FileHeader(FileWindow fileWindow) { - this.fileWindow = fileWindow; - addMouseListener(this); - update(); - } - - void update() { - FileTextArea textArea = fileWindow.textArea; - Font font = textArea.getFont(); - setFont(font); - FontMetrics metrics = getFontMetrics(font); - int h = metrics.getHeight(); - int lineCount = textArea.getLineCount() + 1; - String dummy = Integer.toString(lineCount); - if (dummy.length() < 2) { - dummy = "99"; - } - Dimension d = new Dimension(); - d.width = metrics.stringWidth(dummy) + 16; - d.height = lineCount * h + 100; - setPreferredSize(d); - setSize(d); - } - - public void paint(Graphics g) { - super.paint(g); - FileTextArea textArea = fileWindow.textArea; - Font font = textArea.getFont(); - g.setFont(font); - FontMetrics metrics = getFontMetrics(font); - Rectangle clip = g.getClipBounds(); - g.setColor(getBackground()); - g.fillRect(clip.x, clip.y, clip.width, clip.height); - int left = getX(); - int ascent = metrics.getMaxAscent(); - int h = metrics.getHeight(); - int lineCount = textArea.getLineCount() + 1; - String dummy = Integer.toString(lineCount); - if (dummy.length() < 2) { - dummy = "99"; - } - int maxWidth = metrics.stringWidth(dummy); - int startLine = clip.y / h; - int endLine = (clip.y + clip.height) / h + 1; - int width = getWidth(); - if (endLine > lineCount) endLine = lineCount; - for (int i = startLine; i < endLine; i++) { - String text; - int pos = -2; - try { - pos = textArea.getLineStartOffset(i); - } catch (BadLocationException ignored) { - } - boolean isBreakPoint = fileWindow.isBreakPoint(i + 1); - text = Integer.toString(i + 1) + " "; - int w = metrics.stringWidth(text); - int y = i * h; - g.setColor(Color.blue); - g.drawString(text, 0, y + ascent); - int x = width - ascent; - if (isBreakPoint) { - g.setColor(new Color(0x80, 0x00, 0x00)); - int dy = y + ascent - 9; - g.fillOval(x, dy, 9, 9); - g.drawOval(x, dy, 8, 8); - g.drawOval(x, dy, 9, 9); - } - if (pos == fileWindow.currentPos) { - Polygon arrow = new Polygon(); - int dx = x; - y += ascent - 10; - int dy = y; - arrow.addPoint(dx, dy + 3); - arrow.addPoint(dx + 5, dy + 3); - for (x = dx + 5; x <= dx + 10; x++, y++) { - arrow.addPoint(x, y); - } - for (x = dx + 9; x >= dx + 5; x--, y++) { - arrow.addPoint(x, y); - } - arrow.addPoint(dx + 5, dy + 7); - arrow.addPoint(dx, dy + 7); - g.setColor(Color.yellow); - g.fillPolygon(arrow); - g.setColor(Color.black); - g.drawPolygon(arrow); - } - } - } -}; - -class FileWindow extends JInternalFrame implements ActionListener { - - Main db; - SourceInfo sourceInfo; - FileTextArea textArea; - FileHeader fileHeader; - JScrollPane p; - int currentPos; - JLabel statusBar; - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - if (cmd.equals("Cut")) { - // textArea.cut(); - } else if (cmd.equals("Copy")) { - textArea.copy(); - } else if (cmd.equals("Paste")) { - // textArea.paste(); - } - } - - void runToCursor(ActionEvent e) { - try { - db.runToCursor(getUrl(), - textArea.getLineOfOffset(textArea.getCaretPosition()) + 1, - e); - } catch (BadLocationException exc) { - } - } - - void load() { - Scriptable scope = db.getScope(); - if (scope == null) { - MessageDialogWrapper.showMessageDialog(db, "Can't load scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE); - } else { - String url = getUrl(); - if (url != null) { - new Thread(new LoadFile(db,scope,url)).start(); - } - } - } - - public int getPosition(int line) { - int result = -1; - try { - result = textArea.getLineStartOffset(line); - } catch (javax.swing.text.BadLocationException exc) { - } - return result; - } - - boolean isBreakPoint(int line) { - return sourceInfo.hasBreakpoint(line); - } - - void toggleBreakPoint(int line) { - if (!isBreakPoint(line)) { - setBreakPoint(line); - } else { - clearBreakPoint(line); - } - } - - void setBreakPoint(int line) { - if (sourceInfo.placeBreakpoint(line)) { - fileHeader.repaint(); - } - } - - void clearBreakPoint(int line) { - if (sourceInfo.removeBreakpoint(line)) { - fileHeader.repaint(); - } - } - - FileWindow(Main db, SourceInfo sourceInfo) { - super(SourceInfo.getShortName(sourceInfo.getUrl()), - true, true, true, true); - this.db = db; - this.sourceInfo = sourceInfo; - updateToolTip(); - currentPos = -1; - textArea = new FileTextArea(this); - textArea.setRows(24); - textArea.setColumns(80); - p = new JScrollPane(); - fileHeader = new FileHeader(this); - p.setViewportView(textArea); - p.setRowHeaderView(fileHeader); - setContentPane(p); - pack(); - updateText(); - textArea.select(0); - } - - private void updateToolTip() { - // in case fileName is very long, try to set tool tip on frame - Component c = getComponent(1); - // this will work at least for Metal L&F - if (c != null && c instanceof JComponent) { - ((JComponent)c).setToolTipText(getUrl()); - } - } - - public String getUrl() { - return sourceInfo.getUrl(); - } - - void updateText() { - String newText = sourceInfo.getSource(); - if (!textArea.getText().equals(newText)) { - textArea.setText(newText); - int pos = 0; - if (currentPos != -1) { - pos = currentPos; - } - textArea.select(pos); - } - fileHeader.update(); - fileHeader.repaint(); - } - - void setPosition(int pos) { - textArea.select(pos); - currentPos = pos; - fileHeader.repaint(); - } - - void select(int start, int end) { - int docEnd = textArea.getDocument().getLength(); - textArea.select(docEnd, docEnd); - textArea.select(start, end); - } - - public void dispose() { - db.removeWindow(this); - super.dispose(); - } - -}; - -class MyTableModel extends AbstractTableModel { - Main db; - Vector expressions; - Vector values; - MyTableModel(Main db) { - this.db = db; - expressions = new Vector(); - values = new Vector(); - expressions.addElement(""); - values.addElement(""); - } - - public int getColumnCount() { - return 2; - } - - public int getRowCount() { - return expressions.size(); - } - - public String getColumnName(int column) { - switch (column) { - case 0: - return "Expression"; - case 1: - return "Value"; - } - return null; - } - - public boolean isCellEditable(int row, int column) { - return true; - } - - public Object getValueAt(int row, int column) { - switch (column) { - case 0: - return expressions.elementAt(row); - case 1: - return values.elementAt(row); - } - return ""; - } - - public void setValueAt(Object value, int row, int column) { - switch (column) { - case 0: - String expr = value.toString(); - expressions.setElementAt(expr, row); - String result = ""; - if (expr.length() > 0) { - result = db.eval(expr); - if (result == null) result = ""; - } - values.setElementAt(result, row); - updateModel(); - if (row + 1 == expressions.size()) { - expressions.addElement(""); - values.addElement(""); - fireTableRowsInserted(row + 1, row + 1); - } - break; - case 1: - // just reset column 2; ignore edits - fireTableDataChanged(); - } - } - - void updateModel() { - for (int i = 0; i < expressions.size(); ++i) { - Object value = expressions.elementAt(i); - String expr = value.toString(); - String result = ""; - if (expr.length() > 0) { - result = db.eval(expr); - if (result == null) result = ""; - } else { - result = ""; - } - result = result.replace('\n', ' '); - values.setElementAt(result, i); - } - fireTableDataChanged(); - } -}; - -class Evaluator extends JTable { - MyTableModel tableModel; - Evaluator(Main db) { - super(new MyTableModel(db)); - tableModel = (MyTableModel)getModel(); - } -} - -class MyTreeTable extends JTreeTable { - - public MyTreeTable(TreeTableModel model) { - super(model); - } - - public JTree resetTree(TreeTableModel treeTableModel) { - tree = new TreeTableCellRenderer(treeTableModel); - - // Install a tableModel representing the visible rows in the tree. - super.setModel(new TreeTableModelAdapter(treeTableModel, tree)); - - // Force the JTable and JTree to share their row selection models. - ListToTreeSelectionModelWrapper selectionWrapper = new - ListToTreeSelectionModelWrapper(); - tree.setSelectionModel(selectionWrapper); - setSelectionModel(selectionWrapper.getListSelectionModel()); - - // Make the tree and table row heights the same. - if (tree.getRowHeight() < 1) { - // Metal looks better like this. - setRowHeight(18); - } - - // Install the tree editor renderer and editor. - setDefaultRenderer(TreeTableModel.class, tree); - setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor()); - setShowGrid(true); - setIntercellSpacing(new Dimension(1,1)); - tree.setRootVisible(false); - tree.setShowsRootHandles(true); - DefaultTreeCellRenderer r = (DefaultTreeCellRenderer)tree.getCellRenderer(); - r.setOpenIcon(null); - r.setClosedIcon(null); - r.setLeafIcon(null); - return tree; - } - - public boolean isCellEditable(EventObject e) { - if (e instanceof MouseEvent) { - MouseEvent me = (MouseEvent)e; - // If the modifiers are not 0 (or the left mouse button), - // tree may try and toggle the selection, and table - // will then try and toggle, resulting in the - // selection remaining the same. To avoid this, we - // only dispatch when the modifiers are 0 (or the left mouse - // button). - if (me.getModifiers() == 0 || - ((me.getModifiers() & (InputEvent.BUTTON1_MASK|1024)) != 0 && - (me.getModifiers() & - (InputEvent.SHIFT_MASK | - InputEvent.CTRL_MASK | - InputEvent.ALT_MASK | - InputEvent.BUTTON2_MASK | - InputEvent.BUTTON3_MASK | - 64 | //SHIFT_DOWN_MASK - 128 | //CTRL_DOWN_MASK - 512 | // ALT_DOWN_MASK - 2048 | //BUTTON2_DOWN_MASK - 4096 //BUTTON3_DOWN_MASK - )) == 0)) { - int row = rowAtPoint(me.getPoint()); - for (int counter = getColumnCount() - 1; counter >= 0; - counter--) { - if (TreeTableModel.class == getColumnClass(counter)) { - MouseEvent newME = new MouseEvent - (MyTreeTable.this.tree, me.getID(), - me.getWhen(), me.getModifiers(), - me.getX() - getCellRect(row, counter, true).x, - me.getY(), me.getClickCount(), - me.isPopupTrigger()); - MyTreeTable.this.tree.dispatchEvent(newME); - break; - } - } - } - if (me.getClickCount() >= 3) { - return true; - } - return false; - } - if (e == null) { - return true; - } - return false; - } -}; - -class ContextWindow extends JPanel implements ActionListener { - JComboBox context; - Vector toolTips; - JTabbedPane tabs; - JTabbedPane tabs2; - MyTreeTable thisTable; - MyTreeTable localsTable; - VariableModel model; - MyTableModel tableModel; - Evaluator evaluator; - EvalTextArea cmdLine; - JSplitPane split; - Main db; - boolean enabled; - ContextWindow(Main db) { - super(); - this.db = db; - enabled = false; - JPanel left = new JPanel(); - JToolBar t1 = new JToolBar(); - t1.setName("Variables"); - t1.setLayout(new GridLayout()); - t1.add(left); - JPanel p1 = new JPanel(); - p1.setLayout(new GridLayout()); - JPanel p2 = new JPanel(); - p2.setLayout(new GridLayout()); - p1.add(t1); - JLabel label = new JLabel("Context:"); - context = new JComboBox(); - context.setLightWeightPopupEnabled(false); - toolTips = new java.util.Vector(); - label.setBorder(context.getBorder()); - context.addActionListener(this); - context.setActionCommand("ContextSwitch"); - GridBagLayout layout = new GridBagLayout(); - left.setLayout(layout); - GridBagConstraints lc = new GridBagConstraints(); - lc.insets.left = 5; - lc.anchor = GridBagConstraints.WEST; - lc.ipadx = 5; - layout.setConstraints(label, lc); - left.add(label); - GridBagConstraints c = new GridBagConstraints(); - c.gridwidth = GridBagConstraints.REMAINDER; - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.WEST; - layout.setConstraints(context, c); - left.add(context); - tabs = new JTabbedPane(SwingConstants.BOTTOM); - tabs.setPreferredSize(new Dimension(500,300)); - thisTable = new MyTreeTable(new AbstractTreeTableModel(new DefaultMutableTreeNode()) { - public Object getChild(Object parent, int index) { - return null; - } - public int getChildCount(Object parent) { - return 0; - } - public int getColumnCount() { - //return 3; - return 2; - } - public String getColumnName(int column) { - switch (column) { - case 0: - return " Name"; - case 1: - //return "Type"; - //case 2: - return " Value"; - } - return null; - } - public Object getValueAt(Object node, int column) { - return null; - } - }); - JScrollPane jsp = new JScrollPane(thisTable); - jsp.getViewport().setViewSize(new Dimension(5,2)); - tabs.add("this", jsp); - localsTable = new MyTreeTable(new AbstractTreeTableModel(new DefaultMutableTreeNode()) { - public Object getChild(Object parent, int index) { - return null; - } - public int getChildCount(Object parent) { - return 0; - } - public int getColumnCount() { - return 2; - } - public String getColumnName(int column) { - switch (column) { - case 0: - return " Name"; - case 1: - return " Value"; - } - return null; - } - public Object getValueAt(Object node, int column) { - return null; - } - }); - localsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - localsTable.setPreferredSize(null); - jsp = new JScrollPane(localsTable); - tabs.add("Locals", jsp); - c.weightx = c.weighty = 1; - c.gridheight = GridBagConstraints.REMAINDER; - c.fill = GridBagConstraints.BOTH; - c.anchor = GridBagConstraints.WEST; - layout.setConstraints(tabs, c); - left.add(tabs); - evaluator = new Evaluator(db); - cmdLine = new EvalTextArea(db); - //cmdLine.requestFocus(); - tableModel = evaluator.tableModel; - jsp = new JScrollPane(evaluator); - JToolBar t2 = new JToolBar(); - t2.setName("Evaluate"); - tabs2 = new JTabbedPane(SwingConstants.BOTTOM); - tabs2.add("Watch", jsp); - tabs2.add("Evaluate", new JScrollPane(cmdLine)); - tabs2.setPreferredSize(new Dimension(500,300)); - t2.setLayout(new GridLayout()); - t2.add(tabs2); - p2.add(t2); - evaluator.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, - p1, p2); - split.setOneTouchExpandable(true); - Main.setResizeWeight(split, 0.5); - setLayout(new BorderLayout()); - add(split, BorderLayout.CENTER); - - final JToolBar finalT1 = t1; - final JToolBar finalT2 = t2; - final JPanel finalP1 = p1; - final JPanel finalP2 = p2; - final JSplitPane finalSplit = split; - final JPanel finalThis = this; - final Main finalDb = db; - - ComponentListener clistener = new ComponentListener() { - boolean t1Docked = true; - boolean t2Docked = true; - void check(Component comp) { - Component thisParent = finalThis.getParent(); - if (thisParent == null) { - return; - } - Component parent = finalT1.getParent(); - boolean leftDocked = true; - boolean rightDocked = true; - boolean adjustVerticalSplit = false; - if (parent != null) { - if (parent != finalP1) { - while (!(parent instanceof JFrame)) { - parent = parent.getParent(); - } - JFrame frame = (JFrame)parent; - finalDb.addTopLevel("Variables", frame); - - // We need the following hacks because: - // - We want an undocked toolbar to be - // resizable. - // - We are using JToolbar as a container of a - // JComboBox. Without this JComboBox's popup - // can get left floating when the toolbar is - // re-docked. - // - // We make the frame resizable and then - // remove JToolbar's window listener - // and insert one of our own that first ensures - // the JComboBox's popup window is closed - // and then calls JToolbar's window listener. - if (!frame.isResizable()) { - frame.setResizable(true); - frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - final EventListener[] l = - frame.getListeners(WindowListener.class); - frame.removeWindowListener((WindowListener)l[0]); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - context.hidePopup(); - ((WindowListener)l[0]).windowClosing(e); - } - }); - //adjustVerticalSplit = true; - } - leftDocked = false; - } else { - leftDocked = true; - } - } - parent = finalT2.getParent(); - if (parent != null) { - if (parent != finalP2) { - while (!(parent instanceof JFrame)) { - parent = parent.getParent(); - } - JFrame frame = (JFrame)parent; - finalDb.addTopLevel("Evaluate", frame); - frame.setResizable(true); - rightDocked = false; - } else { - rightDocked = true; - } - } - if (leftDocked && t2Docked && rightDocked && t2Docked) { - // no change - return; - } - t1Docked = leftDocked; - t2Docked = rightDocked; - JSplitPane split = (JSplitPane)thisParent; - if (leftDocked) { - if (rightDocked) { - finalSplit.setDividerLocation(0.5); - } else { - finalSplit.setDividerLocation(1.0); - } - if (adjustVerticalSplit) { - split.setDividerLocation(0.66); - } - - } else if (rightDocked) { - finalSplit.setDividerLocation(0.0); - split.setDividerLocation(0.66); - } else { - // both undocked - split.setDividerLocation(1.0); - } - } - public void componentHidden(ComponentEvent e) { - check(e.getComponent()); - } - public void componentMoved(ComponentEvent e) { - check(e.getComponent()); - } - public void componentResized(ComponentEvent e) { - check(e.getComponent()); - } - public void componentShown(ComponentEvent e) { - check(e.getComponent()); - } - }; - p1.addContainerListener(new ContainerListener() { - public void componentAdded(ContainerEvent e) { - Component thisParent = finalThis.getParent(); - JSplitPane split = (JSplitPane)thisParent; - if (e.getChild() == finalT1) { - if (finalT2.getParent() == finalP2) { - // both docked - finalSplit.setDividerLocation(0.5); - } else { - // left docked only - finalSplit.setDividerLocation(1.0); - } - split.setDividerLocation(0.66); - } - } - public void componentRemoved(ContainerEvent e) { - Component thisParent = finalThis.getParent(); - JSplitPane split = (JSplitPane)thisParent; - if (e.getChild() == finalT1) { - if (finalT2.getParent() == finalP2) { - // right docked only - finalSplit.setDividerLocation(0.0); - split.setDividerLocation(0.66); - } else { - // both undocked - split.setDividerLocation(1.0); - } - } - } - }); - t1.addComponentListener(clistener); - t2.addComponentListener(clistener); - disable(); - } - - public void actionPerformed(ActionEvent e) { - if (!enabled) return; - if (e.getActionCommand().equals("ContextSwitch")) { - ContextHelper helper = new ContextHelper(); - Context cx = db.getCurrentContext(); - ContextData contextData = ContextData.get(cx); - helper.attach(cx); - int frameIndex = context.getSelectedIndex(); - context.setToolTipText(toolTips.elementAt(frameIndex).toString()); - Scriptable obj; - int frameCount = contextData.getFrameCount(); - if (frameIndex < frameCount) { - FrameHelper frame = contextData.getFrame(frameIndex); - obj = frame.getVariableObject(); - } else { - helper.reset(); - return; - } - NativeCall call = null; - if (obj instanceof NativeCall) { - call = (NativeCall)obj; - obj = call.getThisObj(); - } - JTree tree = thisTable.resetTree(model = new VariableModel(obj)); - - if (call == null) { - tree = localsTable.resetTree(new AbstractTreeTableModel(new DefaultMutableTreeNode()) { - public Object getChild(Object parent, int index) { - return null; - } - public int getChildCount(Object parent) { - return 0; - } - public int getColumnCount() { - return 2; - } - public String getColumnName(int column) { - switch (column) { - case 0: - return " Name"; - case 1: - return " Value"; - } - return null; - } - public Object getValueAt(Object node, int column) { - return null; - } - }); - } else { - tree = localsTable.resetTree(model = new VariableModel(call)); - } - helper.reset(); - db.contextSwitch (frameIndex); - tableModel.updateModel(); - } - } - - public void disable() { - context.setEnabled(false); - thisTable.setEnabled(false); - localsTable.setEnabled(false); - evaluator.setEnabled(false); - cmdLine.setEnabled(false); - } - - public void enable() { - context.setEnabled(true); - thisTable.setEnabled(true); - localsTable.setEnabled(true); - evaluator.setEnabled(true); - cmdLine.setEnabled(true); - } - - public void disableUpdate() { - enabled = false; - } - - public void enableUpdate() { - enabled = true; - } -}; - -class CreateFileWindow implements Runnable { - - Main db; - SourceInfo sourceInfo; - int line; - boolean activate; - - private CreateFileWindow() { } - - static Runnable action(Main db, SourceInfo sourceInfo, int line) { - CreateFileWindow obj = new CreateFileWindow(); - obj.db = db; - obj.sourceInfo = sourceInfo; - obj.line = line; - obj.activate = true; - return obj; - } - - static Runnable action(Main db, - SourceInfo sourceInfo, int line, boolean activate) - { - CreateFileWindow obj = new CreateFileWindow(); - obj.db = db; - obj.sourceInfo = sourceInfo; - obj.line = line; - obj.activate = activate; - return obj; - } - - public void run() { - String url = sourceInfo.getUrl(); - FileWindow w = new FileWindow(db, sourceInfo); - db.fileWindows.put(url, w); - if (line != -1) { - if (db.currentWindow != null) { - db.currentWindow.setPosition(-1); - } - try { - w.setPosition(w.textArea.getLineStartOffset(line-1)); - } catch (BadLocationException exc) { - try { - w.setPosition(w.textArea.getLineStartOffset(0)); - } catch (BadLocationException ee) { - w.setPosition(-1); - } - } - } - db.desk.add(w); - if (line != -1) { - db.currentWindow = w; - } - db.menubar.addFile(url); - w.setVisible(true); - if (activate) { - try { - w.setMaximum(true); - w.setSelected(true); - w.moveToFront(); - } catch (Exception exc) { - } - } - } -} - -class SetFilePosition implements Runnable { - - Main db; - FileWindow w; - int line; - boolean activate; - - SetFilePosition(Main db, FileWindow w, int line) { - this.db = db; - this.w = w; - this.line = line; - activate = true; - } - - SetFilePosition(Main db, FileWindow w, int line, boolean activate) { - this.db = db; - this.w = w; - this.line = line; - this.activate = activate; - } - - public void run() { - JTextArea ta = w.textArea; - try { - if (line == -1) { - w.setPosition(-1); - if (db.currentWindow == w) { - db.currentWindow = null; - } - } else { - int loc = ta.getLineStartOffset(line-1); - if (db.currentWindow != null && db.currentWindow != w) { - db.currentWindow.setPosition(-1); - } - w.setPosition(loc); - db.currentWindow = w; - } - } catch (BadLocationException exc) { - // fix me - } - if (activate) { - if (w.isIcon()) { - db.desk.getDesktopManager().deiconifyFrame(w); - } - db.desk.getDesktopManager().activateFrame(w); - try { - w.show(); - w.toFront(); // required for correct frame layering (JDK 1.4.1) - w.setSelected(true); - } catch (Exception exc) { - } - } - } -} - -class UpdateFileText implements Runnable { - - private FileWindow w; - - private UpdateFileText() {} - - static Runnable action(FileWindow w) { - UpdateFileText obj = new UpdateFileText(); - obj.w = w; - return obj; - } - - public void run() { - w.updateText(); - } -} - -class UpdateContext implements Runnable { - Main db; - ContextData contextData; - UpdateContext(Main db, Context cx) { - this.db = db; - this.contextData = ContextData.get(cx); - } - - public void run() { - db.context.enable(); - JComboBox ctx = db.context.context; - Vector toolTips = db.context.toolTips; - db.context.disableUpdate(); - int frameCount = contextData.getFrameCount(); - ctx.removeAllItems(); - // workaround for JDK 1.4 bug that caches selected value even after - // removeAllItems() is called - ctx.setSelectedItem(null); - toolTips.removeAllElements(); - for (int i = 0; i < frameCount; i++) { - FrameHelper frame = contextData.getFrame(i); - String url = frame.getUrl(); - int lineNumber = frame.getLineNumber(); - String shortName = url; - if (url.length() > 20) { - shortName = "..." + url.substring(url.length() - 17); - } - String location = "\"" + shortName + "\", line " + lineNumber; - ctx.insertItemAt(location, i); - location = "\"" + url + "\", line " + lineNumber; - toolTips.addElement(location); - } - db.context.enableUpdate(); - if (frameCount != 0) { - ctx.setSelectedIndex(0); - } - ctx.setMinimumSize(new Dimension(50, ctx.getMinimumSize().height)); - } -}; - -class Menubar extends JMenuBar implements ActionListener { - - JMenu getDebugMenu() { - return getMenu(2); - } - - Menubar(Main db) { - super(); - this.db = db; - String[] fileItems = {"Open...", "Run...", "", "Exit"}; - String[] fileCmds = {"Open", "Load", "", "Exit"}; - char[] fileShortCuts = {'0', 'N', '\0', 'X'}; - int[] fileAccelerators = {KeyEvent.VK_O, - KeyEvent.VK_N, - 0, - KeyEvent.VK_Q}; - String[] editItems = {"Cut", "Copy", "Paste", "Go to function..."}; - char[] editShortCuts = {'T', 'C', 'P', 'F'}; - String[] debugItems = {"Break", "Go", "Step Into", "Step Over", "Step Out"}; - char[] debugShortCuts = {'B', 'G', 'I', 'O', 'T'}; - String[] plafItems = {"Metal", "Windows", "Motif"}; - char [] plafShortCuts = {'M', 'W', 'F'}; - int[] debugAccelerators = {KeyEvent.VK_PAUSE, - KeyEvent.VK_F5, - KeyEvent.VK_F11, - KeyEvent.VK_F7, - KeyEvent.VK_F8, - 0, 0}; - - JMenu fileMenu = new JMenu("File"); - fileMenu.setMnemonic('F'); - JMenu editMenu = new JMenu("Edit"); - editMenu.setMnemonic('E'); - JMenu plafMenu = new JMenu("Platform"); - plafMenu.setMnemonic('P'); - JMenu debugMenu = new JMenu("Debug"); - debugMenu.setMnemonic('D'); - windowMenu = new JMenu("Window"); - windowMenu.setMnemonic('W'); - for (int i = 0; i < fileItems.length; ++i) { - if (fileItems[i].length() == 0) { - fileMenu.addSeparator(); - } else { - JMenuItem item = new JMenuItem(fileItems[i], - fileShortCuts[i]); - item.setActionCommand(fileCmds[i]); - item.addActionListener(this); - fileMenu.add(item); - if (fileAccelerators[i] != 0) { - KeyStroke k = KeyStroke.getKeyStroke(fileAccelerators[i], Event.CTRL_MASK); - item.setAccelerator(k); - } - } - } - for (int i = 0; i < editItems.length; ++i) { - JMenuItem item = new JMenuItem(editItems[i], - editShortCuts[i]); - item.addActionListener(this); - editMenu.add(item); - } - for (int i = 0; i < plafItems.length; ++i) { - JMenuItem item = new JMenuItem(plafItems[i], - plafShortCuts[i]); - item.addActionListener(this); - plafMenu.add(item); - } - for (int i = 0; i < debugItems.length; ++i) { - JMenuItem item = new JMenuItem(debugItems[i], - debugShortCuts[i]); - item.addActionListener(this); - if (debugAccelerators[i] != 0) { - KeyStroke k = KeyStroke.getKeyStroke(debugAccelerators[i], 0); - item.setAccelerator(k); - } - if (i != 0) { - item.setEnabled(false); - } - debugMenu.add(item); - } - breakOnExceptions = new JCheckBoxMenuItem("Break on Exceptions"); - breakOnExceptions.setMnemonic('X'); - breakOnExceptions.addActionListener(this); - breakOnExceptions.setSelected(false); - debugMenu.add(breakOnExceptions); - - breakOnEnter = new JCheckBoxMenuItem("Break on Function Enter"); - breakOnEnter.setMnemonic('E'); - breakOnEnter.addActionListener(this); - breakOnEnter.setSelected(false); - debugMenu.add(breakOnEnter); - - breakOnReturn = new JCheckBoxMenuItem("Break on Function Return"); - breakOnReturn.setMnemonic('R'); - breakOnReturn.addActionListener(this); - breakOnReturn.setSelected(false); - debugMenu.add(breakOnReturn); - - add(fileMenu); - add(editMenu); - //add(plafMenu); - add(debugMenu); - JMenuItem item; - windowMenu.add(item = new JMenuItem("Cascade", 'A')); - item.addActionListener(this); - windowMenu.add(item = new JMenuItem("Tile", 'T')); - item.addActionListener(this); - windowMenu.addSeparator(); - windowMenu.add(item = new JMenuItem("Console", 'C')); - item.addActionListener(this); - add(windowMenu); - - } - - public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - String plaf_name = null; - if (cmd.equals("Metal")) { - plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel"; - } else if (cmd.equals("Windows")) { - plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - } else if (cmd.equals("Motif")) { - plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; - } else { - Object source = e.getSource(); - if (source == breakOnExceptions) { - db.setBreakOnExceptions(breakOnExceptions.isSelected()); - }else if (source == breakOnEnter) { - db.setBreakOnEnter(breakOnEnter.isSelected()); - }else if (source == breakOnReturn) { - db.setBreakOnReturn(breakOnReturn.isSelected()); - }else { - db.actionPerformed(e); - } - return; - } - try { - UIManager.setLookAndFeel(plaf_name); - SwingUtilities.updateComponentTreeUI(db); - SwingUtilities.updateComponentTreeUI(db.dlg); - } catch (Exception ignored) { - //ignored.printStackTrace(); - } - } - - void addFile(String url) { - int count = windowMenu.getItemCount(); - JMenuItem item; - if (count == 4) { - windowMenu.addSeparator(); - count++; - } - JMenuItem lastItem = windowMenu.getItem(count -1); - boolean hasMoreWin = false; - int maxWin = 5; - if (lastItem != null && - lastItem.getText().equals("More Windows...")) { - hasMoreWin = true; - maxWin++; - } - if (!hasMoreWin && count - 4 == 5) { - windowMenu.add(item = new JMenuItem("More Windows...", 'M')); - item.setActionCommand("More Windows..."); - item.addActionListener(this); - return; - } else if (count - 4 <= maxWin) { - if (hasMoreWin) { - count--; - windowMenu.remove(lastItem); - } - String shortName = SourceInfo.getShortName(url); - - windowMenu.add(item = new JMenuItem((char)('0' + (count-4)) + " " + shortName, '0' + (count - 4))); - if (hasMoreWin) { - windowMenu.add(lastItem); - } - } else { - return; - } - item.setActionCommand(url); - item.addActionListener(this); - } - - Main db; - JMenu windowMenu; - JCheckBoxMenuItem breakOnExceptions; - JCheckBoxMenuItem breakOnEnter; - JCheckBoxMenuItem breakOnReturn; -}; - -class EnterInterrupt implements Runnable { - Main db; - Context cx; - EnterInterrupt(Main db, Context cx) { - this.db = db; - this.cx = cx; - } - public void run() { - JMenu menu = db.getJMenuBar().getMenu(0); - //menu.getItem(0).setEnabled(false); // File->Load - menu = db.getJMenuBar().getMenu(2); - menu.getItem(0).setEnabled(false); // Debug->Break - int count = menu.getItemCount(); - for (int i = 1; i < count; ++i) { - menu.getItem(i).setEnabled(true); - } - boolean b = false; - for (int ci = 0, cc = db.toolBar.getComponentCount(); ci < cc; ci++) { - db.toolBar.getComponent(ci).setEnabled(b); - b = true; - } - db.toolBar.setEnabled(true); - // raise the debugger window - db.toFront(); - } -}; - -class ExitInterrupt implements Runnable { - Main db; - ExitInterrupt(Main db) { - this.db = db; - } - public void run() { - JMenu menu = db.getJMenuBar().getMenu(0); - menu.getItem(0).setEnabled(true); // File->Load - menu = db.getJMenuBar().getMenu(2); - menu.getItem(0).setEnabled(true); // Debug->Break - int count = menu.getItemCount() - 1; - int i = 1; - for (; i < count; ++i) { - menu.getItem(i).setEnabled(false); - } - db.context.disable(); - boolean b = true; - for (int ci = 0, cc = db.toolBar.getComponentCount(); ci < cc; ci++) { - db.toolBar.getComponent(ci).setEnabled(b); - b = false; - } - //db.console.consoleTextArea.requestFocus(); - } -}; - -class OpenFile implements Runnable -{ - String fileName; - Main db; - OpenFile(Main db, String fileName) - { - this.fileName = fileName; - this.db = db; - } - public void run() { - Context cx = Context.enter(); - ContextData contextData = ContextData.get(cx); - contextData.breakNextLine = true; - try { - cx.compileReader(new FileReader(fileName), fileName, 1, null); - } catch (Exception exc) { - String msg = exc.getMessage(); - if (exc instanceof EcmaError) { - EcmaError err = (EcmaError)exc; - msg = err.getSourceName() + ", line " + err.getLineNumber() + ": " + msg; - } - MessageDialogWrapper.showMessageDialog(db, - msg, - "Error Compiling File", - JOptionPane.ERROR_MESSAGE); - } finally { - cx.exit(); - } - } -} - -class LoadFile implements Runnable { - Scriptable scope; - String fileName; - Main db; - LoadFile(Main db, Scriptable scope, String fileName) { - this.scope = scope; - this.fileName = fileName; - this.db = db; - } - public void run() { - Context cx = Context.enter(); - ContextData contextData = ContextData.get(cx); - contextData.breakNextLine = true; - try { - cx.evaluateReader(scope, new FileReader(fileName), - fileName, 1, null); - } catch (Exception exc) { - String msg = exc.getMessage(); - if (exc instanceof EcmaError) { - EcmaError err = (EcmaError)exc; - msg = err.getSourceName() + ", line " + err.getLineNumber() + ": " + msg; - } - MessageDialogWrapper.showMessageDialog(db, - msg, - "Run", - JOptionPane.ERROR_MESSAGE); - } finally { - cx.exit(); - } - } -} - - -class ContextHelper { - Context old; - int enterCount; - Context New; - public void attach(Context cx) { - old = Context.getCurrentContext(); - enterCount = 0; - if (old != null) { - old.exit(); - while (Context.getCurrentContext() != null) { - enterCount++; - old.exit(); - } - } - Context.enter(cx); - New = cx; - } - void reset() { - New.exit(); - if (old != null) { - if (Context.enter(old) != old) { - throw new RuntimeException("debugger error: failed to reset context"); - } - while (enterCount > 0) { - Context.enter(); - enterCount--; - } - } - } -} - -class ContextData { - static ContextData get(Context cx) { - return (ContextData)cx.getDebuggerContextData(); - } - - int getFrameCount() { - return frameStack.size(); - } - - FrameHelper getFrame(int frameNumber) { - return (FrameHelper) frameStack.get(frameStack.size() - frameNumber - 1); - } - - void pushFrame(FrameHelper frame) { - frameStack.push(frame); - } - - void popFrame() { - frameStack.pop(); - } - - ObjArray frameStack = new ObjArray(); - boolean breakNextLine; -} - -class FrameHelper implements DebugFrame { - - FrameHelper(Context cx, Main db, DebuggableScript fnOrScript) - { - this.db = db; - this.contextData = ContextData.get(cx); - this.fnOrScript = fnOrScript; - ScriptItem item = db.getScriptItem(fnOrScript); - if (item != null) { - this.sourceInfo = item.getSourceInfo(); - this.lineNumber = item.getFirstLine(); - } - contextData.pushFrame(this); - } - - public void onEnter(Context cx, Scriptable activation, - Scriptable thisObj, Object[] args) - { - this.activation = activation; - if (db.breakOnEnter) { - db.handleBreakpointHit(cx); - } - } - - public void onLineChange(Context cx, int lineno) { - this.lineNumber = lineno; - if (contextData.breakNextLine - || (sourceInfo != null && sourceInfo.hasBreakpoint(lineno))) - { - db.handleBreakpointHit(cx); - } - } - - public void onExceptionThrown(Context cx, Throwable exception) { - db.handleExceptionThrown(cx, exception, this); - } - - public void onExit(Context cx, boolean byThrow, Object resultOrException) { - if (db.breakOnReturn && !byThrow) { - db.handleBreakpointHit(cx); - } - contextData.popFrame(); - } - - SourceInfo getSourceInfo() { - return sourceInfo; - } - - Scriptable getVariableObject() { - return activation; - } - - String getUrl() { - if (sourceInfo != null) { - return sourceInfo.getUrl(); - } - return db.getNormilizedUrl(fnOrScript); - } - - int getLineNumber() { - return lineNumber; - } - - DebuggableScript getScript() { - return fnOrScript; - } - - private Main db; - private ContextData contextData; - private Scriptable activation; - private DebuggableScript fnOrScript; - private SourceInfo sourceInfo; - private int lineNumber; -} - -class ScriptItem { - - ScriptItem(DebuggableScript fnOrScript, SourceInfo sourceInfo) { - this.fnOrScript = fnOrScript; - this.sourceInfo = sourceInfo; - } - - DebuggableScript getScript() { return fnOrScript; } - - SourceInfo getSourceInfo() { return sourceInfo; } - - int getFirstLine() { - return (firstLine == 0) ? 1 : firstLine; - } - - void setFirstLine(int firstLine) { - if (firstLine <= 0) { throw new IllegalArgumentException(); } - if (this.firstLine != 0) { throw new IllegalStateException(); } - this.firstLine = firstLine; - } - - private DebuggableScript fnOrScript; - private SourceInfo sourceInfo; - private int firstLine; -} - -class SourceInfo { - - static String getShortName(String url) { - int lastSlash = url.lastIndexOf('/'); - if (lastSlash < 0) { - lastSlash = url.lastIndexOf('\\'); - } - String shortName = url; - if (lastSlash >= 0 && lastSlash + 1 < url.length()) { - shortName = url.substring(lastSlash + 1); - } - return shortName; - } - - SourceInfo(String sourceUrl, String source) { - this.sourceUrl = sourceUrl; - this.source = source; - } - - String getUrl() { - return sourceUrl; - } - - String getSource() { - return source; - } - - synchronized void setSource(String source) { - if (!this.source.equals(source)) { - this.source = source; - endLine = 0; - breakableLines = null; - - if (breakpoints != null) { - for (int i = breakpoints.length - 1; i >= 0; --i) { - if (breakpoints[i] == BREAK_FLAG) { - breakpoints[i] = OLD_BREAK_FLAG; - } - } - } - } - } - - synchronized void updateLineInfo(ScriptItem item) { - - int[] lines = item.getScript().getLineNumbers(); - if (lines.length == 0) { - return; - } - - int fnFirstLine = lines[0]; - int fnEndLine = fnFirstLine + 1; - for (int i = 1; i != lines.length; ++i) { - int line = lines[i]; - if (line < fnFirstLine) { - fnFirstLine = line; - }else if (line >= fnEndLine) { - fnEndLine = line + 1; - } - } - item.setFirstLine(fnFirstLine); - - if (endLine < fnEndLine) { - endLine = fnEndLine; - } - if (breakableLines == null) { - int newLength = 20; - if (newLength < endLine) { newLength = endLine; } - breakableLines = new boolean[newLength]; - }else if (breakableLines.length < endLine) { - int newLength = breakableLines.length * 2; - if (newLength < endLine) { newLength = endLine; } - boolean[] tmp = new boolean[newLength]; - System.arraycopy(breakableLines, 0, tmp, 0, breakableLines.length); - breakableLines = tmp; - } - int breakpointsEnd = (breakpoints == null) ? 0 : breakpoints.length; - for (int i = 0; i != lines.length; ++i) { - int line = lines[i]; - breakableLines[line] = true; - if (line < breakpointsEnd) { - if (breakpoints[line] == OLD_BREAK_FLAG) { - breakpoints[line] = BREAK_FLAG; - } - } - } - } - - boolean breakableLine(int line) { - boolean[] breakableLines = this.breakableLines; - if (breakableLines != null && line < breakableLines.length) { - return breakableLines[line]; - } - return false; - } - - boolean hasBreakpoint(int line) { - byte[] breakpoints = this.breakpoints; - if (breakpoints != null && line < breakpoints.length) { - return breakpoints[line] == BREAK_FLAG; - } - return false; - } - - synchronized boolean placeBreakpoint(int line) { - if (breakableLine(line)) { - if (breakpoints == null) { - breakpoints = new byte[endLine]; - }else if (line >= breakpoints.length) { - byte[] tmp = new byte[endLine]; - System.arraycopy(breakpoints, 0, tmp, 0, breakpoints.length); - breakpoints = tmp; - } - breakpoints[line] = BREAK_FLAG; - return true; - } - return false; - } - - synchronized boolean removeBreakpoint(int line) { - boolean wasBreakpoint = false; - if (breakpoints != null && line < breakpoints.length) { - wasBreakpoint = (breakpoints[line] == BREAK_FLAG); - breakpoints[line] = 0; - } - return wasBreakpoint; - } - - synchronized void removeAllBreakpoints() { - breakpoints = null; - } - - private String sourceUrl; - private String source; - - private int endLine; - private boolean[] breakableLines; - - private static final byte BREAK_FLAG = 1; - private static final byte OLD_BREAK_FLAG = 2; - private byte[] breakpoints; - -} - -public class Main extends JFrame implements Debugger, ContextListener { - - /* ContextListener interface */ - - ObjToIntMap contexts = new ObjToIntMap(); - - static Thread mainThread; // thread used to run the shell - - public void contextCreated(Context cx) { - - synchronized (contexts) { - ContextData contextData = new ContextData(); - cx.setDebugger(this, contextData); - cx.setGeneratingDebug(true); - cx.setOptimizationLevel(-1); - // if the user pressed "Break" or if this thread is the shell's - // Main then set the break flag so that when the debugger is run - // with a file argument on the command line it will - // break at the start of the file - if (breakFlag || Thread.currentThread() == mainThread) { - contextData.breakNextLine = true; - } - } - } - - public void contextEntered(Context cx) { - // If the debugger is attached to cx - // keep a reference to it even if it was detached - // from its thread (we cause that to happen below - // in interrupted) - synchronized (contexts) { - if (!contexts.has(cx)) { - if (cx.getDebugger() == this) { - contexts.put(cx, 1); - } - } - } - } - - public void contextExited(Context cx) { - } - - public void contextReleased(Context cx) { - synchronized (contexts) { - contexts.remove(cx); - } - } - - /* end ContextListener interface */ - - boolean breakFlag = false; - - public void doBreak() { - breakFlag = true; - synchronized (contexts) { - ObjToIntMap.Iterator iter = contexts.newIterator(); - for (iter.start(); !iter.done(); iter.next()) { - Context cx = (Context)iter.getKey(); - ContextData.get(cx).breakNextLine = true; - } - } - } - - public void setVisible(boolean b) { - super.setVisible(b); - if (b) { - // this needs to be done after the window is visible - console.consoleTextArea.requestFocus(); - context.split.setDividerLocation(0.5); - try { - console.setMaximum(true); - console.setSelected(true); - console.show(); - console.consoleTextArea.requestFocus(); - } catch (Exception exc) { - } - } - } - - static final int STEP_OVER = 0; - static final int STEP_INTO = 1; - static final int STEP_OUT = 2; - static final int GO = 3; - static final int BREAK = 4; - static final int RUN_TO_CURSOR = 5; - static final int EXIT = 6; - - class ThreadState { - private int stopAtFrameDepth = -1; - }; - - private Hashtable threadState = new Hashtable(); - private Thread runToCursorThread; - private int runToCursorLine; - private String runToCursorFile; - private Hashtable scriptItems = new Hashtable(); - Hashtable sourceNames = new Hashtable(); - - Hashtable functionNames = new Hashtable(); - - ScriptItem getScriptItem(DebuggableScript fnOrScript) { - ScriptItem item = (ScriptItem)scriptItems.get(fnOrScript); - if (item == null) { - String url = getNormilizedUrl(fnOrScript); - SourceInfo si = (SourceInfo)sourceNames.get(url); - if (si == null) { - if (!fnOrScript.isGeneratedScript()) { - // Not eval or Function, try to load it from URL - String source = null; - try { - InputStream is = openSource(url); - try { source = readSource(is); } - finally { is.close(); } - } catch (IOException ex) { - System.err.println - ("Failed to load source from "+url+": "+ ex); - } - if (source != null) { - si = registerSource(url, source); - } - } - } - if (si != null) { - item = registerScript(si, fnOrScript); - } - } - return item; - } - - /* Debugger Interface */ - - public void handleCompilationDone(Context cx, DebuggableScript fnOrScript, - String source) - { - String sourceUrl = getNormilizedUrl(fnOrScript); - SourceInfo si = registerSource(sourceUrl, source); - registerScript(si, fnOrScript); - } - - String getNormilizedUrl(DebuggableScript fnOrScript) { - String url = fnOrScript.getSourceName(); - if (url == null) { url = ""; } - else { - // Not to produce window for eval from different lines, - // strip line numbers, i.e. replace all #[0-9]+\(eval\) by (eval) - // Option: similar teatment for Function? - char evalSeparator = '#'; - StringBuffer sb = null; - int urlLength = url.length(); - int cursor = 0; - for (;;) { - int searchStart = url.indexOf(evalSeparator, cursor); - if (searchStart < 0) { - break; - } - String replace = null; - int i = searchStart + 1; - boolean hasDigits = false; - while (i != urlLength) { - int c = url.charAt(i); - if (!('0' <= c && c <= '9')) { - break; - } - ++i; - } - if (i != searchStart + 1) { - // i points after #[0-9]+ - if ("(eval)".regionMatches(0, url, i, 6)) { - cursor = i + 6; - replace = "(eval)"; - } - } - if (replace == null) { - break; - } - if (sb == null) { - sb = new StringBuffer(); - sb.append(url.substring(0, searchStart)); - } - sb.append(replace); - } - if (sb != null) { - if (cursor != urlLength) { - sb.append(url.substring(cursor)); - } - url = sb.toString(); - } - } - // System.err.println(fnOrScript.getSourceName() + " -> " + url); - return url; - } - - private static InputStream openSource(String sourceUrl) - throws IOException - { - int hash = sourceUrl.indexOf('#'); - if (hash >= 0) { - sourceUrl = sourceUrl.substring(0, hash); - } - if (sourceUrl.indexOf(':') < 0) { - // Can be a file name - try { - if (sourceUrl.startsWith("~/")) { - String home = System.getProperty("user.home"); - if (home != null) { - String pathFromHome = sourceUrl.substring(2); - File f = new File(new File(home), pathFromHome); - if (f.exists()) { - return new FileInputStream(f); - } - } - } - File f = new File(sourceUrl); - if (f.exists()) { - return new FileInputStream(f); - } - } catch (SecurityException ex) { } - // No existing file, assume missed http:// - if (sourceUrl.startsWith("//")) { - sourceUrl = "http:" + sourceUrl; - } else if (sourceUrl.startsWith("/")) { - sourceUrl = "http://127.0.0.1" + sourceUrl; - } else { - sourceUrl = "http://" + sourceUrl; - } - } - - return (new java.net.URL(sourceUrl)).openStream(); - } - - private static String readSource(InputStream is) throws IOException { - byte[] buffer = new byte[4096]; - int offset = 0; - for (;;) { - int n = is.read(buffer, 0, buffer.length - offset); - if (n < 0) { break; } - offset += n; - if (offset == buffer.length) { - byte[] tmp = new byte[buffer.length * 2]; - System.arraycopy(buffer, 0, tmp, 0, offset); - buffer = tmp; - } - } - return new String(buffer, 0, offset); - } - - private SourceInfo registerSource(String sourceUrl, String source) { - SourceInfo si; - synchronized (sourceNames) { - si = (SourceInfo)sourceNames.get(sourceUrl); - if (si == null) { - si = new SourceInfo(sourceUrl, source); - sourceNames.put(sourceUrl, si); - } else { - si.setSource(source); - } - } - return si; - } - - private ScriptItem registerScript(SourceInfo si, - DebuggableScript fnOrScript) - { - ScriptItem item = new ScriptItem(fnOrScript, si); - si.updateLineInfo(item); - scriptItems.put(fnOrScript, item); - - String name = fnOrScript.getFunctionName(); - if (name != null && name.length() > 0 && !name.equals("anonymous")) { - functionNames.put(name, item); - } - - // loadedFile(si); - return item; - } - - void handleBreakpointHit(Context cx) { - breakFlag = false; - interrupted(cx); - } - - private static String exceptionString(Throwable ex) { - if (ex instanceof JavaScriptException) { - JavaScriptException jse = (JavaScriptException)ex; - return ScriptRuntime.toString(jse.getValue()); - } else if (ex instanceof EcmaError) { - return ex.toString(); - } else if (ex instanceof WrappedException) { - Throwable wrapped = ((WrappedException)ex).getWrappedException(); - if (wrapped != null) { - ex = wrapped; - } - } - String msg = ex.toString(); - if (msg == null || msg.length() == 0) { - msg = ex.getClass().toString(); - } - return msg; - } - - void handleExceptionThrown(Context cx, Throwable ex, FrameHelper frame) { - if (breakOnExceptions) { - String url = frame.getUrl(); - int lineNumber = frame.getLineNumber(); - FileWindow w = getFileWindow(url); - String msg = exceptionString(ex); - msg += " (" + url + ", line " + lineNumber + ")"; - if (w != null) { - swingInvoke(new SetFilePosition(this, w, lineNumber)); - } - MessageDialogWrapper.showMessageDialog(this, - msg, - "Exception in Script", - JOptionPane.ERROR_MESSAGE); - //if (w != null) { - //swingInvoke(new SetFilePosition(this, w, -1)); - //} - interrupted(cx); - } - } - - public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) { - return new FrameHelper(cx, this, fnOrScript); - } - - /* end Debugger interface */ - - JDesktopPane desk; - ContextWindow context; - Menubar menubar; - JToolBar toolBar; - JSInternalConsole console; - EvalWindow evalWindow; - JSplitPane split1; - JLabel statusBar; - - void init() { - setJMenuBar(menubar = new Menubar(this)); - toolBar = new JToolBar(); - JButton button; - JButton breakButton, goButton, stepIntoButton, - stepOverButton, stepOutButton; - String [] toolTips = {"Break (Pause)", - "Go (F5)", - "Step Into (F11)", - "Step Over (F7)", - "Step Out (F8)"}; - int count = 0; - button = breakButton = new JButton("Break"); - JButton focusButton = button; - button.setToolTipText("Break"); - button.setActionCommand("Break"); - button.addActionListener(menubar); - button.setEnabled(true); - button.setToolTipText(toolTips[count++]); - - button = goButton = new JButton("Go"); - button.setToolTipText("Go"); - button.setActionCommand("Go"); - button.addActionListener(menubar); - button.setEnabled(false); - button.setToolTipText(toolTips[count++]); - - button = stepIntoButton = new JButton("Step Into"); - button.setToolTipText("Step Into"); - button.setActionCommand("Step Into"); - button.addActionListener(menubar); - button.setEnabled(false); - button.setToolTipText(toolTips[count++]); - - button = stepOverButton = new JButton("Step Over"); - button.setToolTipText("Step Over"); - button.setActionCommand("Step Over"); - button.setEnabled(false); - button.addActionListener(menubar); - button.setToolTipText(toolTips[count++]); - - button = stepOutButton = new JButton("Step Out"); - button.setToolTipText("Step Out"); - button.setActionCommand("Step Out"); - button.setEnabled(false); - button.addActionListener(menubar); - button.setToolTipText(toolTips[count++]); - - Dimension dim = stepOverButton.getPreferredSize(); - breakButton.setPreferredSize(dim); - breakButton.setMinimumSize(dim); - breakButton.setMaximumSize(dim); - breakButton.setSize(dim); - goButton.setPreferredSize(dim); - goButton.setMinimumSize(dim); - goButton.setMaximumSize(dim); - stepIntoButton.setPreferredSize(dim); - stepIntoButton.setMinimumSize(dim); - stepIntoButton.setMaximumSize(dim); - stepOverButton.setPreferredSize(dim); - stepOverButton.setMinimumSize(dim); - stepOverButton.setMaximumSize(dim); - stepOutButton.setPreferredSize(dim); - stepOutButton.setMinimumSize(dim); - stepOutButton.setMaximumSize(dim); - toolBar.add(breakButton); - toolBar.add(goButton); - toolBar.add(stepIntoButton); - toolBar.add(stepOverButton); - toolBar.add(stepOutButton); - - JPanel contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout()); - getContentPane().add(toolBar, BorderLayout.NORTH); - getContentPane().add(contentPane, BorderLayout.CENTER); - desk = new JDesktopPane(); - desk.setPreferredSize(new Dimension(600, 300)); - desk.setMinimumSize(new Dimension(150, 50)); - desk.add(console = new JSInternalConsole("JavaScript Console")); - context = new ContextWindow(this); - context.setPreferredSize(new Dimension(600, 120)); - context.setMinimumSize(new Dimension(50, 50)); - - split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, desk, - context); - split1.setOneTouchExpandable(true); - Main.setResizeWeight(split1, 0.66); - contentPane.add(split1, BorderLayout.CENTER); - statusBar = new JLabel(); - statusBar.setText("Thread: "); - contentPane.add(statusBar, BorderLayout.SOUTH); - dlg = new JFileChooser(); - - javax.swing.filechooser.FileFilter filter = - new javax.swing.filechooser.FileFilter() { - public boolean accept(File f) { - if (f.isDirectory()) { - return true; - } - String n = f.getName(); - int i = n.lastIndexOf('.'); - if (i > 0 && i < n.length() -1) { - String ext = n.substring(i + 1).toLowerCase(); - if (ext.equals("js")) { - return true; - } - } - return false; - } - - public String getDescription() { - return "JavaScript Files (*.js)"; - } - }; - dlg.addChoosableFileFilter(filter); - final Main self = this; - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - self.Exit(); - } - }); - } - - - ScopeProvider scopeProvider; - Runnable exitAction; - - - Scriptable getScope() { - return (scopeProvider != null) ? scopeProvider.getScope() : null; - } - - FileWindow getFileWindow(String url) { - if (url == null || url.equals("")) { - return null; - } - return (FileWindow)fileWindows.get(url); - } - - void loadedFile(SourceInfo si) { - String fileName = si.getUrl(); - FileWindow w = getFileWindow(fileName); - if (w != null) { - swingInvoke(UpdateFileText.action(w)); - w.show(); - } else if (!fileName.equals("")) { - swingInvoke(CreateFileWindow.action(this, si, -1)); - } - } - - static void swingInvoke(Runnable f) { - if (SwingUtilities.isEventDispatchThread()) { - f.run(); - return; - } - try { - SwingUtilities.invokeAndWait(f); - } catch (Exception exc) { - exc.printStackTrace(); - } - } - - static void swingInvokeLater(Runnable f) { - try { - SwingUtilities.invokeLater(f); - } catch (RuntimeException exc) { - exc.printStackTrace(); - } - } - - int frameIndex = -1; - - void contextSwitch (int frameIndex) { - Context cx = getCurrentContext(); - ContextData contextData = ContextData.get(cx); - ContextHelper helper = new ContextHelper(); - helper.attach(cx); - if (cx != null) { - int frameCount = contextData.getFrameCount(); - if (frameIndex < 0 || frameIndex >= frameCount) { - helper.reset(); - return; - } - this.frameIndex = frameIndex; - FrameHelper frame = contextData.getFrame(frameIndex); - String sourceName = frame.getUrl(); - if (sourceName == null || sourceName.equals("")) { - console.show(); - helper.reset(); - return; - } - int lineNumber = frame.getLineNumber(); - this.frameIndex = frameIndex; - FileWindow w = getFileWindow(sourceName); - if (w != null) { - SetFilePosition action = - new SetFilePosition(this, w, lineNumber); - action.run(); - } else { - SourceInfo si = frame.getSourceInfo(); - CreateFileWindow.action(this, si, lineNumber).run(); - } - helper.reset(); - } - } - - boolean isInterrupted = false; - boolean nonDispatcherWaiting = false; - int dispatcherIsWaiting = 0; - Context currentContext = null; - - Context getCurrentContext() { - return currentContext; - } - - void interrupted(Context cx) { - synchronized (swingMonitor) { - if (SwingUtilities.isEventDispatchThread()) { - dispatcherIsWaiting++; - if (nonDispatcherWaiting) { - // Another thread is stopped in the debugger - // process events until it resumes and we - // can enter - java.awt.EventQueue eventQ = - java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue(); - while (nonDispatcherWaiting) { - try { - AWTEvent event = eventQ.getNextEvent(); - if (event instanceof ActiveEvent) { - ((ActiveEvent)event).dispatch(); - } else { - Object source = event.getSource(); - if (source instanceof Component) { - Component comp = (Component)source; - // Suppress Window/InputEvent's that aren't - // directed to the Debugger - // if (!(event instanceof InputEvent || - //event instanceof WindowEvent)|| - //shouldDispatchTo(comp)) { - comp.dispatchEvent(event); - //} - } else if (source instanceof MenuComponent) { - ((MenuComponent)source).dispatchEvent(event); - } - } - if (this.returnValue == EXIT) { - return; - } - swingMonitor.wait(1); - } catch (InterruptedException exc) { - return; - } - } - } - } else { - while (isInterrupted || dispatcherIsWaiting > 0) { - try { - swingMonitor.wait(); - } catch (InterruptedException exc) { - return; - } - } - nonDispatcherWaiting = true; - } - isInterrupted = true; - } - do { - currentContext = cx; - ContextData contextData = ContextData.get(cx); - Thread thread = Thread.currentThread(); - statusBar.setText("Thread: " + thread.toString()); - ThreadState state = (ThreadState)threadState.get(thread); - int stopAtFrameDepth = -1; - if (state != null) { - stopAtFrameDepth = state.stopAtFrameDepth; - } - if (runToCursorFile != null && thread == runToCursorThread) { - int frameCount = contextData.getFrameCount(); - if (frameCount > 0) { - FrameHelper frame = contextData.getFrame(0); - String url = frame.getUrl(); - if (url != null) { - if (url.equals(runToCursorFile)) { - int lineNumber = frame.getLineNumber(); - if (lineNumber == runToCursorLine) { - stopAtFrameDepth = -1; - runToCursorFile = null; - } else { - FileWindow w = getFileWindow(url); - if (w == null || - !w.isBreakPoint(lineNumber)) { - return; - } else { - runToCursorFile = null; - } - } - } - } - } else { - } - } - if (stopAtFrameDepth > 0) { - if (contextData.getFrameCount() > stopAtFrameDepth) { - break; - } - } - if (state != null) { - state.stopAtFrameDepth = -1; - } - threadState.remove(thread); - int frameCount = contextData.getFrameCount(); - this.frameIndex = frameCount -1; - int line = 0; - if (frameCount == 0) { - break; - } - FrameHelper frame = contextData.getFrame(0); - String url = frame.getUrl(); - contextData.breakNextLine = false; - line = frame.getLineNumber(); - int enterCount = 0; - boolean isDispatchThread = - SwingUtilities.isEventDispatchThread(); - - if (!isDispatchThread) { - // detach cx from its thread so the debugger (in the awt - // dispatcher thread) can enter it if necessary - cx.exit(); - while (Context.getCurrentContext() != null) { - Context.exit(); - enterCount++; - } - } - if (url != null && !url.equals("")) { - FileWindow w = (FileWindow)getFileWindow(url); - if (w != null) { - SetFilePosition action = - new SetFilePosition(this, w, line); - swingInvoke(action); - } else { - SourceInfo si = frame.getSourceInfo(); - swingInvoke(CreateFileWindow.action(this, si, line)); - } - } else { - if (console.isVisible()) { - final JSInternalConsole finalConsole = console; - swingInvoke(new Runnable() { - public void run() { - finalConsole.show(); - } - }); - } - } - swingInvoke(new EnterInterrupt(this, cx)); - swingInvoke(new UpdateContext(this, cx)); - int returnValue; - if (!isDispatchThread) { - synchronized (monitor) { - this.returnValue = -1; - try { - while (this.returnValue == -1) { - monitor.wait(); - } - returnValue = this.returnValue; - } catch (InterruptedException exc) { - break; - } - } - } else { - java.awt.EventQueue eventQ = - java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue(); - this.returnValue = -1; - while (this.returnValue == -1) { - try { - AWTEvent event = eventQ.getNextEvent(); - if (event instanceof ActiveEvent) { - ((ActiveEvent)event).dispatch(); - } else { - Object source = event.getSource(); - if (source instanceof Component) { - Component comp = (Component)source; - // Suppress Window/InputEvent's that aren't - // directed to the Debugger - // if (!(event instanceof InputEvent || - //event instanceof WindowEvent)|| - // shouldDispatchTo(comp)) { - //comp.dispatchEvent(event); - //} - comp.dispatchEvent(event); - } else if (source instanceof MenuComponent) { - ((MenuComponent)source).dispatchEvent(event); - } - } - } catch (InterruptedException exc) { - } - } - returnValue = this.returnValue; - } - swingInvoke(new ExitInterrupt(this)); - if (!isDispatchThread) { - // reattach cx to its thread - Context current; - if ((current = Context.enter(cx)) != cx) { - System.out.println("debugger error: cx = " + cx + " current = " + current); - - } - while (enterCount > 0) { - Context.enter(); - enterCount--; - } - } - switch (returnValue) { - case STEP_OVER: - contextData.breakNextLine = true; - stopAtFrameDepth = contextData.getFrameCount(); - if (state == null) { - state = new ThreadState(); - } - state.stopAtFrameDepth = stopAtFrameDepth; - threadState.put(thread, state); - break; - case STEP_INTO: - contextData.breakNextLine = true; - if (state != null) { - state.stopAtFrameDepth = -1; - } - break; - case STEP_OUT: - stopAtFrameDepth = contextData.getFrameCount() -1; - if (stopAtFrameDepth > 0) { - contextData.breakNextLine = true; - if (state == null) { - state = new ThreadState(); - } - state.stopAtFrameDepth = stopAtFrameDepth; - threadState.put(thread, state); - } - break; - case RUN_TO_CURSOR: - contextData.breakNextLine = true; - if (state != null) { - state.stopAtFrameDepth = -1; - } - break; - } - } while (false); - synchronized (swingMonitor) { - isInterrupted = false; - if (SwingUtilities.isEventDispatchThread()) { - dispatcherIsWaiting--; - } else { - nonDispatcherWaiting = false; - } - swingMonitor.notifyAll(); - } - } - - JFileChooser dlg; - - String chooseFile(String title) { - dlg.setDialogTitle(title); - File CWD = null; - String dir = System.getProperty("user.dir"); - if (dir != null) { - CWD = new File(dir); - } - if (CWD != null) { - dlg.setCurrentDirectory(CWD); - } - int returnVal = dlg.showOpenDialog(this); - if (returnVal == JFileChooser.APPROVE_OPTION) { - try { - String result = dlg.getSelectedFile().getCanonicalPath(); - CWD = dlg.getSelectedFile().getParentFile(); - Properties props = System.getProperties(); - props.put("user.dir", CWD.getPath()); - System.setProperties(props); - return result; - }catch (IOException ignored) { - }catch (SecurityException ignored) { - } - } - return null; - } - - JInternalFrame getSelectedFrame() { - JInternalFrame[] frames = desk.getAllFrames(); - for (int i = 0; i < frames.length; i++) { - if (frames[i].isShowing()) { - return frames[i]; - } - } - return frames[frames.length - 1]; - } - - void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - int returnValue = -1; - if (cmd.equals("Cut") || cmd.equals("Copy") || cmd.equals("Paste")) { - JInternalFrame f = getSelectedFrame(); - if (f != null && f instanceof ActionListener) { - ((ActionListener)f).actionPerformed(e); - } - } else if (cmd.equals("Step Over")) { - returnValue = STEP_OVER; - } else if (cmd.equals("Step Into")) { - returnValue = STEP_INTO; - } else if (cmd.equals("Step Out")) { - returnValue = STEP_OUT; - } else if (cmd.equals("Go")) { - returnValue = GO; - } else if (cmd.equals("Break")) { - doBreak(); - } else if (cmd.equals("Run to Cursor")) { - returnValue = RUN_TO_CURSOR; - } else if (cmd.equals("Exit")) { - Exit(); - } else if (cmd.equals("Open")) { - String fileName = chooseFile("Select a file to compile"); - if (fileName != null) { - new Thread(new OpenFile(this, fileName)).start(); - } - } else if (cmd.equals("Load")) { - Scriptable scope = getScope(); - if (scope == null) { - MessageDialogWrapper.showMessageDialog(this, "Can't run scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE); - } else { - String fileName = chooseFile("Select a file to execute"); - if (fileName != null) { - new Thread(new LoadFile(this, scope, - fileName)).start(); - } - } - } else if (cmd.equals("More Windows...")) { - MoreWindows dlg = new MoreWindows(this, fileWindows, - "Window", "Files"); - dlg.showDialog(this); - } else if (cmd.equals("Console")) { - if (console.isIcon()) { - desk.getDesktopManager().deiconifyFrame(console); - } - console.show(); - desk.getDesktopManager().activateFrame(console); - console.consoleTextArea.requestFocus(); - } else if (cmd.equals("Cut")) { - } else if (cmd.equals("Copy")) { - } else if (cmd.equals("Paste")) { - } else if (cmd.equals("Go to function...")) { - FindFunction dlg = new FindFunction(this, functionNames, - "Go to function", - "Function"); - dlg.showDialog(this); - } else if (cmd.equals("Tile")) { - JInternalFrame[] frames = desk.getAllFrames(); - int count = frames.length; - int rows, cols; - rows = cols = (int)Math.sqrt(count); - if (rows*cols < count) { - cols++; - if (rows * cols < count) { - rows++; - } - } - Dimension size = desk.getSize(); - int w = size.width/cols; - int h = size.height/rows; - int x = 0; - int y = 0; - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) { - int index = (i*cols) + j; - if (index >= frames.length) { - break; - } - JInternalFrame f = frames[index]; - try { - f.setIcon(false); - f.setMaximum(false); - } catch (Exception exc) { - } - desk.getDesktopManager().setBoundsForFrame(f, x, y, - w, h); - x += w; - } - y += h; - x = 0; - } - } else if (cmd.equals("Cascade")) { - JInternalFrame[] frames = desk.getAllFrames(); - int count = frames.length; - int x, y, w, h; - x = y = 0; - h = desk.getHeight(); - int d = h / count; - if (d > 30) d = 30; - for (int i = count -1; i >= 0; i--, x += d, y += d) { - JInternalFrame f = frames[i]; - try { - f.setIcon(false); - f.setMaximum(false); - } catch (Exception exc) { - } - Dimension dimen = f.getPreferredSize(); - w = dimen.width; - h = dimen.height; - desk.getDesktopManager().setBoundsForFrame(f, x, y, w, h); - } - } else { - Object obj = getFileWindow(cmd); - if (obj != null) { - FileWindow w = (FileWindow)obj; - try { - if (w.isIcon()) { - w.setIcon(false); - } - w.setVisible(true); - w.moveToFront(); - w.setSelected(true); - } catch (Exception exc) { - } - } - } - if (returnValue != -1) { - if (currentWindow != null) currentWindow.setPosition(-1); - synchronized (monitor) { - this.returnValue = returnValue; - monitor.notify(); - } - } - } - - void runToCursor(String fileName, - int lineNumber, - ActionEvent evt) { - SourceInfo si = (SourceInfo)sourceNames.get(fileName); - if (si == null) { - System.out.println("debugger error: Couldn't find source: " + fileName); - } - if (si.breakableLine(lineNumber)) { - runToCursorFile = fileName; - runToCursorLine = lineNumber; - actionPerformed(evt); - } - } - - JMenu getWindowMenu() { - return menubar.getMenu(3); - } - - void removeWindow(FileWindow w) { - fileWindows.remove(w.getUrl()); - JMenu windowMenu = getWindowMenu(); - int count = windowMenu.getItemCount(); - JMenuItem lastItem = windowMenu.getItem(count -1); - String name = SourceInfo.getShortName(w.getUrl()); - for (int i = 5; i < count; i++) { - JMenuItem item = windowMenu.getItem(i); - if (item == null) continue; // separator - String text = item.getText(); - //1 D:\foo.js - //2 D:\bar.js - int pos = text.indexOf(' '); - if (text.substring(pos + 1).equals(name)) { - windowMenu.remove(item); - // Cascade [0] - // Tile [1] - // ------- [2] - // Console [3] - // ------- [4] - if (count == 6) { - // remove the final separator - windowMenu.remove(4); - } else { - int j = i - 4; - for (;i < count -1; i++) { - JMenuItem thisItem = windowMenu.getItem(i); - if (thisItem != null) { - //1 D:\foo.js - //2 D:\bar.js - text = thisItem.getText(); - if (text.equals("More Windows...")) { - break; - } else { - pos = text.indexOf(' '); - thisItem.setText((char)('0' + j) + " " + - text.substring(pos + 1)); - thisItem.setMnemonic('0' + j); - j++; - } - } - } - if (count - 6 == 0 && lastItem != item) { - if (lastItem.getText().equals("More Windows...")) { - windowMenu.remove(lastItem); - } - } - } - break; - } - } - windowMenu.revalidate(); - } - - boolean stringIsCompilableUnit(String expr) { - Context cx = Context.enter(); - boolean result = cx.stringIsCompilableUnit(expr); - cx.exit(); - return result; - } - - String eval(String expr) { - Context cx = getCurrentContext(); - if (cx == null) return "undefined"; - ContextData contextData = ContextData.get(cx); - ContextHelper helper = new ContextHelper(); - helper.attach(cx); - if (frameIndex >= contextData.getFrameCount()) { - helper.reset(); - return "undefined"; - } - String resultString; - cx.setDebugger(null, null); - cx.setGeneratingDebug(false); - cx.setOptimizationLevel(-1); - boolean savedBreakNextLine = contextData.breakNextLine; - contextData.breakNextLine = false; - try { - Script script; - int savedLevel = cx.getOptimizationLevel(); - try { - cx.setOptimizationLevel(-1); - script = cx.compileString(expr, "", 0, null); - } finally { - cx.setOptimizationLevel(savedLevel); - } - FrameHelper frame = contextData.getFrame(frameIndex); - Scriptable scope = frame.getVariableObject(); - Object result; - if (scope instanceof NativeCall - && script instanceof Function) - { - NativeCall call = (NativeCall)scope; - Function f = (Function)script; - result = f.call(cx, scope, call.getThisObj(), - ScriptRuntime.emptyArgs); - } else { - result = script.exec(cx, scope); - } - if (result == Undefined.instance) { - result = ""; - } - try { - resultString = ScriptRuntime.toString(result); - } catch (RuntimeException exc) { - resultString = result.toString(); - } - } catch (Exception exc) { - resultString = exc.getMessage(); - } - if (resultString == null) { - resultString = "null"; - } - cx.setDebugger(this, contextData); - cx.setGeneratingDebug(true); - cx.setOptimizationLevel(-1); - contextData.breakNextLine = savedBreakNextLine; - helper.reset(); - return resultString; - } - - void Exit() { - // stop handling events - this.returnValue = EXIT; - // call the exit handler if any - if (exitAction != null) { - swingInvokeLater(exitAction); - } - } - - java.util.Hashtable fileWindows = new java.util.Hashtable(); - FileWindow currentWindow; - Object monitor = new Object(); - Object swingMonitor = new Object(); - int returnValue = -1; - boolean breakOnExceptions; - boolean breakOnEnter; - boolean breakOnReturn; - - static void setResizeWeight(JSplitPane pane, double weight) { - // call through reflection for portability - // pre-1.3 JDK JSplitPane doesn't have this method - try { - Method m = JSplitPane.class.getMethod("setResizeWeight", - new Class[]{double.class}); - m.invoke(pane, new Object[]{new Double(weight)}); - } catch (NoSuchMethodException exc) { - } catch (IllegalAccessException exc) { - } catch (java.lang.reflect.InvocationTargetException exc) { - } - } - - java.util.Hashtable toplevels = new java.util.Hashtable(); - - boolean shouldDispatchTo(Component source) { - Component root = SwingUtilities.getRoot(source); - if (root == this) { - return true; - } - Enumeration e = toplevels.keys(); - while (e.hasMoreElements()) { - Object key = e.nextElement(); - JFrame frame = (JFrame)toplevels.get(key); - if (root == frame) { - return true; - } - } - return false; - } - - void addTopLevel(String key, JFrame frame) { - if (frame != this) { - toplevels.put(key, frame); - } - } - - // - // public interface - // - - public Main(String title) { - super(title); - init(); - } - - /** - * Toggle Break-on-Exception behavior - */ - public void setBreakOnExceptions(boolean value) { - this.breakOnExceptions = value; - } - - /** - * Toggle Break-on-Enter behavior - */ - public void setBreakOnEnter(boolean value) { - this.breakOnEnter = value; - } - - /** - * Toggle Break-on-Return behavior - */ - public void setBreakOnReturn(boolean value) { - this.breakOnReturn = value; - } - - /** - * - * Remove all breakpoints - */ - public void clearAllBreakpoints() { - Enumeration e = sourceNames.elements(); - while (e.hasMoreElements()) { - SourceInfo si = (SourceInfo)e.nextElement(); - si.removeAllBreakpoints(); - } - } - - /** - * Resume Execution - */ - public void go() - { - returnValue = GO; - synchronized (monitor) { - this.returnValue = returnValue; - monitor.notifyAll(); - } - } - - /** - * Assign an object that can provide a Scriptable that will - * be used as the scope for loading scripts from files - * when the user selects "Open..." or "Run..." - */ - public void setScopeProvider(ScopeProvider p) { - scopeProvider = p; - } - - /** - * Assign a Runnable object that will be invoked when the user - * selects "Exit..." or closes the Debugger main window - */ - public void setExitAction(Runnable r) { - exitAction = r; - } - - /** - * Get an input stream to the Debugger's internal Console window - */ - - public InputStream getIn() { - return console.getIn(); - } - - /** - * Get an output stream to the Debugger's internal Console window - */ - - public PrintStream getOut() { - return console.getOut(); - } - - /** - * Get an error stream to the Debugger's internal Console window - */ - - public PrintStream getErr() { - return console.getErr(); - } - - public static void main(String[] args) { - try { - mainThread = Thread.currentThread(); - final Main sdb = new Main("Rhino JavaScript Debugger"); - swingInvoke(new Runnable() { - public void run() { - sdb.pack(); - sdb.setSize(600, 460); - sdb.setVisible(true); - } - }); - sdb.setExitAction(new Runnable() { - public void run() { - System.exit(0); - } - }); - System.setIn(sdb.getIn()); - System.setOut(sdb.getOut()); - System.setErr(sdb.getErr()); - Context.addContextListener(sdb); - sdb.setScopeProvider(new ScopeProvider() { - public Scriptable getScope() { - return org.mozilla.javascript.tools.shell.Main.getScope(); - } - }); - org.mozilla.javascript.tools.shell.Main.exec(args); - } catch (Exception exc) { - exc.printStackTrace(); - } - } - -} - diff --git a/src/helma/scripting/rhino/debug/ScopeProvider.java b/src/helma/scripting/rhino/debug/ScopeProvider.java deleted file mode 100644 index 1266c111..00000000 --- a/src/helma/scripting/rhino/debug/ScopeProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino JavaScript Debugger code, released - * November 21, 2000. - * - * The Initial Developer of the Original Code is See Beyond Corporation. - - * Portions created by See Beyond are - * Copyright (C) 2000 See Beyond Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Christopher Oliver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package helma.scripting.rhino.debug; - -import org.mozilla.javascript.Scriptable; - -public interface ScopeProvider { - public Scriptable getScope(); -}; diff --git a/src/helma/scripting/rhino/debug/TreeTableModel.java b/src/helma/scripting/rhino/debug/TreeTableModel.java deleted file mode 100644 index 445afc6d..00000000 --- a/src/helma/scripting/rhino/debug/TreeTableModel.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * TreeTableModel.java - * - * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved. - * - * This software is the confidential and proprietary information of Sun - * Microsystems, Inc. ("Confidential Information"). You shall not - * disclose such Confidential Information and shall use it only in - * accordance with the terms of the license agreement you entered into - * with Sun. - * - * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE - * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES - * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING - * THIS SOFTWARE OR ITS DERIVATIVES. - * - */ - - - package helma.scripting.rhino.debug; - import javax.swing.tree.TreeModel; - - -/** - * TreeTableModel is the model used by a JTreeTable. It extends TreeModel - * to add methods for getting inforamtion about the set of columns each - * node in the TreeTableModel may have. Each column, like a column in - * a TableModel, has a name and a type associated with it. Each node in - * the TreeTableModel can return a value for each of the columns and - * set that value if isCellEditable() returns true. - * - * @author Philip Milne - * @author Scott Violet - */ -public interface TreeTableModel extends TreeModel -{ - /** - * Returns the number ofs availible column. - */ - public int getColumnCount(); - - /** - * Returns the name for column number column. - */ - public String getColumnName(int column); - - /** - * Returns the type for column number column. - */ - public Class getColumnClass(int column); - - /** - * Returns the value to be displayed for node node, - * at column number column. - */ - public Object getValueAt(Object node, int column); - - /** - * Indicates whether the the value for node node, - * at column number column is editable. - */ - public boolean isCellEditable(Object node, int column); - - /** - * Sets the value for node node, - * at column number column. - */ - public void setValueAt(Object aValue, Object node, int column); -} diff --git a/src/helma/scripting/rhino/debug/TreeTableModelAdapter.java b/src/helma/scripting/rhino/debug/TreeTableModelAdapter.java deleted file mode 100644 index c82250ae..00000000 --- a/src/helma/scripting/rhino/debug/TreeTableModelAdapter.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * @(#)TreeTableModelAdapter.java 1.2 98/10/27 - * - * Copyright 1997, 1998 by Sun Microsystems, Inc., - * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. - * All rights reserved. - * - * This software is the confidential and proprietary information - * of Sun Microsystems, Inc. ("Confidential Information"). You - * shall not disclose such Confidential Information and shall use - * it only in accordance with the terms of the license agreement - * you entered into with Sun. - */ - - - package helma.scripting.rhino.debug; - import javax.swing.JTree; - -import javax.swing.SwingUtilities; -import javax.swing.table.AbstractTableModel; -import javax.swing.tree.TreePath; -import javax.swing.event.TreeExpansionEvent; -import javax.swing.event.TreeExpansionListener; -import javax.swing.event.TreeModelEvent; -import javax.swing.event.TreeModelListener; - -/** - * This is a wrapper class takes a TreeTableModel and implements - * the table model interface. The implementation is trivial, with - * all of the event dispatching support provided by the superclass: - * the AbstractTableModel. - * - * @version 1.2 10/27/98 - * - * @author Philip Milne - * @author Scott Violet - */ -public class TreeTableModelAdapter extends AbstractTableModel -{ - JTree tree; - TreeTableModel treeTableModel; - - public TreeTableModelAdapter(TreeTableModel treeTableModel, JTree tree) { - this.tree = tree; - this.treeTableModel = treeTableModel; - - tree.addTreeExpansionListener(new TreeExpansionListener() { - // Don't use fireTableRowsInserted() here; the selection model - // would get updated twice. - public void treeExpanded(TreeExpansionEvent event) { - fireTableDataChanged(); - } - public void treeCollapsed(TreeExpansionEvent event) { - fireTableDataChanged(); - } - }); - - // Install a TreeModelListener that can update the table when - // tree changes. We use delayedFireTableDataChanged as we can - // not be guaranteed the tree will have finished processing - // the event before us. - treeTableModel.addTreeModelListener(new TreeModelListener() { - public void treeNodesChanged(TreeModelEvent e) { - delayedFireTableDataChanged(); - } - - public void treeNodesInserted(TreeModelEvent e) { - delayedFireTableDataChanged(); - } - - public void treeNodesRemoved(TreeModelEvent e) { - delayedFireTableDataChanged(); - } - - public void treeStructureChanged(TreeModelEvent e) { - delayedFireTableDataChanged(); - } - }); - } - - // Wrappers, implementing TableModel interface. - - public int getColumnCount() { - return treeTableModel.getColumnCount(); - } - - public String getColumnName(int column) { - return treeTableModel.getColumnName(column); - } - - public Class getColumnClass(int column) { - return treeTableModel.getColumnClass(column); - } - - public int getRowCount() { - return tree.getRowCount(); - } - - protected Object nodeForRow(int row) { - TreePath treePath = tree.getPathForRow(row); - return treePath.getLastPathComponent(); - } - - public Object getValueAt(int row, int column) { - return treeTableModel.getValueAt(nodeForRow(row), column); - } - - public boolean isCellEditable(int row, int column) { - return treeTableModel.isCellEditable(nodeForRow(row), column); - } - - public void setValueAt(Object value, int row, int column) { - treeTableModel.setValueAt(value, nodeForRow(row), column); - } - - /** - * Invokes fireTableDataChanged after all the pending events have been - * processed. SwingUtilities.invokeLater is used to handle this. - */ - protected void delayedFireTableDataChanged() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - fireTableDataChanged(); - } - }); - } -} - diff --git a/src/helma/scripting/rhino/debug/VariableModel.java b/src/helma/scripting/rhino/debug/VariableModel.java deleted file mode 100644 index 052324f4..00000000 --- a/src/helma/scripting/rhino/debug/VariableModel.java +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino JavaScript Debugger code, released - * November 21, 2000. - * - * The Initial Developer of the Original Code is SeeBeyond Corporation. - - * Portions created by SeeBeyond are - * Copyright (C) 2000 SeeBeyond Technology Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Christopher Oliver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package helma.scripting.rhino.debug; -import org.mozilla.javascript.*; -import javax.swing.event.TableModelEvent; -import java.util.Hashtable; -import java.util.Enumeration; - -public class VariableModel extends AbstractTreeTableModel - implements TreeTableModel { - - // Names of the columns. - - static protected String[] cNames = { " Name", " Value"}; - - // Types of the columns. - - static protected Class[] cTypes = {TreeTableModel.class, String.class}; - - - public VariableModel(Scriptable scope) { - super(scope == null ? null : new VariableNode(scope, "this")); - } - - // - // Some convenience methods. - // - - protected Object getObject(Object node) { - VariableNode varNode = ((VariableNode)node); - if (varNode == null) return null; - return varNode.getObject(); - } - - protected Object[] getChildren(Object node) { - VariableNode varNode = ((VariableNode)node); - return varNode.getChildren(); - } - - // - // The TreeModel interface - // - - public int getChildCount(Object node) { - Object[] children = getChildren(node); - return (children == null) ? 0 : children.length; - } - - public Object getChild(Object node, int i) { - return getChildren(node)[i]; - } - - // The superclass's implementation would work, but this is more efficient. - public boolean isLeaf(Object node) { - if (node == null) return true; - VariableNode varNode = (VariableNode)node; - Object[] children = varNode.getChildren(); - if (children != null && children.length > 0) { - return false; - } - return true; - } - - public boolean isCellEditable(Object node, int column) { - return column == 0; - } - - // - // The TreeTableNode interface. - // - - public int getColumnCount() { - return cNames.length; - } - - public String getColumnName(int column) { - return cNames[column]; - } - - public Class getColumnClass(int column) { - return cTypes[column]; - } - - public Object getValueAt(Object node, int column) { - Context cx = Context.enter(); - try { - Object value = getObject(node); - switch (column) { - case 0: // Name - VariableNode varNode = (VariableNode)node; - String name = ""; - if (varNode.name != null) { - return name + varNode.name; - } - return name + "[" + varNode.index + "]"; - case 1: // Value - if (value == Undefined.instance || - value == ScriptableObject.NOT_FOUND) { - return "undefined"; - } - if (value == null) { - return "null"; - } - if (value instanceof NativeCall) { - return "[object Call]"; - } - String result; - try { - result = Context.toString(value); - } catch (RuntimeException exc) { - result = exc.getMessage(); - } - StringBuffer buf = new StringBuffer(); - int len = result.length(); - for (int i = 0; i < len; i++) { - char ch = result.charAt(i); - if (Character.isISOControl(ch)) { - ch = ' '; - } - buf.append(ch); - } - return buf.toString(); - } - } catch (Exception exc) { - //exc.printStackTrace(); - } finally { - cx.exit(); - } - return null; - } - - public void setScope(Scriptable scope) { - VariableNode rootVar = (VariableNode)root; - rootVar.scope = scope; - fireTreeNodesChanged(this, - new Object[]{root}, - null, new Object[]{root}); - } - -} - - -class VariableNode { - Scriptable scope; - String name; - int index; - - public VariableNode(Scriptable scope, String name) { - this.scope = scope; - this.name = name; - } - - public VariableNode(Scriptable scope, int index) { - this.scope = scope; - this.name = null; - this.index = index; - } - - /** - * Returns the the string to be used to display this leaf in the JTree. - */ - public String toString() { - return (name != null ? name : "[" + index + "]"); - } - - public Object getObject() { - try { - if (scope == null) return null; - if (name != null) { - if (name.equals("this")) { - return scope; - } - Object result = ScriptableObject.NOT_FOUND; - if (name.equals("__proto__")) { - result = scope.getPrototype(); - } else if (name.equals("__parent__")) { - result = scope.getParentScope(); - } else { - try { - result = ScriptableObject.getProperty(scope, name); - } catch (RuntimeException e) { - result = e.getMessage(); - } - } - if (result == ScriptableObject.NOT_FOUND) { - result = Undefined.instance; - } - return result; - } - Object result = ScriptableObject.getProperty(scope, index); - if (result == ScriptableObject.NOT_FOUND) { - result = Undefined.instance; - } - return result; - } catch (Exception exc) { - return "undefined"; - } - } - - Object[] children; - - static final Object[] empty = new Object[0]; - - protected Object[] getChildren() { - if (children != null) return children; - Context cx = Context.enter(); - try { - Object value = getObject(); - if (value == null) return children = empty; - if (value == ScriptableObject.NOT_FOUND || - value == Undefined.instance) { - return children = empty; - } - if (value instanceof Scriptable) { - Scriptable scrip = (Scriptable)value; - Scriptable proto = scrip.getPrototype(); - Scriptable parent = scrip.getParentScope(); - if (scrip.has(0, scrip)) { - int len = 0; - try { - Scriptable start = scrip; - Scriptable obj = start; - Object result = Undefined.instance; - do { - if (obj.has("length", start)) { - result = obj.get("length", start); - if (result != Scriptable.NOT_FOUND) - break; - } - obj = obj.getPrototype(); - } while (obj != null); - if (result instanceof Number) { - len = ((Number)result).intValue(); - } - } catch (Exception exc) { - } - if (parent != null) { - len++; - } - if (proto != null) { - len++; - } - children = new VariableNode[len]; - int i = 0; - int j = 0; - if (parent != null) { - children[i++] = new VariableNode(scrip, "__parent__"); - j++; - } - if (proto != null) { - children[i++] = new VariableNode(scrip, "__proto__"); - j++; - } - for (; i < len; i++) { - children[i] = new VariableNode(scrip, i-j); - } - } else { - int len = 0; - Hashtable t = new Hashtable(); - Object[] ids; - if (scrip instanceof ScriptableObject) { - ids = ((ScriptableObject)scrip).getAllIds(); - } else { - ids = scrip.getIds(); - } - if (ids == null) ids = empty; - if (proto != null) t.put("__proto__", "__proto__"); - if (parent != null) t.put("__parent__", "__parent__"); - if (ids.length > 0) { - for (int j = 0; j < ids.length; j++) { - t.put(ids[j], ids[j]); - } - } - ids = new Object[t.size()]; - Enumeration e = t.keys(); - int j = 0; - while (e.hasMoreElements()) { - ids[j++] = e.nextElement().toString(); - } - if (ids != null && ids.length > 0) { - java.util.Arrays.sort(ids, new java.util.Comparator() { - public int compare(Object l, Object r) { - return l.toString().compareToIgnoreCase(r.toString()); - - } - }); - len = ids.length; - } - children = new VariableNode[len]; - for (int i = 0; i < len; i++) { - Object id = ids[i]; - children[i] = new - VariableNode(scrip, id.toString()); - } - } - } - } catch (Exception exc) { - exc.printStackTrace(); - } finally { - cx.exit(); - } - return children; - } -} -