Changes from code review, BeanShell document scripts can now be edited,

Rhino document scripts cannot.
This commit is contained in:
Tomas O'Connor
2003-05-26 13:47:45 +00:00
parent 9b4ee751fe
commit 73ee44c0cd
5 changed files with 180 additions and 247 deletions

View File

@@ -1,59 +1,71 @@
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import drafts.com.sun.star.script.framework.runtime.XScriptContext;
public class DebugRunner {
private static final String FILE_URL_PREFIX =
System.getProperty("os.name").startsWith("Windows") == true ?
"file:///" : "file://";
public void go(final XScriptContext xsctxt, String language, String uri,
String filename) {
OOScriptDebugger debugger;
InputStream is = null;
String path = "";
System.out.println("uri: " + uri + ", language: " + language);
if (language.equals("Rhino"))
debugger = new OORhinoDebugger();
else if (language.equals("BeanShell"))
debugger = new OOBeanShellDebugger();
else
return;
if (uri.startsWith(FILE_URL_PREFIX)) {
uri = URLDecoder.decode(uri);
String s = uri.substring(FILE_URL_PREFIX.length());
File f = new File(s);
if (f.exists()) {
if (f.isDirectory()) {
if (!filename.equals("")) {
path = new File(f, filename).getAbsolutePath();
}
}
else {
path = f.getAbsolutePath();
}
}
}
else if (uri.startsWith("http://")) {
try {
if (!filename.equals(""))
uri = uri + "/" + filename;
URL url = new URL(uri);
is = url.openStream();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
System.out.println("path: " + path);
debugger.go(xsctxt, path);
}
}
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import com.sun.star.uno.XComponentContext;
import com.sun.star.scripting.runtime.java.PathUtils;
import drafts.com.sun.star.script.framework.runtime.XScriptContext;
public class DebugRunner {
private static final String FILE_URL_PREFIX =
System.getProperty("os.name").startsWith("Windows") == true ?
"file:///" : "file://";
public void go(final XScriptContext xsctxt, String language, String uri,
String filename) {
OOScriptDebugger debugger;
String path = "";
if (language.equals("Rhino")) {
debugger = new OORhinoDebugger();
}
else if (language.equals("BeanShell")) {
debugger = new OOBeanShellDebugger();
}
else {
return;
}
if (uri.startsWith(FILE_URL_PREFIX)) {
uri = URLDecoder.decode(uri);
String s = uri.substring(FILE_URL_PREFIX.length());
File f = new File(s);
if (f.exists()) {
if (f.isDirectory()) {
if (!filename.equals("")) {
path = new File(f, filename).getAbsolutePath();
}
}
else {
path = f.getAbsolutePath();
}
}
debugger.go(xsctxt, path);
}
else {
if (!uri.endsWith("/")) {
uri += "/";
}
String script = uri + filename;
InputStream is;
try {
is = PathUtils.getScriptFileStream(
script, xsctxt.getComponentContext());
if (is != null) {
debugger.go(xsctxt, is);
}
}
catch (IOException ioe) {
System.out.println("Error loading script: " + script);
}
}
}
}

View File

@@ -1,13 +1,34 @@
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.text.Document;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import drafts.com.sun.star.script.framework.runtime.XScriptContext;
import bsh.*;
import bsh.Interpreter;
public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, DocumentListener {
@@ -16,22 +37,18 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
private GlyphGutter gg;
private XScriptContext context;
private int currentPosition = -1;
private ArrayList breakpoints;
private int linecount;
private BufferedReader bufReader;
private Interpreter sessionInterpreter;
private Thread execThread = null;
private String filename = null;
/* Entry point for script execution */
public void go(XScriptContext context, String filename) {
this.context = context;
this.breakpoints = new ArrayList();
initUI();
if (filename != null && filename != "") {
try {
loadFile(filename);
FileInputStream fis = new FileInputStream(filename);
this.filename = filename;
go(context, fis);
}
catch (IOException ioe) {
JOptionPane.showMessageDialog(frame,
@@ -41,9 +58,9 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
}
}
/* Entry point for script execution */
public void go(XScriptContext context, InputStream in) {
this.context = context;
this.breakpoints = new ArrayList();
initUI();
if (in != null) {
@@ -58,12 +75,10 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
}
}
public void loadFile(String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
loadFile(fis);
}
public void loadFile(InputStream in) throws IOException {
/* Remove ourselves as a DocumentListener while loading the file
so we don't get a storm of DocumentEvents during loading */
ta.getDocument().removeDocumentListener(this);
byte[] contents = new byte[1024];
@@ -74,6 +89,13 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
pos += len;
}
try {
in.close();
}
catch (IOException ignore) {
}
/* Update the GlyphGutter and add back the DocumentListener */
gg.update();
ta.getDocument().addDocumentListener(this);
}
@@ -93,7 +115,7 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
sp.setRowHeaderView(gg);
ta.getDocument().addDocumentListener(this);
String[] labels = {"Run", /* "Stop", */ "Clear", "Save", "Close"};
String[] labels = {"Run", "Clear", "Save", "Close"};
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
@@ -109,6 +131,7 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
frame.show();
}
/* Implementation of DocumentListener interface */
public void insertUpdate(DocumentEvent e) {
doChanged(e);
}
@@ -121,6 +144,8 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
doChanged(e);
}
/* If the number of lines in the JTextArea has changed then update the
GlyphGutter */
public void doChanged(DocumentEvent e) {
if (linecount != ta.getLineCount()) {
gg.update();
@@ -134,6 +159,7 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
Interpreter interpreter = new Interpreter();
interpreter.getNameSpace().clear();
// reset position and repaint gutter so no red arrow appears
currentPosition = -1;
gg.repaint();
@@ -144,12 +170,13 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
catch (bsh.EvalError err) {
currentPosition = err.getErrorLineNumber() - 1;
try {
// scroll to line of the error
int line = ta.getLineStartOffset(currentPosition);
Rectangle rect = ta.modelToView(line);
ta.scrollRectToVisible(rect);
}
catch (Exception e) {
System.err.println("error: " + e.getMessage());
// couldn't scroll to line, do nothing
}
gg.repaint();
@@ -168,108 +195,13 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
execThread.start();
}
private void stopExecution() {
if (execThread != null) {
execThread.interrupt();
execThread = null;
}
ta.setEditable(true);
if (bufReader != null) {
try {
bufReader.close();
}
catch (IOException ioe) {}
}
bufReader = null;
currentPosition = -1;
gg.repaint();
}
private void startSession() {
/* Reader reader = new StringReader(ta.getText());
bsh.Parser parser = new bsh.Parser(reader);
boolean eof = false;
try {
Interpreter interpreter = new Interpreter();
interpreter.getNameSpace().clear();
interpreter.set("context", context);
CallStack callstack = new CallStack();
callstack.push(interpreter.getNameSpace());
bsh.SimpleNode node = null;
while(!eof) {
eof = parser.Line();
node = parser.popNode();
System.out.println("Executing: " + node.getText());
node.eval(callstack, interpreter);
}
}
catch(Exception e) {
e.printStackTrace();
} */
/* try {
sessionInterpreter = new Interpreter();
sessionInterpreter.getNameSpace().clear();
sessionInterpreter.set("context", context);
}
catch (bsh.EvalError err) {
JOptionPane.showMessageDialog(frame,
"Error at line " + String.valueOf(err.getErrorLineNumber()) +
"\n\n: " + err.getErrorText(),
"Error", JOptionPane.ERROR_MESSAGE);
stopExecution();
}
ta.setEditable(false);
Reader reader = new StringReader(ta.getText());
bufReader = new BufferedReader(reader);
currentPosition = 0;
gg.repaint(); */
}
private void doStep() {
String line = null;
try {
line = bufReader.readLine();
}
catch (IOException ioe) {
JOptionPane.showMessageDialog(frame,
"Error reading line " + currentPosition +
"\n\n: " + ioe.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
stopExecution();
}
if (line != null) {
try {
sessionInterpreter.eval(line);
currentPosition++;
gg.repaint();
}
catch (bsh.EvalError err) {
gg.repaint();
JOptionPane.showMessageDialog(frame,
"Error at line " + String.valueOf(err.getErrorLineNumber()) +
"\n\n: " + err.getErrorText(),
"Error", JOptionPane.ERROR_MESSAGE);
}
}
else
stopExecution();
}
private void promptForSaveName() {
JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
if (f.isDirectory() || f.getName().endsWith(".bsh"))
if (f.isDirectory() || f.getName().endsWith(".bsh")) {
return true;
}
return false;
}
@@ -282,20 +214,23 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
if (ret == JFileChooser.APPROVE_OPTION) {
filename = chooser.getSelectedFile().getAbsolutePath();
if (!filename.endsWith(".bsh"))
if (!filename.endsWith(".bsh")) {
filename += ".bsh";
}
}
}
private void saveTextArea() {
if (filename == null)
if (filename == null) {
promptForSaveName();
}
FileOutputStream fos = null;
if (filename != null) {
try {
File f = new File(filename);
FileOutputStream fos = new FileOutputStream(f);
fos = new FileOutputStream(f);
String s = ta.getText();
fos.write(s.getBytes(), 0, s.length());
}
@@ -304,20 +239,31 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
"Error saving file: " + ioe.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
}
finally {
if (fos != null) {
try {
fos.close();
}
catch (IOException ignore) {
}
}
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Run"))
if (e.getActionCommand().equals("Run")) {
startExecution();
else if (e.getActionCommand().equals("Stop"))
stopExecution();
else if (e.getActionCommand().equals("Close"))
}
else if (e.getActionCommand().equals("Close")) {
frame.dispose();
else if (e.getActionCommand().equals("Save"))
}
else if (e.getActionCommand().equals("Save")) {
saveTextArea();
else if (e.getActionCommand().equals("Clear"))
}
else if (e.getActionCommand().equals("Clear")) {
ta.setText("");
}
}
public JTextArea getTextArea() {
@@ -327,52 +273,15 @@ public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, Do
public int getCurrentPosition() {
return currentPosition;
}
public void toggleBreakPoint(int line) {
Integer lineObj = new Integer(line);
int idx = breakpoints.indexOf(lineObj);
if (idx != -1)
breakpoints.remove(lineObj);
else
breakpoints.add(lineObj);
}
public boolean isBreakPoint(int line) {
if (breakpoints.contains(new Integer(line)))
return true;
return false;
}
}
class GlyphGutter extends JComponent implements MouseListener {
class GlyphGutter extends JComponent {
private OOBeanShellDebugger debugger;
private boolean isError = false;
public void mouseEntered(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
if (e.getComponent() == this &&
(e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
int x = e.getX();
int y = e.getY();
Font font = debugger.getTextArea().getFont();
FontMetrics metrics = getFontMetrics(font);
int h = metrics.getHeight();
int line = y/h;
debugger.toggleBreakPoint(line + 1);
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
private final String DUMMY_STRING = "99";
GlyphGutter(OOBeanShellDebugger debugger) {
this.debugger = debugger;
// addMouseListener(this);
update();
}
@@ -380,13 +289,16 @@ class GlyphGutter extends JComponent implements MouseListener {
JTextArea textArea = debugger.getTextArea();
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";
dummy = DUMMY_STRING;
}
Dimension d = new Dimension();
d.width = metrics.stringWidth(dummy) + 16;
d.height = lineCount * h + 100;
@@ -413,7 +325,9 @@ class GlyphGutter extends JComponent implements MouseListener {
int startLine = clip.y / h;
int endLine = (clip.y + clip.height) / h + 1;
int width = getWidth();
if (endLine > lineCount) endLine = lineCount;
if (endLine > lineCount) {
endLine = lineCount;
}
for (int i = startLine; i < endLine; i++) {
String text;
@@ -424,22 +338,13 @@ class GlyphGutter extends JComponent implements MouseListener {
g.drawString(text, 0, y + ascent);
int x = width - ascent;
if (debugger.isBreakPoint(i + 1))
drawBreakPoint(g, ascent, x, y);
if (i == debugger.getCurrentPosition())
// if currentPosition is not -1 then a red arrow will be drawn
if (i == debugger.getCurrentPosition()) {
drawArrow(g, ascent, x, y);
}
}
}
private void drawBreakPoint(Graphics g, int ascent, int x, int y) {
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);
}
private void drawArrow(Graphics g, int ascent, int x, int y) {
Polygon arrow = new Polygon();
int dx = x;

View File

@@ -1,10 +1,18 @@
import drafts.com.sun.star.script.framework.runtime.XScriptContext;
import javax.swing.SwingUtilities;
import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.debugger.*;
import java.io.InputStream;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.tools.debugger.Main;
import org.mozilla.javascript.tools.debugger.ScopeProvider;
import drafts.com.sun.star.script.framework.runtime.XScriptContext;
public class OORhinoDebugger implements OOScriptDebugger {
// This code is based on the main method of the Rhino Debugger Main class
// We pass in the XScriptContext in the global scope for script execution
public void go(final XScriptContext xsctxt, String filename) {
try {
final Main sdb = new Main("Rhino JavaScript Debugger");
@@ -31,12 +39,17 @@ public class OORhinoDebugger implements OOScriptDebugger {
return scope;
}
});
// This is the method we've added to open a file when starting
// the Rhino debugger
sdb.openFile(filename);
} catch (Exception exc) {
exc.printStackTrace();
}
}
public void go(final XScriptContext xsctxt, InputStream in) {
}
static void swingInvoke(Runnable f) {
if (SwingUtilities.isEventDispatchThread()) {
f.run();

View File

@@ -1,5 +1,7 @@
import java.io.InputStream;
import drafts.com.sun.star.script.framework.runtime.XScriptContext;
public interface OOScriptDebugger {
public void go(XScriptContext ctxt, String filename);
public void go(XScriptContext ctxt, InputStream in);
}

View File

@@ -4,10 +4,11 @@
<script language="Java">
<locale lang="en">
<displayname value="asdf.doMethod" />
<description>asdf.doMethod</description>
<displayname value="Scripting Framework Debugger" />
<description>Script that starts debuggers for Rhino and BeanShell
</description>
</locale>
<logicalname value="DebugRunner.Debug" />
<logicalname value="_$DebugRunner.Debug" />
<functionname value="DebugRunner.go" />
<languagedepprops>
<prop name="classpath" value="debugger.jar"/>