add LockUtil and fix Cache

This commit is contained in:
Looly
2020-03-26 23:46:36 +08:00
parent 54760ea0a2
commit 0d7ef8f092
13 changed files with 379 additions and 218 deletions

View File

@@ -1,9 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
@@ -13,12 +14,37 @@
<artifactId>hutool-script</artifactId>
<name>${project.artifactId}</name>
<description>Hutool 脚本执行封装</description>
<properties>
<jython.version>2.7.0</jython.version>
<luaj.version>3.0.1</luaj.version>
<groovy.version>3.0.2</groovy.version>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython</artifactId>
<version>${jython.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.luaj</groupId>
<artifactId>luaj-jse</artifactId>
<version>${luaj.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>${groovy.version}</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,65 +1,64 @@
package cn.hutool.script;
import java.io.Reader;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.Reader;
/**
* Javascript引擎类
* @author Looly
*
* @author Looly
*/
public class JavaScriptEngine extends FullSupportScriptEngine{
public class JavaScriptEngine extends FullSupportScriptEngine {
public JavaScriptEngine() {
super(new ScriptEngineManager().getEngineByName("javascript"));
super(ScriptUtil.getJsEngine());
}
/**
* 引擎实例
*
* @return 引擎实例
*/
public static JavaScriptEngine instance(){
public static JavaScriptEngine instance() {
return new JavaScriptEngine();
}
//----------------------------------------------------------------------------------------------- Invocable
@Override
public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException {
return ((Invocable)engine).invokeMethod(thiz, name, args);
return ((Invocable) engine).invokeMethod(thiz, name, args);
}
@Override
public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException {
return ((Invocable)engine).invokeFunction(name, args);
return ((Invocable) engine).invokeFunction(name, args);
}
@Override
public <T> T getInterface(Class<T> clasz) {
return ((Invocable)engine).getInterface(clasz);
return ((Invocable) engine).getInterface(clasz);
}
@Override
public <T> T getInterface(Object thiz, Class<T> clasz) {
return ((Invocable)engine).getInterface(thiz, clasz);
return ((Invocable) engine).getInterface(thiz, clasz);
}
//----------------------------------------------------------------------------------------------- Compilable
@Override
public CompiledScript compile(String script) throws ScriptException {
return ((Compilable)engine).compile(script);
return ((Compilable) engine).compile(script);
}
@Override
public CompiledScript compile(Reader script) throws ScriptException {
return ((Compilable)engine).compile(script);
return ((Compilable) engine).compile(script);
}
//----------------------------------------------------------------------------------------------- ScriptEngine

View File

@@ -1,10 +1,10 @@
package cn.hutool.script;
import javax.script.ScriptException;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import javax.script.ScriptException;
/**
* 脚本运行时异常
*
@@ -50,7 +50,6 @@ public class ScriptRuntimeException extends RuntimeException {
super(message);
this.fileName = fileName;
this.lineNumber = lineNumber;
this.columnNumber = -1;
}
/**

View File

@@ -1,5 +1,8 @@
package cn.hutool.script;
import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.util.StrUtil;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
@@ -10,34 +13,92 @@ import javax.script.ScriptException;
/**
* 脚本工具类
*
* @author Looly
*
* @author Looly
*/
public class ScriptUtil {
private static final ScriptEngineManager manager = new ScriptEngineManager();
private static SimpleCache<String, ScriptEngine> cache = new SimpleCache<>();
/**
* 获得 {@link ScriptEngine} 实例
*
* @param name 脚本名称
*
* @param nameOrExtOrMime 脚本名称
* @return {@link ScriptEngine} 实例
*/
public static ScriptEngine getScript(String name) {
return new ScriptEngineManager().getEngineByName(name);
public static ScriptEngine getScript(String nameOrExtOrMime) {
return cache.get(nameOrExtOrMime, ()->{
ScriptEngine engine = manager.getEngineByName(nameOrExtOrMime);
if (null == engine) {
engine = manager.getEngineByExtension(nameOrExtOrMime);
}
if (null == engine) {
engine = manager.getEngineByMimeType(nameOrExtOrMime);
}
if (null == engine) {
throw new NullPointerException(StrUtil.format("Script for [{}] not support !", nameOrExtOrMime));
}
return engine;
});
}
/**
* 获得 Javascript引擎 {@link JavaScriptEngine}
*
*
* @return {@link JavaScriptEngine}
*/
public static JavaScriptEngine getJavaScriptEngine() {
return new JavaScriptEngine();
}
/**
* 编译脚本
*
* 获得 JavaScript引擎
*
* @return Python引擎
* @since 5.2.5
*/
public static ScriptEngine getJsEngine() {
return getScript("js");
}
/**
* 获得 Python引擎<br>
* 需要引入org.python:jython
*
* @return Python引擎
* @since 5.2.5
*/
public static ScriptEngine getPythonEngine() {
System.setProperty("python.import.site", "false");
return getScript("python");
}
/**
* 获得Lua引擎<br>
* 需要引入org.luaj:luaj-jse
*
* @return Lua引擎
* @since 5.2.5
*/
public static ScriptEngine getLuaEngine() {
return getScript("lua");
}
/**
* 获得Groovy引擎<br>
* 需要引入org.codehaus.groovy:groovy-all
*
* @return Groovy引擎
* @since 5.2.5
*/
public static ScriptEngine getGroovyEngine() {
return getScript("groovy");
}
/**
* 执行脚本
*
* @param script 脚本内容
* @return {@link CompiledScript}
* @throws ScriptRuntimeException 脚本异常
@@ -45,16 +106,16 @@ public class ScriptUtil {
*/
public static Object eval(String script) throws ScriptRuntimeException {
try {
return compile(script).eval();
return getJsEngine().eval(script);
} catch (ScriptException e) {
throw new ScriptRuntimeException(e);
}
}
/**
* 编译脚本
*
* @param script 脚本内容
* 执行脚本
*
* @param script 脚本内容
* @param context 脚本上下文
* @return {@link CompiledScript}
* @throws ScriptRuntimeException 脚本异常
@@ -62,16 +123,16 @@ public class ScriptUtil {
*/
public static Object eval(String script, ScriptContext context) throws ScriptRuntimeException {
try {
return compile(script).eval(context);
return getJsEngine().eval(script, context);
} catch (ScriptException e) {
throw new ScriptRuntimeException(e);
}
}
/**
* 编译脚本
*
* @param script 脚本内容
* 执行脚本
*
* @param script 脚本内容
* @param bindings 绑定的参数
* @return {@link CompiledScript}
* @throws ScriptRuntimeException 脚本异常
@@ -79,7 +140,7 @@ public class ScriptUtil {
*/
public static Object eval(String script, Bindings bindings) throws ScriptRuntimeException {
try {
return compile(script).eval(bindings);
return getJsEngine().eval(script, bindings);
} catch (ScriptException e) {
throw new ScriptRuntimeException(e);
}
@@ -87,7 +148,7 @@ public class ScriptUtil {
/**
* 编译脚本
*
*
* @param script 脚本内容
* @return {@link CompiledScript}
* @throws ScriptRuntimeException 脚本异常
@@ -95,7 +156,7 @@ public class ScriptUtil {
*/
public static CompiledScript compile(String script) throws ScriptRuntimeException {
try {
return compile(getJavaScriptEngine(), script);
return compile(getJsEngine(), script);
} catch (ScriptException e) {
throw new ScriptRuntimeException(e);
}
@@ -103,7 +164,7 @@ public class ScriptUtil {
/**
* 编译脚本
*
*
* @param engine 引擎
* @param script 脚本内容
* @return {@link CompiledScript}
@@ -111,7 +172,7 @@ public class ScriptUtil {
*/
public static CompiledScript compile(ScriptEngine engine, String script) throws ScriptException {
if (engine instanceof Compilable) {
Compilable compEngine = (Compilable) engine;
final Compilable compEngine = (Compilable) engine;
return compEngine.compile(script);
}
return null;

View File

@@ -1,12 +1,12 @@
package cn.hutool.script.test;
import javax.script.CompiledScript;
import javax.script.ScriptException;
import org.junit.Test;
import cn.hutool.script.ScriptRuntimeException;
import cn.hutool.script.ScriptUtil;
import org.junit.Test;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
/**
* 脚本单元测试类
@@ -30,4 +30,22 @@ public class ScriptUtilTest {
public void evalTest() {
ScriptUtil.eval("print('Script test!');");
}
@Test
public void pythonTest() throws ScriptException {
final ScriptEngine pythonEngine = ScriptUtil.getPythonEngine();
pythonEngine.eval("print('Hello Python')");
}
@Test
public void luaTest() throws ScriptException {
final ScriptEngine engine = ScriptUtil.getLuaEngine();
engine.eval("print('Hello Lua')");
}
@Test
public void groovyTest() throws ScriptException {
final ScriptEngine engine = ScriptUtil.getGroovyEngine();
engine.eval("println 'Hello Groovy'");
}
}