Friday, November 7, 2008

I wanted to execute JavaScript in a Java program. Rhino looked like it would do the trick, but there is no DOM without a browser, and i wanted to run browser-less. I found a lot of discussion around this but none worked just right. Here is the incantation i used:
document = new Object ();
document.writeln = function (s)
{
if (s instanceof Array)
for (x in s)
document.writeln (s[x]);
else
java.lang.System.out.println (s);
}
document.write = function (s)
{
if (s instanceof Array)
for (x in s)
document.write (s[x]);
else
java.lang.System.out.print (s);
}

I imagine i could extend it to capture most of what a browser's DOM contains; maybe some day.
I also modified RunScript to read from System.in and inject the above code:
import java.io.FileReader;
import org.mozilla.javascript.*;

public class RunScript
{
public static void main(String args[]) throws
java.io.FileNotFoundException, java.io.IOException
{
String s = "document = new Object ();" +
"document.writeln = function (s)" +
"{ java.lang.System.out.println (s); };" +
"document.write = function (s)" +
"{ java.lang.System.out.print (s); };";

Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();

Object result = cx.evaluateString (scope, s, "<prelude>", 1, null);

FileReader in = new FileReader (args[0]);

result = cx.evaluateReader (scope, in, args[0], 1, null);

System.err.println(Context.toString(result));

}
finally
{
Context.exit();
}
}
}

No comments: