* Update Rhino to 1.6R3.
* Remove old Rhino 1.5 classes, make Helma debugger subclass Rhino 1.6 classes (not fully functional yet, needs patches to Rhino debugger). * Make helma.doc.DocFunction compile with Rhino 1.6 by introducing intermediary DockenStream class that proxies TokenStream using java reflection.
This commit is contained in:
parent
fc37ba8cb3
commit
e5033685db
14 changed files with 254 additions and 4963 deletions
BIN
lib/rhino.jar
BIN
lib/rhino.jar
Binary file not shown.
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
112
src/helma/doc/DockenStream.java
Normal file
112
src/helma/doc/DockenStream.java
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2006 Hannes Wallnoefer <hannes@helma.at>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
*/
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.<p>
|
||||
* 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.
|
||||
* <p>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 <code>updatingListSelectionModel</code>
|
||||
* 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 <code>updatingListSelectionModel</code> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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();
|
||||
};
|
|
@ -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 <code>column</code>.
|
||||
*/
|
||||
public String getColumnName(int column);
|
||||
|
||||
/**
|
||||
* Returns the type for column number <code>column</code>.
|
||||
*/
|
||||
public Class getColumnClass(int column);
|
||||
|
||||
/**
|
||||
* Returns the value to be displayed for node <code>node</code>,
|
||||
* at column number <code>column</code>.
|
||||
*/
|
||||
public Object getValueAt(Object node, int column);
|
||||
|
||||
/**
|
||||
* Indicates whether the the value for node <code>node</code>,
|
||||
* at column number <code>column</code> is editable.
|
||||
*/
|
||||
public boolean isCellEditable(Object node, int column);
|
||||
|
||||
/**
|
||||
* Sets the value for node <code>node</code>,
|
||||
* at column number <code>column</code>.
|
||||
*/
|
||||
public void setValueAt(Object aValue, Object node, int column);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue