Links

pmuellr is Patrick Mueller

other pmuellr thangs: home page, twitter, flickr, github

Saturday, March 11, 2006

More Eclipse Monkeying

Playing with Eclipse Monkey

I spent a little time playing more with Eclipse Monkey yeserday. I've written a little Domain Object Model (DOM) that allows you to load and execute a JavaScript file. The idea is to create some little reusable functions / classes. The first quick test was writing an alert() function. Here's the source of alert.js:

//------------------------------------------------------------------- // a port of web browser's alert() function //------------------------------------------------------------------- alert = function (message) { Packages.org.eclipse.jface.dialogs.MessageDialog.openInformation( window.getShell(), "Eclipse Monkey Alert", message ) } alert

What's going on here is that I'm defining a function that puts up a dialog with some message in it. The last line of the file references the function, and ends up being the 'result' of executing the script with my DOM. Let's show the example that uses this in the file alertTest.em:

/* * Menu: Test > alert * DOM: http://localhost/org.muellerware.eclipsemonkey.dom.scriptloader */ alert = ScriptLoader.loadProjectFile("ScriptLoader Sample", "monkey/alert.js") function main() { alert("Hello, World") }

Taking it from the top, the Menu: line will cause a "Test" menu to be created under the Monkey Script menu on the main window, and then add a menu item to that called "alert".

The DOM: line points to my DOM. I cheated; the 'value' of the line is supposed to be a URL to the update site to get the DOM. The last path segment in the URL names the bundle the DOM is implemented in. As long as that bundle is loaded, the previous part of the URL isn't used for anything.

The next line with the alert assignment loads the script defined previously. Since that script 'returns' a function, we store the function in a variable called 'alert'. Note that the uses of alert in both files is completely independent. The name used in the alert.js file is basically thrown away. The only thing remembered in that script is the 'return' value. After the assignment from the result of the loadProjectFile() method, we can use the alert() function anywhere else in the .em file.

Pretty cool.

My next thought was to create a Console class which provided access to an Eclipse console. I thought this would be a nice way to support some basic println() capabilties. And would be pretty simple to test.

Here's the source for my Console.js class:

Array = java.lang.reflect.Array ConsolePlugin = Packages.org.eclipse.ui.console.ConsolePlugin MessageConsole = Packages.org.eclipse.ui.console.MessageConsole MessageConsoleStream = Packages.org.eclipse.ui.console.MessageConsoleStream //------------------------------------------------------------------- function Console(name) { var console = new MessageConsole(name, null) this.messageConsole = console this.messageStream = console.newMessageStream() var consoles = Array.newInstance(MessageConsole, 1) consoles[0] = console ConsolePlugin.getDefault().getConsoleManager().addConsoles(consoles) } //------------------------------------------------------------------- Console.prototype.print = function(string) { this.messageStream.print("" + string) } //------------------------------------------------------------------- Console.prototype.println = function(string) { this.messageStream.println("" + string) } //------------------------------------------------------------------- Console.prototype.println = function() { this.messageStream.println("" + string) } //------------------------------------------------------------------- Console

And here's the tester:

/* * Menu: Test > Console * DOM: http://download.eclipse.org/technology/dash/update/org.muellerware.eclipsemonkey.dom.scriptloader */ alert = ScriptLoader.loadProjectFile("ScriptLoader Sample", "monkey/alert.js"); function main() { var Console = ScriptLoader.loadProjectFile("ScriptLoader Sample", "monkey/Console.js") console = new Console("testing, 1, 2, 3") alert(console) console.print("1") console.print("2") console.print("3") console.println() console.println("1") console.println("2") console.println("3") }

Bad news. Looks like I'm unable to load the MessageConsole class. As near as I can tell, the issue is that while running an Eclipse Monkey script, you only have access to stuff that the plugin that runs the script has visibility to. That plugin is org.eclipse.eclipsemonkey. You can change this, to some extent, with your own DOM, as it can see whatever it wants. However, that doesn't help in the JavaScript code, only in the Java code that implements your DOM.

Dang. The whole reason for doing my scriptloader thing was to try to radically cut down on the amount of Java you would need to write interesting scripts. I can see we are limited by strict classloading rules the eclipse runtime lays down on us. Which you can 'relax' by writing your own plugins. Which kills the idea of radically cutting down the amount of Java you need to write.

Sigh.

No comments: