This commit is contained in:
Looly
2023-04-21 01:09:02 +08:00
parent 9bbfdca820
commit 32e8caccdd
14 changed files with 86 additions and 512 deletions

View File

@@ -354,8 +354,8 @@
</dependency>
<dependency>
<groupId>com.mayabot.mynlp</groupId>
<artifactId>mynlp-segment</artifactId>
<version>3.0.2</version>
<artifactId>mynlp-all</artifactId>
<version>4.0.0</version>
<optional>true</optional>
</dependency>
<!-- Spring Boot -->
@@ -422,6 +422,13 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.4</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- 验证工具可选依赖 begin -->
<dependency>
<groupId>jakarta.validation</groupId>
@@ -463,6 +470,10 @@
<artifactId>junit-jupiter</artifactId>
<groupId>org.junit.jupiter</groupId>
</exclusion>
<exclusion>
<artifactId>json-path</artifactId>
<groupId>com.jayway.jsonpath</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View File

@@ -1,72 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.aop.interceptor;
import org.dromara.hutool.extra.aop.aspects.Aspect;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Cglib实现的动态代理切面
*
* @author looly, ted.L
*/
public class CglibInterceptor implements MethodInterceptor, Serializable {
private static final long serialVersionUID = 1L;
private final Object target;
private final Aspect aspect;
/**
* 构造
*
* @param target 被代理对象
* @param aspect 切面实现
*/
public CglibInterceptor(final Object target, final Aspect aspect) {
this.target = target;
this.aspect = aspect;
}
public Object getTarget() {
return this.target;
}
@Override
public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
final Object target = this.target;
Object result = null;
// 开始前回调
if (aspect.before(target, method, args)) {
try {
// result = proxy.invokeSuper(obj, args);
result = proxy.invoke(target, args);
} catch (final InvocationTargetException e) {
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
if (aspect.afterException(target, method, args, e.getTargetException())) {
throw e;
}
}
}
// 结束执行回调
if (aspect.after(target, method, args, result)) {
return result;
}
return null;
}
}

View File

@@ -16,7 +16,6 @@ import org.dromara.hutool.core.reflect.ModifierUtil;
import org.dromara.hutool.core.reflect.ReflectUtil;
import org.dromara.hutool.extra.aop.aspects.Aspect;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -27,12 +26,9 @@ import java.lang.reflect.Method;
* @author Looly
* @author ted.L
*/
public class JdkInterceptor implements InvocationHandler, Serializable {
public class JdkInterceptor extends SimpleInterceptor implements InvocationHandler {
private static final long serialVersionUID = 1L;
private final Object target;
private final Aspect aspect;
/**
* 构造
*
@@ -40,17 +36,7 @@ public class JdkInterceptor implements InvocationHandler, Serializable {
* @param aspect 切面实现
*/
public JdkInterceptor(final Object target, final Aspect aspect) {
this.target = target;
this.aspect = aspect;
}
/**
* 获取目标对象
*
* @return 目标对象
*/
public Object getTarget() {
return this.target;
super(target, aspect);
}
@SuppressWarnings("SuspiciousInvocationHandlerImplementation")

View File

@@ -10,27 +10,42 @@
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.aop.proxy;
package org.dromara.hutool.extra.aop.interceptor;
import org.dromara.hutool.extra.aop.aspects.Aspect;
import org.dromara.hutool.extra.aop.interceptor.CglibInterceptor;
import net.sf.cglib.proxy.Enhancer;
import java.io.Serializable;
/**
* 基于Cglib的切面代理工厂
* 简单拦截器保存了被拦截的对象和Aspect实现
*
* @author looly
* @since 6.0.0
*/
public class CglibProxyFactory implements ProxyFactory {
public class SimpleInterceptor implements Serializable {
private static final long serialVersionUID = 1L;
@Override
@SuppressWarnings("unchecked")
public <T> T proxy(final T target, final Aspect aspect) {
final Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new CglibInterceptor(target, aspect));
return (T) enhancer.create();
protected final Object target;
protected final Aspect aspect;
/**
* 构造
*
* @param target 被代理对象
* @param aspect 切面实现
*/
public SimpleInterceptor(final Object target, final Aspect aspect) {
this.target = target;
this.aspect = aspect;
}
/**
* 获取目标对象
*
* @return 目标对象
*/
public Object getTarget() {
return this.target;
}
}

View File

@@ -16,21 +16,18 @@ import org.dromara.hutool.extra.aop.aspects.Aspect;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Spring-cglib实现的动态代理切面
* Spring-cglib实现的动态代理切面<br>
* 只用于JDK8
*
* @author looly
*/
public class SpringCglibInterceptor implements MethodInterceptor, Serializable {
public class SpringCglibInterceptor extends SimpleInterceptor implements MethodInterceptor {
private static final long serialVersionUID = 1L;
private final Object target;
private final Aspect aspect;
/**
* 构造
*
@@ -38,17 +35,7 @@ public class SpringCglibInterceptor implements MethodInterceptor, Serializable {
* @param aspect 切面实现
*/
public SpringCglibInterceptor(final Object target, final Aspect aspect) {
this.target = target;
this.aspect = aspect;
}
/**
* 获得目标对象
*
* @return 目标对象
*/
public Object getTarget() {
return this.target;
super(target, aspect);
}
@Override
@@ -58,7 +45,6 @@ public class SpringCglibInterceptor implements MethodInterceptor, Serializable {
// 开始前回调
if (aspect.before(target, method, args)) {
try {
// result = proxy.invokeSuper(obj, args);
result = proxy.invoke(target, args);
} catch (final InvocationTargetException e) {
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)

View File

@@ -1,287 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.script;
import org.dromara.hutool.core.exceptions.UtilException;
import org.dromara.hutool.core.map.WeakConcurrentMap;
import org.dromara.hutool.core.text.StrUtil;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* 脚本工具类<br>
* 此脚本工具为javax.script的薄封装脚本执行取决于脚本引擎<br>
* 使用此脚本工具用户需要自行检查脚本中可能存在的风险代码,以避免脚本执行漏洞。
*
* @author Looly
*/
public class ScriptUtil {
private static final ScriptEngineManager MANAGER = new ScriptEngineManager();
private static final WeakConcurrentMap<String, ScriptEngine> CACHE = new WeakConcurrentMap<>();
/**
* 获得单例的{@link ScriptEngine} 实例
*
* @param nameOrExtOrMime 脚本名称
* @return {@link ScriptEngine} 实例
*/
public static ScriptEngine getScript(final String nameOrExtOrMime) {
return CACHE.computeIfAbsent(nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime));
}
/**
* 创建 {@link ScriptEngine} 实例
*
* @param nameOrExtOrMime 脚本名称
* @return {@link ScriptEngine} 实例
* @since 5.2.6
*/
public static ScriptEngine createScript(final String 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引擎
*
* @return Javascript引擎
* @since 5.2.5
*/
public static ScriptEngine getJsEngine() {
return getScript("js");
}
/**
* 创建新的JavaScript引擎
*
* @return Javascript引擎
* @since 5.2.6
*/
public static ScriptEngine createJsEngine() {
return createScript("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");
}
/**
* 创建Python引擎<br>
* 需要引入org.python:jython
*
* @return Python引擎
* @since 5.2.6
*/
public static ScriptEngine createPythonEngine() {
System.setProperty("python.import.site", "false");
return createScript("python");
}
/**
* 获得单例的Lua引擎<br>
* 需要引入org.luaj:luaj-jse
*
* @return Lua引擎
* @since 5.2.5
*/
public static ScriptEngine getLuaEngine() {
return getScript("lua");
}
/**
* 创建Lua引擎<br>
* 需要引入org.luaj:luaj-jse
*
* @return Lua引擎
* @since 5.2.6
*/
public static ScriptEngine createLuaEngine() {
return createScript("lua");
}
/**
* 获得单例的Groovy引擎<br>
* 需要引入org.codehaus.groovy:groovy-all
*
* @return Groovy引擎
* @since 5.2.5
*/
public static ScriptEngine getGroovyEngine() {
return getScript("groovy");
}
/**
* 创建Groovy引擎<br>
* 需要引入org.codehaus.groovy:groovy-all
*
* @return Groovy引擎
* @since 5.2.6
*/
public static ScriptEngine createGroovyEngine() {
return createScript("groovy");
}
/**
* 执行Javascript脚本返回Invocable此方法分为两种情况
*
* <ol>
* <li>执行的脚本返回值是可执行的脚本方法</li>
* <li>脚本为函数库则ScriptEngine本身为可执行方法</li>
* </ol>
*
* @param script 脚本内容
* @return 执行结果
* @throws UtilException 脚本异常
* @since 5.3.6
*/
public static Invocable evalInvocable(final String script) throws UtilException {
final ScriptEngine jsEngine = getJsEngine();
final Object eval;
try {
eval = jsEngine.eval(script);
} catch (final ScriptException e) {
throw new UtilException(e);
}
if(eval instanceof Invocable){
return (Invocable)eval;
} else if(jsEngine instanceof Invocable){
return (Invocable)jsEngine;
}
throw new UtilException("Script is not invocable !");
}
/**
* 执行有返回值的Javascript脚本
*
* @param script 脚本内容
* @return 执行结果
* @throws UtilException 脚本异常
* @since 3.2.0
*/
public static Object eval(final String script) throws UtilException {
try {
return getJsEngine().eval(script);
} catch (final ScriptException e) {
throw new UtilException(e);
}
}
/**
* 执行有返回值的脚本
*
* @param script 脚本内容
* @param context 脚本上下文
* @return 执行结果
* @throws UtilException 脚本异常
* @since 3.2.0
*/
public static Object eval(final String script, final ScriptContext context) throws UtilException {
try {
return getJsEngine().eval(script, context);
} catch (final ScriptException e) {
throw new UtilException(e);
}
}
/**
* 执行有返回值的脚本
*
* @param script 脚本内容
* @param bindings 绑定的参数
* @return 执行结果
* @throws UtilException 脚本异常
* @since 3.2.0
*/
public static Object eval(final String script, final Bindings bindings) throws UtilException {
try {
return getJsEngine().eval(script, bindings);
} catch (final ScriptException e) {
throw new UtilException(e);
}
}
/**
* 执行JS脚本中的指定方法
*
* @param script js脚本
* @param func 方法名
* @param args 方法参数
* @return 结果
* @since 5.3.6
*/
public static Object invoke(final String script, final String func, final Object... args) {
final Invocable eval = evalInvocable(script);
try {
return eval.invokeFunction(func, args);
} catch (final ScriptException | NoSuchMethodException e) {
throw new UtilException(e);
}
}
/**
* 编译Javascript脚本
*
* @param script 脚本内容
* @return {@link CompiledScript}
* @throws UtilException 脚本异常
* @since 3.2.0
*/
public static CompiledScript compile(final String script) throws UtilException {
try {
return compile(getJsEngine(), script);
} catch (final ScriptException e) {
throw new UtilException(e);
}
}
/**
* 编译Javascript脚本
*
* @param engine 引擎
* @param script 脚本内容
* @return {@link CompiledScript}
* @throws ScriptException 脚本异常
*/
public static CompiledScript compile(final ScriptEngine engine, final String script) throws ScriptException {
if (engine instanceof Compilable) {
final Compilable compEngine = (Compilable) engine;
return compEngine.compile(script);
}
return null;
}
}

View File

@@ -1,18 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* 使用Java对脚本引擎的工具封装
*
* @author looly
*/
package org.dromara.hutool.extra.script;

View File

@@ -12,10 +12,9 @@
package org.dromara.hutool.extra.tokenizer.engine.mynlp;
import com.mayabot.nlp.Mynlp;
import com.mayabot.nlp.segment.Lexer;
import com.mayabot.nlp.segment.Lexers;
import com.mayabot.nlp.segment.Sentence;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.tokenizer.Result;
import org.dromara.hutool.extra.tokenizer.TokenizerEngine;
@@ -35,7 +34,10 @@ public class MynlpEngine implements TokenizerEngine {
* 构造
*/
public MynlpEngine() {
this.lexer = Lexers.core();
// CORE分词器构建器
// 开启词性标注功能
// 开启人名识别功能
this.lexer = Mynlp.instance().bigramLexer();
}
/**

View File

@@ -10,6 +10,5 @@
# See the Mulan PSL v2 for more details.
#
org.dromara.hutool.extra.aop.proxy.CglibProxyFactory
org.dromara.hutool.extra.aop.proxy.SpringCglibProxyFactory
org.dromara.hutool.extra.aop.proxy.JdkProxyFactory

View File

@@ -1,39 +0,0 @@
package org.dromara.hutool.extra.script;
import org.dromara.hutool.core.exceptions.UtilException;
import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import javax.script.CompiledScript;
import javax.script.ScriptException;
/**
* 脚本单元测试类
*
* @author looly
*
*/
public class ScriptUtilTest {
@Test
public void compileTest() {
final CompiledScript script = ScriptUtil.compile("print('Script test!');");
try {
script.eval();
} catch (final ScriptException e) {
throw new UtilException(e);
}
}
@Test
public void evalTest() {
ScriptUtil.eval("print('Script test!');");
}
@Test
public void invokeTest() {
final Object result = ScriptUtil.invoke(ResourceUtil.readUtf8Str("filter1.js"), "filter1", 2, 1);
Assertions.assertTrue((Boolean) result);
}
}

View File

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