Monday, December 7, 2015

A new interpreter for EASE (1): Playing with beanshell

This new series will provide a guide how to integrate your own interpreter in EASE. As a showcase we will implement an interpreter for BeanShell.

Read all tutorials from this series.

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online. 

Step 1: Evaluate interpreter candidates

The bare minimum requirement for an interpreter to do something useful with EASE is to support an execute() method that accepts and executes arbitrary strings of script code. This will allow to use the interpreter in the script shell and to create script files and execute them using the EASE launch target.

Now EASE typically integrates interpreters that run natively on the JRE. This allows scripts to seamlessly interact with the current application. Such interpreters have some additional requirements:
  • access native java objects (eg. java.lang.System)
  • set/get variables in the interpreter
  • allow to define functions/methods
  • redirect input/output/error streams
Interpreters like Rhino or Jython support these extended requirements and therefore allow to write scripts that fully integrate into EASE.

However much simpler interpreters may make sense in some cases. I have played around with such interpreters and built a basic git console and a bash console. Both are in a proof of concept state, but might indicate what can be done with EASE.

Step 2: Integrating BeanShell

We will concentrate on BeanShell, so download the latest stable build.

Now create a new Plug-in from Existing JAR Archives. On the next page hit Add External and add the downloaded bsh-<version>.jar. Set the project name to org.beanshell and select Unzip the JAR archives into the project.

Open the Plug-in Manifest Editor and make sure that the bsh package is correctly exported on the Runtime tab.

Step 3: Play with the interpreter

To learn how the interpreter works we create a Java Project org.beanshell.playground. Add our org.beanshell project to the Java Build Path and create a test class with a main method:
package org.beanshell.playground;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;

import bsh.EvalError;
import bsh.Interpreter;

public class RunEmbedded {

 private static final String[] CODE_FRAGMENTS = new String[] { "2+3", "foo*10", "new java.io.File(\"/\").exists()",
   "sum(a,b){\n return a+b;\n }\nsum(40,2)" };

 public static void main(String[] args) throws EvalError, FileNotFoundException, IOException {
  Interpreter interpreter = new Interpreter(); // Construct an interpreter

  // set variables
  interpreter.set("foo", 5);
  interpreter.set("date", new Date());

  // get variables
  Object date = interpreter.get("date");

  // evaluate statements
  for (String code : CODE_FRAGMENTS) {
   System.out.println(interpreter.eval(code));
  }
 }
}

A simple embedding example was quickly found using google, now our tests show how to get/set variables and how to execute various pieces of code. From what we can see so far BeanShell is a perfect candidate for scripting.

The following tutorials will show how to integrate the interpreter in EASE, stay tuned!.

No comments:

Post a Comment