This commit is contained in:
Looly 2020-09-28 19:27:57 +08:00
parent d775ce9cca
commit 80f85390e4
6 changed files with 127 additions and 74 deletions

View File

@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.4.4 (2020-09-23) # 5.4.4 (2020-09-28)
### 新特性 ### 新特性
* 【core 】 ServiceLoaderUtil改为使用contextClassLoaderpr#183@Gitee * 【core 】 ServiceLoaderUtil改为使用contextClassLoaderpr#183@Gitee
@ -36,6 +36,7 @@
* 【core 】 修复新建默认TreeSet没有默认比较器导致的问题issue#1101@Github * 【core 】 修复新建默认TreeSet没有默认比较器导致的问题issue#1101@Github
* 【core 】 修复Linux下使用Windows路径分隔符导致的解压错误issue#I1MW0E@Gitee * 【core 】 修复Linux下使用Windows路径分隔符导致的解压错误issue#I1MW0E@Gitee
* 【core 】 修复Word07Writer写出map问题issue#I1W49R@Gitee * 【core 】 修复Word07Writer写出map问题issue#I1W49R@Gitee
* 【script 】 修复函数库脚本执行问题
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@ -1433,8 +1433,7 @@ public class NumberUtil {
public static long factorial(long start, long end) { public static long factorial(long start, long end) {
// 负数没有阶乘 // 负数没有阶乘
if (start < 0 || end < 0) { if (start < 0 || end < 0) {
throw new IllegalArgumentException(String.format("Factorial start and end both must be >= 0, " + throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be >= 0, but got start={}, end={}", start, end));
"but got start=%d, end=%d", start, end));
} }
if (0L == start || start == end) { if (0L == start || start == end) {
return 1L; return 1L;
@ -1447,6 +1446,7 @@ public class NumberUtil {
/** /**
* 计算范围阶乘中校验中间的计算是否存在溢出factorial提前做了负数和0的校验因此这里没有校验数字的正负 * 计算范围阶乘中校验中间的计算是否存在溢出factorial提前做了负数和0的校验因此这里没有校验数字的正负
*
* @param a 乘数 * @param a 乘数
* @param b 被乘数 * @param b 被乘数
* @return 如果 a * b的结果没有溢出直接返回否则抛出异常 * @return 如果 a * b的结果没有溢出直接返回否则抛出异常
@ -1455,7 +1455,7 @@ public class NumberUtil {
if (a <= Long.MAX_VALUE / b) { if (a <= Long.MAX_VALUE / b) {
return a * b; return a * b;
} }
throw new IllegalArgumentException(String.format("Overflow in multiplication: {%d} * {%d}", a, b)); throw new IllegalArgumentException(StrUtil.format("Overflow in multiplication: {} * {}", a, b));
} }
/** /**
@ -1469,8 +1469,7 @@ public class NumberUtil {
*/ */
public static long factorial(long n) { public static long factorial(long n) {
if (n < 0 || n > 20) { if (n < 0 || n > 20) {
throw new IllegalArgumentException(String.format("Factorial must have n >= 0 and n <= 20 for n!, " + throw new IllegalArgumentException(StrUtil.format("Factorial must have n >= 0 and n <= 20 for n!, but got n = {}", n));
"but got n = %d", n));
} }
return FACTORIALS[(int) n]; return FACTORIALS[(int) n];
} }

View File

@ -151,7 +151,12 @@ public class ScriptUtil {
} }
/** /**
* 执行Javascript脚本返回Invocable * 执行Javascript脚本返回Invocable此方法分为两种情况
*
* <ol>
* <li>执行的脚本返回值是可执行的脚本方法</li>
* <li>脚本为函数库则ScriptEngine本身为可执行方法</li>
* </ol>
* *
* @param script 脚本内容 * @param script 脚本内容
* @return 执行结果 * @return 执行结果
@ -159,11 +164,23 @@ public class ScriptUtil {
* @since 5.3.6 * @since 5.3.6
*/ */
public static Invocable evalInvocable(String script) throws ScriptRuntimeException { public static Invocable evalInvocable(String script) throws ScriptRuntimeException {
return (Invocable) eval(script); final ScriptEngine jsEngine = getJsEngine();
final Object eval;
try {
eval = jsEngine.eval(script);
} catch (ScriptException e) {
throw new ScriptRuntimeException(e);
}
if(eval instanceof Invocable){
return (Invocable)eval;
} else if(jsEngine instanceof Invocable){
return (Invocable)jsEngine;
}
throw new ScriptRuntimeException("Script is not invocable !");
} }
/** /**
* 执行Javascript脚本 * 执行有返回值的Javascript脚本
* *
* @param script 脚本内容 * @param script 脚本内容
* @return 执行结果 * @return 执行结果
@ -179,7 +196,7 @@ public class ScriptUtil {
} }
/** /**
* 执行脚本 * 执行有返回值的脚本
* *
* @param script 脚本内容 * @param script 脚本内容
* @param context 脚本上下文 * @param context 脚本上下文
@ -196,7 +213,7 @@ public class ScriptUtil {
} }
/** /**
* 执行脚本 * 执行有返回值的脚本
* *
* @param script 脚本内容 * @param script 脚本内容
* @param bindings 绑定的参数 * @param bindings 绑定的参数

View File

@ -0,0 +1,22 @@
package cn.hutool.script.test;
import cn.hutool.core.io.resource.ResourceUtil;
import org.junit.Assert;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class NashornDeepTest {
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.eval(ResourceUtil.readUtf8Str("filter1.js"));
final Object filter1 = ((Invocable) engine).invokeFunction("filter1", 1, 2);
Assert.assertFalse((Boolean) filter1);
}
}

View File

@ -1,7 +1,9 @@
package cn.hutool.script.test; package cn.hutool.script.test;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.script.ScriptRuntimeException; import cn.hutool.script.ScriptRuntimeException;
import cn.hutool.script.ScriptUtil; import cn.hutool.script.ScriptUtil;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import javax.script.CompiledScript; import javax.script.CompiledScript;
@ -31,6 +33,12 @@ public class ScriptUtilTest {
ScriptUtil.eval("print('Script test!');"); ScriptUtil.eval("print('Script test!');");
} }
@Test
public void invokeTest() {
final Object result = ScriptUtil.invoke(ResourceUtil.readUtf8Str("filter1.js"), "filter1", 2, 1);
Assert.assertTrue((Boolean) result);
}
@Test @Test
public void pythonTest() throws ScriptException { public void pythonTest() throws ScriptException {
final ScriptEngine pythonEngine = ScriptUtil.getPythonEngine(); final ScriptEngine pythonEngine = ScriptUtil.getPythonEngine();

View File

@ -0,0 +1,6 @@
function filter1(a, b) {
if (a > b) {
return a > b;
}
return false;
}