a simple example for java script engine.
package script;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.*;
/**
* @author piumnl
* @version 1.0.0
* @since on 2016-12-14.
*/
public class ScriptDemo {
private ScriptEngineManager manager;
private ScriptEngine engine;
/**
* 测试之前的操作
*
* @since 2016/12/14
*/
@Before
public void before() {
System.out.println("============正在初始化测试环境=============");
manager = new ScriptEngineManager();
engine = manager.getEngineByName("JavaScript");
System.out.println("============成功初始化测试环境=============");
System.out.println("===================测试开始===============");
}
/**
* 测试getEngine()方法
*
* @since 2016/12/14
*/
@Test
public void test_getEngine() {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
ScriptEngine extension = manager.getEngineByExtension("js");
ScriptEngine mimeType = manager.getEngineByMimeType("text/javascript");
}
/**
* 测试getScriptEngineFactory()方法
*
* @since 2016/12/14
*/
@Test
public void test_getScriptEngineFactory() {
ScriptEngineManager manager = new ScriptEngineManager();
List<ScriptEngineFactory> engineFactories = manager.getEngineFactories();
for (ScriptEngineFactory engineFactory : engineFactories) {
System.out.println("engineName:" + engineFactory.getEngineName());
System.out.println("engineVersion:" + engineFactory.getEngineVersion());
List<String> names = engineFactory.getNames();
System.out.print("\tname:");
for (String name : names) {
System.out.print(name + ",");
}
System.out.println();
List<String> mimeTypes = engineFactory.getMimeTypes();
System.out.print("\tmimeType:");
for (String mimeType : mimeTypes) {
System.out.print(mimeType + ",");
}
System.out.println();
List<String> extensions = engineFactory.getExtensions();
System.out.print("\textension:");
for (String extension : extensions) {
System.out.print(extension + ",");
}
System.out.println();
System.out.println("\tlanguageName:" + engineFactory.getLanguageName());
System.out.println("\tlanguageVersion:" + engineFactory.getLanguageVersion());
ScriptEngine scriptEngine = engineFactory.getScriptEngine();
}
}
/**
* 测试runScript()方法
*
* @since 2016/12/14
*/
@Test
public void test_runScript() throws ScriptException {
// eval 直接运行 字符串 ,并返回该 表达式的结果
engine.eval("var n = 10;");
Object eval;
eval = engine.eval("n == 10");
Assert.assertTrue((Boolean) eval);
// 运行 js 脚本
try {
String scriptFile = this.getClass().getResource("/").getPath() + "/simple.js";
FileReader fileReader = new FileReader(new File(scriptFile));
engine.eval(fileReader);
Object t = engine.eval("t");
Assert.assertEquals(201D, t);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 向 引擎 绑定值
engine.put("k", 1589);
eval = engine.eval("k * 10");
Assert.assertEquals(15890D, eval);
// 从 引擎 中获取值,大多数脚本语言都可以访问 java 对象
JButton button = new JButton();
engine.put("b", button);
engine.eval("b.text = 'OK'");
Assert.assertEquals("OK", button.getText());
// 全局作用域,对所有 引擎 可视
manager.put("global", "This is the global scope");
Assert.assertEquals("This is the global scope", engine.get("global"));
// 可以将绑定的值放置在 Bindings 中,然后传递给 engine ,此时值就不存在于 engine 中。
Bindings scope = engine.createBindings();
scope.put("b", new JButton());
engine.eval("b.name = 'H'", scope);
eval = engine.eval("b.name", scope);
Assert.assertEquals("H", eval);
// 自定义 作用域
// 定义类 实现 ScriptContext 接口,然后管理一个作用域集合,
// 每个作用域都由一个整数标识,越小的数字越先被搜索。
// 标准类库中提供了 SimpleScriptContext 类,但它只持有全局作用域和引擎作用域。
}
/**
* 测试outputAndInput()方法
*
* @since 2016/12/14
*/
@Test
public void test_outputAndInput() throws ScriptException {
StringWriter writer = new StringWriter();
// 只能传 PrintWriter,否则会抛异常
// 此处用 js 的print和println函数产生的输出会发送到writer中。
engine.getContext().setWriter(new PrintWriter(writer, true));
engine.eval("print('Hello')");
Assert.assertEquals("Hello\r\n", writer.getBuffer().toString());
}
/**
* 测试invokeFunction()方法
*
* @since 2016/12/14
*/
@Test
public void test_invokeFunction() throws ScriptException, NoSuchMethodException {
// 调用脚本的函数,需要脚本引擎实现了 Invocable 接口
engine.eval("function sum(a, b) { return a + b; }");
if (engine instanceof Invocable) {
Object sum = ((Invocable) engine).invokeFunction("sum", 10, 20);
Assert.assertEquals(30D, sum);
// 如果 脚本 是面向对象的,可以这样调用
// ((Invocable) engine).invokeMethod(impliciParam, "aMethod", explicitParam1, explicitParam2);
// 此处 的 impliciParam 对象是脚本语言编写的对象的一个代理,它必须是前一个脚本引擎调用的结果。
}
}
/**
* 测试implementInterface()方法
* js 实现 java 接口
* @since 2016/12/14
*/
@Test
public void test_implementInterface() throws ScriptException {
if (engine instanceof Invocable) {
engine.eval("function greet(whom) { return 'Hello,' + whom + '!'; }");
Greeter greeter = ((Invocable) engine).getInterface(Greeter.class); // 注意 接口必须是 public
greeter.greet("piumnl");
}
}
/**
* 测试implementInterfaceForOOP()方法
* @since 2016/12/14
*/
@Test
public void test_implementInterfaceForOOP() throws ScriptException {
if (engine instanceof Invocable) {
engine.eval("function SimpleGreeter(salutation) {\n" +
" this.salutation = salutation\n" +
"}\n" +
"SimpleGreeter.prototype.greet = function (whom) {\n" +
" return this.salutation + ', ' + whom + '!';\n" +
"}");
Object bye = engine.eval("new SimpleGreeter('Goodbye')");
Greeter greeter = ((Invocable) engine).getInterface(bye, Greeter.class);
Assert.assertEquals("Goodbye, piumnl!", greeter.greet("piumnl"));
}
}
/**
* 测试compile()方法
* 有时候对脚本编译可以加快运行速度
* @since 2016/12/14
* @throws FileNotFoundException
*/
@Test
public void test_compile() throws FileNotFoundException, ScriptException {
String jsFile = this.getClass().getResource("/").getPath() + "/simple.js";
FileReader fileReader = new FileReader(new File(jsFile));
if (engine instanceof Compilable) {
CompiledScript compile = ((Compilable) engine).compile(fileReader);
if (compile != null) {
compile.eval();
} else {// 脚本引擎不支持编译
engine.eval(fileReader);
}
}
}
public interface Greeter {
String greet(String whom);
}
}