diff --git a/gradle.properties b/gradle.properties index 84ee40e7..8e81745b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,9 +36,9 @@ application_version=1.0.0 # platform ########################################################### platform_group=io.sc -platform_version=8.1.27 +platform_version=8.1.28 platform_plugin_version=8.1.13 -platform_core_frontend_version=8.1.145 +platform_core_frontend_version=8.1.149 ########################################################### # dependencies version diff --git a/io.sc.engine.rule.client.spring/gradle.properties b/io.sc.engine.rule.client.spring/gradle.properties new file mode 100644 index 00000000..e69de29b diff --git a/io.sc.engine.rule.client.spring/src/main/java/io/sc/engine/rule/client/spring/service/ExecutorFactoryService.java b/io.sc.engine.rule.client.spring/src/main/java/io/sc/engine/rule/client/spring/service/ExecutorFactoryService.java new file mode 100644 index 00000000..5b89b457 --- /dev/null +++ b/io.sc.engine.rule.client.spring/src/main/java/io/sc/engine/rule/client/spring/service/ExecutorFactoryService.java @@ -0,0 +1,14 @@ +package io.sc.engine.rule.client.spring.service; + +import io.sc.engine.rule.client.Executor; + +/** + * Spring 环境中的决策引擎执行器工厂服务类 + */ +public interface ExecutorFactoryService { + /** + * 获取执行器 + * @return 执行器 + */ + public Executor getExecutor(); +} diff --git a/io.sc.engine.rule.client.spring/src/main/java/io/sc/engine/rule/client/spring/service/impl/ExecutorFactoryServiceImpl.java b/io.sc.engine.rule.client.spring/src/main/java/io/sc/engine/rule/client/spring/service/impl/ExecutorFactoryServiceImpl.java new file mode 100644 index 00000000..fe719e82 --- /dev/null +++ b/io.sc.engine.rule.client.spring/src/main/java/io/sc/engine/rule/client/spring/service/impl/ExecutorFactoryServiceImpl.java @@ -0,0 +1,112 @@ +package io.sc.engine.rule.client.spring.service.impl; + +import java.util.Map; + +import javax.annotation.PostConstruct; + +import io.sc.platform.core.service.RuntimeService; +import io.sc.platform.mvc.service.SystemParameterService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; +import io.sc.engine.rule.client.Executor; +import io.sc.engine.rule.client.ExecutorBuilder; +import io.sc.engine.rule.client.enums.ExecutorMode; +import io.sc.engine.rule.client.enums.LoaderMode; +import io.sc.engine.rule.client.local.LocalExecutor; +import io.sc.engine.rule.client.spring.service.ExecutorFactoryService; +import io.sc.engine.rule.client.spring.service.LocalLoader; +import io.sc.engine.rule.client.spring.util.EngineSpringApplicationContextUtil; + +@Service("reExecutorFactoryService") +public class ExecutorFactoryServiceImpl implements ExecutorFactoryService{ + private static final Logger log =LoggerFactory.getLogger(ExecutorFactoryServiceImpl.class); + + private static final String EXECUTOR_MODE_KEY ="parameter.re.client.executorMode"; + private static final String LOADER_MODE_KEY ="parameter.re.client.loaderMode"; + private static final String REMOTE_API_URL_KEY ="parameter.re.client.remoteApiUrl"; + + @Autowired private RuntimeService runtimeService; + @Autowired private SystemParameterService systemParameterService; + @Autowired private LocalLoader localLoader; + @Autowired private ApplicationContext applicationContext; + + private ExecutorMode lastExecutorMode; //上一次保存的执行器执行模式 + private LoaderMode lastLoaderMode; //上一次保存的加载器执行模式 + private String lastRemoteApiUrl; //上一次保存的远程服务器 api url 地址 + + private Executor executor; + + @PostConstruct + public void init() { + try { + EngineSpringApplicationContextUtil.setApplicationContext(applicationContext); + executor =buildExecutor(); + } catch (Exception e) { + log.error("",e); + } + } + + @Override + public Executor getExecutor() { + if(!runtimeService.isReady()) { + return null; + } + if(executor!=null) return executor; + try { + Map parameters =systemParameterService.getParameters(new String[] { + EXECUTOR_MODE_KEY, + LOADER_MODE_KEY, + REMOTE_API_URL_KEY + }); + + ExecutorMode executorMode =ExecutorMode.parse(parameters.get(EXECUTOR_MODE_KEY)); + LoaderMode loaderMode =LoaderMode.parse(parameters.get(LOADER_MODE_KEY)); + String remoteApiUrl =parameters.get(REMOTE_API_URL_KEY); + + if( + executorMode!=null && executorMode.equals(lastExecutorMode) + && loaderMode!=null && loaderMode.equals(lastLoaderMode) + && remoteApiUrl!=null && remoteApiUrl.equals(lastRemoteApiUrl) + + ) { + return executor; + }else { + if(ExecutorMode.LOCAL.equals(executorMode) && LoaderMode.LOCAL.equals(loaderMode)) { + executor =new LocalExecutor(localLoader); + }else { + executor =new ExecutorBuilder().build(executorMode, loaderMode, remoteApiUrl); + } + lastExecutorMode =executorMode; + lastLoaderMode =loaderMode; + lastRemoteApiUrl =remoteApiUrl; + return executor; + } + } catch (Exception e) { + log.error("",e); + return null; + } + } + + private Executor buildExecutor() throws Exception{ + if(!runtimeService.isReady()) { + return null; + } + Map parameters =systemParameterService.getParameters(new String[] { + EXECUTOR_MODE_KEY, + LOADER_MODE_KEY, + REMOTE_API_URL_KEY + }); + + ExecutorMode executorMode =ExecutorMode.parse(parameters.get(EXECUTOR_MODE_KEY)); + LoaderMode loaderMode =LoaderMode.parse(parameters.get(LOADER_MODE_KEY)); + String remoteApiUrl =parameters.get(REMOTE_API_URL_KEY); + if(ExecutorMode.LOCAL.equals(executorMode) && LoaderMode.LOCAL.equals(loaderMode)) { + return new LocalExecutor(localLoader); + }else { + return new ExecutorBuilder().build(executorMode, loaderMode, remoteApiUrl); + } + } +} diff --git a/io.sc.engine.rule.client/gradle.properties b/io.sc.engine.rule.client/gradle.properties new file mode 100644 index 00000000..e69de29b diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/Executor.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/Executor.java new file mode 100644 index 00000000..af882050 --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/Executor.java @@ -0,0 +1,169 @@ +package io.sc.engine.rule.client; + +import java.util.Map; + +import io.sc.engine.rule.core.code.impl.support.ResourceResult; + +/** + * 客户端执行器接口 + */ +public interface Executor { + /** + * 编译资源 + * @param resourceId 资源唯一标识 + * @throws Exception 违例 + */ + public void compileById(String resourceId) throws Exception; + + /** + * 编译资源 + * @param resourceCode 资源代码 + * @param version 资源版本 + * @throws Exception 违例 + */ + public void compileByCode(String resourceCode,Integer version) throws Exception; + + /** + * 执行资源 + * @param resourceId 资源唯一标识 + * @param json 需要提交给资源的参数 json 字符串 + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeById(String resourceId,String json) throws Exception; + + /** + * 执行资源 + * @param resourceId 资源唯一标识 + * @param subModelCode 子模型代码 + * @param json 需要提交给资源的参数 json 字符串 + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeById(String resourceId,String subModelCode,String json) throws Exception; + + /** + * 执行资源 + * @param resourceId 资源唯一标识 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeById(String resourceId,Map map) throws Exception; + + /** + * 执行资源 + * @param resourceId 资源唯一标识 + * @param subModelCode 子模型代码 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeById(String resourceId,String subModelCode,Map map) throws Exception; + + /** + * 执行资源 + * @param resourceCode 资源代码 + * @param version 资源版本 + * @param json 需要提交给资源的参数 json 字符串 + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByCode(String resourceCode,Integer version,String json) throws Exception; + + /** + * 执行资源 + * @param resourceCode 资源代码 + * @param version 资源版本 + * @param subModelCode 子模型代码 + * @param json 需要提交给资源的参数 json 字符串 + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByCode(String resourceCode,Integer version,String subModelCode,String json) throws Exception; + + /** + * 执行资源 + * @param resourceCode 资源代码 + * @param version 资源版本 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByCode(String resourceCode,Integer version,Map map) throws Exception; + + /** + * 执行资源 + * @param resourceCode 资源代码 + * @param version 资源版本 + * @param subModelCode 子模型代码 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByCode(String resourceCode,Integer version,String subModelCode,Map map) throws Exception; + + + + + /** + * 编译资源(测试) + * @param resourceId 资源唯一标识 + * @throws Exception 违例 + */ + public void compileByIdForTest(String resourceId) throws Exception; + + /** + * 编译资源(测试) + * @param resourceCode 资源代码 + * @param version 资源版本 + * @throws Exception 违例 + */ + public void compileByCodeForTest(String resourceCode,Integer version) throws Exception; + + /** + * 执行资源(测试) + * @param resourceId 资源唯一标识 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByIdForTest(String resourceId,Map map) throws Exception; + + /** + * 执行资源(测试) + * @param resourceId 资源唯一标识 + * @param subModelCode 子模型代码 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByIdForTest(String resourceId,String subModelCode,Map map) throws Exception; + + /** + * 执行资源(测试) + * @param resourceCode 资源代码 + * @param version 资源版本 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByCodeForTest(String resourceCode,Integer version,Map map) throws Exception; + + /** + * 执行资源(测试) + * @param resourceCode 资源代码 + * @param version 资源版本 + * @param subModelCode 子模型代码 + * @param map 需要提交给资源的参数 map + * @return 执行结果 + * @throws Exception 违例 + */ + public ResourceResult executeByCodeForTest(String resourceCode,Integer version,String subModelCode,Map map) throws Exception; + + /** + * 获取资源定义加载器 + * @return 资源定义加载器 + */ + public Loader getLoader(); +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/ExecutorBuilder.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/ExecutorBuilder.java new file mode 100644 index 00000000..7c12ba06 --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/ExecutorBuilder.java @@ -0,0 +1,78 @@ +package io.sc.engine.rule.client; + +import io.sc.engine.rule.client.enums.ExecutorMode; +import io.sc.engine.rule.client.enums.LoaderMode; +import io.sc.engine.rule.client.local.LocalExecutor; +import io.sc.engine.rule.client.remote.RemoteExecutor; +import io.sc.engine.rule.client.remote.RemoteLoader; + +/** + * 执行器构建器 + */ +public class ExecutorBuilder { + private ExecutorMode executorMode =ExecutorMode.LOCAL; + private LoaderMode loaderMode =LoaderMode.REMOTE; + private String url; + + public ExecutorBuilder loader(LoaderMode loaderMode) { + this.loaderMode =loaderMode; + return this; + } + + public ExecutorBuilder executor(ExecutorMode executorMode) { + this.executorMode =executorMode; + return this; + } + + public ExecutorBuilder url(String url) { + this.url =url; + return this; + } + + /** + * 快捷构建执行器 + * @param executorMode 执行模式 + * @param loaderMode 模型定义加载模式 + * @param url 模型引擎服务器 url + * @return 执行器 + */ + public Executor build(ExecutorMode executorMode,LoaderMode loaderMode,String url) { + this.executorMode =executorMode; + this.loaderMode =loaderMode; + this.url =url; + return build(); + } + + /** + * 构建执行器 + * @return 执行器 + */ + public Executor build(){ + //检查组合是否有效 + //如果采用远程执行,必须指定 url + if(executorMode==ExecutorMode.REMOTE && (url==null || "".equals(url.trim()))) { + throw new RuntimeException("REMOTE executor mode MUST set the url"); + } + //如果采用远程加载模型定义,必须指定 url + if(loaderMode==LoaderMode.REMOTE && (url==null || "".equals(url.trim()))) { + throw new RuntimeException("REMOTE loader mode MUST set the url"); + } + //不支持本地执行,本地加载模型定义 + if(executorMode==ExecutorMode.LOCAL && loaderMode==LoaderMode.LOCAL) { + throw new RuntimeException("LOCAL loader and LOCAL executor NOT Supported!"); + } + + //只支持以下两种方式: + //1. 本地执行,远程加载模型定义 + if(loaderMode==LoaderMode.REMOTE && executorMode==ExecutorMode.LOCAL) { + return new LocalExecutor(new RemoteLoader(url)); + } + + //2. 远程执行 + if(executorMode==ExecutorMode.REMOTE) { + return new RemoteExecutor(url); + } + + return null; + } +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/ExecutorFactory.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/ExecutorFactory.java new file mode 100644 index 00000000..151bab05 --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/ExecutorFactory.java @@ -0,0 +1,29 @@ +package io.sc.engine.rule.client; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 执行器工厂,用于缓存执行器 + */ +public class ExecutorFactory { + private static Map cache =new ConcurrentHashMap(); + + /** + * 注册执行器 + * @param name 执行器名称 + * @param executor 执行器 + */ + public static void register(String name,Executor executor) { + cache.put(name, executor); + } + + /** + * 获取执行器 + * @param name 执行器名称 + * @return 执行器 + */ + public static Executor getExecutor(String name) { + return cache.get(name); + } +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/enums/ExecutorMode.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/enums/ExecutorMode.java new file mode 100644 index 00000000..c3a74464 --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/enums/ExecutorMode.java @@ -0,0 +1,18 @@ +package io.sc.engine.rule.client.enums; + +/** + * 执行器模式 + */ +public enum ExecutorMode { + LOCAL, //本地 + REMOTE; //远程 + + public static ExecutorMode parse(String str) { + if("LOCAL".equalsIgnoreCase(str)) { + return ExecutorMode.LOCAL; + }else if("REMOTE".equalsIgnoreCase(str)) { + return ExecutorMode.REMOTE; + } + return null; + } +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/GroovyEngineRuntime.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/GroovyEngineRuntime.java new file mode 100644 index 00000000..bfcf3b8f --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/GroovyEngineRuntime.java @@ -0,0 +1,145 @@ +package io.sc.engine.rule.client.runtime.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import io.sc.engine.rule.client.Executor; +import io.sc.engine.rule.client.runtime.EngineRuntime; +import io.sc.engine.rule.client.runtime.impl.groovy.GroovyScriptEngineService; +import io.sc.engine.rule.client.runtime.impl.groovy.GroovyScriptEngineServiceImpl; +import io.sc.engine.rule.core.code.CodeGenerator; +import io.sc.engine.rule.core.code.SourceCode; +import io.sc.engine.rule.core.code.impl.GroovySourceCodeGenerator; +import io.sc.engine.rule.core.code.impl.support.ResourceResult; +import io.sc.engine.rule.core.code.impl.support.ResourceWrapper; +import io.sc.engine.rule.core.code.impl.support.ResourceWrapper4Lib; +import io.sc.engine.rule.core.code.impl.support.ResourceWrapper4Resource; +import io.sc.engine.rule.core.po.lib.Lib; +import io.sc.engine.rule.core.po.resource.Resource; + +public class GroovyEngineRuntime extends EngineRuntime{ + private static final Logger log =LoggerFactory.getLogger(GroovyEngineRuntime.class); + private static GroovyEngineRuntime instance =new GroovyEngineRuntime(); + private GroovyScriptEngineService service =new GroovyScriptEngineServiceImpl(); + private CodeGenerator codeGenerator =new GroovySourceCodeGenerator(); + + private GroovyEngineRuntime() {} + + public static GroovyEngineRuntime getInstance() { + return instance; + } + + @Override + public void compileById(String resourceId, ResourceWrapper wrapper) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeById(resourceId, wrapper); + String resourceName =null; + if("RESOURCE".equals(wrapper.getType())){ + ResourceWrapper4Resource _wrapper =(ResourceWrapper4Resource)wrapper; + Resource resource =_wrapper.getResource(); + resourceName =resource.getName(); + }else if("LIB".equals(wrapper.getType())) { + ResourceWrapper4Lib _wrapper =(ResourceWrapper4Lib)wrapper; + Lib lib =_wrapper.getLib(); + resourceName =lib.getName(); + } + try { + service.validate(code.getSource()); + } catch (Exception e) { + log.error("Compile Error for " + resourceName + "(resourceId=" + resourceId + ")",e); + } + } + + @Override + public void compileByCode(String resourceCode, Integer version, ResourceWrapper wrapper) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeByCode(resourceCode, version, wrapper); + String resourceName =null; + if("RESOURCE".equals(wrapper.getType())){ + ResourceWrapper4Resource _wrapper =(ResourceWrapper4Resource)wrapper; + Resource resource =_wrapper.getResource(); + resourceName =resource.getName(); + }else if("LIB".equals(wrapper.getType())) { + ResourceWrapper4Lib _wrapper =(ResourceWrapper4Lib)wrapper; + Lib lib =_wrapper.getLib(); + resourceName =lib.getName(); + } + try { + service.validate(code.getSource()); + } catch (Exception e) { + log.error("Compile Error for " + resourceName + "(code=" + resourceCode + ",verion=" + version + ")",e); + } + } + + @Override + public ResourceResult executeById(Executor executor,String resourceId, ResourceWrapper wrapper, String json) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeById(resourceId,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,null,json)); + return result; + } + + @Override + public ResourceResult executeById(Executor executor,String resourceId, ResourceWrapper wrapper, String subModelCode, String json) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeById(resourceId,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,subModelCode,json)); + return result; + } + + @Override + public ResourceResult executeById(Executor executor,String resourceId, ResourceWrapper wrapper, Map map) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeById(resourceId,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,null,map)); + return result; + } + + @Override + public ResourceResult executeById(Executor executor,String resourceId, ResourceWrapper wrapper, String subModelCode, Map map) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeById(resourceId,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,subModelCode,map)); + return result; + } + + @Override + public ResourceResult executeByCode(Executor executor,String resourceCode, Integer version, ResourceWrapper wrapper, String json) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeByCode(resourceCode,version,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,null,json)); + return result; + } + + @Override + public ResourceResult executeByCode(Executor executor,String resourceCode, Integer version, ResourceWrapper wrapper, String subModelCode, String json) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeByCode(resourceCode,version,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,subModelCode,json)); + return result; + } + + @Override + public ResourceResult executeByCode(Executor executor,String resourceCode, Integer version, ResourceWrapper wrapper,Map map) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeByCode(resourceCode,version,wrapper); + //if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,null,map)); + return result; + } + + @Override + public ResourceResult executeByCode(Executor executor,String resourceCode, Integer version, ResourceWrapper wrapper, String subModelCode, Map map) throws Exception { + SourceCode code =codeGenerator.generateSourceCodeByCode(resourceCode,version,wrapper); + if(log.isDebugEnabled()) {log.debug("generated groovy source code:\n{}",code.getSource());} + ResourceResult result =(ResourceResult)service.eval(code.getSource(), "INPUT_PARAMETER", prepareParameter(executor,subModelCode,map)); + return result; + } + + private Map prepareParameter(Executor executor,String subModelCode, Object argument){ + Map parameter =new HashMap(2); + parameter.put("executor", executor); + parameter.put("subModelCode", subModelCode); + parameter.put("argument", argument); + return parameter; + } +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptEngineService.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptEngineService.java new file mode 100644 index 00000000..353d699b --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptEngineService.java @@ -0,0 +1,90 @@ +package io.sc.engine.rule.client.runtime.impl.groovy; + +import java.util.Map; + +import groovy.lang.Binding; + +/** + * Groovy 脚本执行引擎服务 + */ +public interface GroovyScriptEngineService { + /** + * 对脚本进行语法验证 + * @param script 需要验证的脚本内容 + * @return 是否验证通过 + * @throws Exception 违例 + */ + public boolean validate(String script) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @return 执行后的单值结果 + * @throws Exception 违例 + */ + public Object eval(String script) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @param key 传入的单值参数名称 + * @param value 传入的单值参数值 + * @return 执行后的单值结果 + * @throws Exception 违例 + */ + public Object eval(String script, String key, Object value) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @param context 传入参数集合 + * @return 执行后的单值结果 + * @throws Exception 违例 + */ + public Object eval(String script, Map context) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @param binding 传入参数 groovy binding 对象 + * @return 执行后的单值结果 + * @throws Exception 违例 + */ + public Object eval(String script, Binding binding) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @return 执行后的多值结果 + * @throws Exception 违例 + */ + public Map execute(String script) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @param key 传入的单值参数名称 + * @param value 传入的单值参数值 + * @return 执行后的多值结果 + * @throws Exception 违例 + */ + public Map execute(String script, String key, Object value) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @param context 传入参数集合 + * @return 执行后的多值结果 + * @throws Exception 违例 + */ + public Map execute(String script, Map context) throws Exception; + + /** + * 执行脚本 + * @param script 脚本内容 + * @param binding 传入参数 groovy binding 对象 + * @return 执行后的多值结果 + * @throws Exception 违例 + */ + public Map execute(String script, Binding binding) throws Exception; +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptEngineServiceImpl.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptEngineServiceImpl.java new file mode 100644 index 00000000..de1dab26 --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptEngineServiceImpl.java @@ -0,0 +1,54 @@ +package io.sc.engine.rule.client.runtime.impl.groovy; + +import java.util.Map; + +import groovy.lang.Binding; + +public class GroovyScriptEngineServiceImpl implements GroovyScriptEngineService{ + private GroovyScriptExecutor engine =new GroovyScriptExecutor(); + + @Override + public boolean validate(String script) throws Exception { + return engine.validate(script); + } + + @Override + public Object eval(String script) throws Exception { + return engine.eval(script); + } + + @Override + public Object eval(String script, String key, Object value) throws Exception { + return engine.eval(script,key,value); + } + + @Override + public Object eval(String script, Map context) throws Exception { + return engine.eval(script,context); + } + + @Override + public Object eval(String script, Binding binding) throws Exception { + return engine.eval(script,binding); + } + + @Override + public Map execute(String script) throws Exception { + return engine.execute(script); + } + + @Override + public Map execute(String script, String key, Object value) throws Exception { + return engine.execute(script,key,value); + } + + @Override + public Map execute(String script, Map context) throws Exception { + return engine.execute(script,context); + } + + @Override + public Map execute(String script, Binding binding) throws Exception { + return engine.execute(script,binding); + } +} diff --git a/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptExecutor.java b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptExecutor.java new file mode 100644 index 00000000..a3741265 --- /dev/null +++ b/io.sc.engine.rule.client/src/main/java/io/sc/engine/rule/client/runtime/impl/groovy/GroovyScriptExecutor.java @@ -0,0 +1,201 @@ +package io.sc.engine.rule.client.runtime.impl.groovy; + +import java.util.Map; + +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.SimpleBindings; + +import groovy.lang.Binding; + +/** + * Groovy 脚本执行引擎服务类 + */ +public class GroovyScriptExecutor { + private Compilable compilableEngine; + + public GroovyScriptExecutor(){ + ScriptEngineManager manager =new ScriptEngineManager(); + ScriptEngine engine =manager.getEngineByName("groovy"); + compilableEngine =(Compilable)engine; + } + + /** + * 编译验证 groovy 脚本的语法是否正确 + * @param script groovy 脚本 + * @return 是否通过编译验证 + * @throws Exception 违例 + */ + public boolean validate(String script) throws Exception{ + compilableEngine.compile(script); + return true; + } + + /** + * 执行 groovy 脚本(单返回值) + * @param script groovy 脚本 + * @return 执行结果 + * @throws Exception 违例 + */ + public Object eval(String script) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + return compiledScript.eval(); + } + return null; + } + + /** + * 执行 groovy 脚本(单参数,单返回值) + * @param script groovy 脚本 + * @param key 参数名 + * @param value 参数值 + * @return 执行结果 + * @throws Exception 违例 + */ + public Object eval(String script, String key, Object value) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + if(key!=null && !"".equals(key.trim())){ + bindings.put(key,value); + } + return compiledScript.eval(bindings); + } + return null; + } + + /** + * 执行 groovy 脚本(多参数,单返回值) + * @param script groovy 脚本 + * @param context 参数集合 + * @return 执行结果 + * @throws Exception 违例 + */ + public Object eval(String script, Map context) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + if(context!=null && context.size()>0){ + bindings.putAll(context); + } + return compiledScript.eval(bindings); + } + return null; + } + + /** + * 执行 groovy 脚本(单返回值) + * @param script script groovy 脚本 + * @param binding Groovy Bindings 对象 + * @return 执行结果 + * @throws Exception 违例 + */ + @SuppressWarnings("unchecked") + public Object eval(String script, Binding binding) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + if(binding!=null && binding.getVariables().size()>0){ + bindings.putAll(binding.getVariables()); + } + return compiledScript.eval(bindings); + } + return null; + } + + /** + * 执行 groovy 脚本(多返回值) + * @param script groovy 脚本 + * @return 执行结果 + * @throws Exception 违例 + */ + public Map execute(String script) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + compiledScript.eval(bindings); + return (Map)bindings; + } + return null; + } + + /** + * 执行 groovy 脚本(单参数,多返回值) + * @param script groovy 脚本 + * @param key 参数名 + * @param value 参数值 + * @return 执行结果 + * @throws Exception 违例 + */ + public Map execute(String script, String key, Object value) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + if(key!=null && !"".equals(key.trim())){ + bindings.put(key,value); + } + compiledScript.eval(bindings); + return (Map)bindings; + } + return null; + } + + /** + * 执行 groovy 脚本(多参数,多返回值) + * @param script groovy 脚本 + * @param context 参数集合 + * @return 执行结果 + * @throws Exception 违例 + */ + public Map execute(String script, Map context) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + if(context!=null){ + bindings.putAll(context); + } + compiledScript.eval(bindings); + return (Map)bindings; + } + return null; + } + + /** + * 执行 groovy 脚本(多返回值) + * @param script groovy 脚本 + * @param binding Groovy Bindings 对象 + * @return 执行结果 + * @throws Exception 违例 + */ + @SuppressWarnings("unchecked") + public Map execute(String script, Binding binding) throws Exception { + CompiledScript compiledScript =getCompiledScript(script); + if(compiledScript!=null){ + Bindings bindings =new SimpleBindings(); + if(binding!=null){ + bindings.putAll(binding.getVariables()); + } + compiledScript.eval(bindings); + return (Map)bindings; + } + return null; + } + + /** + * 编译 groovy 脚本 + * 由于 groovy 的 Compilable 实现已经实现了缓存编译后的脚本对象(即对相同的文本不会进行重复编译),所以应用无需进行缓存。 + * @param script 脚本文本字符串 + * @return 编译后的脚本对象 + * @throws Exception 违例 + */ + private CompiledScript getCompiledScript(String script) throws Exception{ + if(script!=null && !"".equals(script.trim())){ + return compilableEngine.compile(script); + } + return null; + } +} diff --git a/io.sc.engine.rule.core/gradle.properties b/io.sc.engine.rule.core/gradle.properties new file mode 100644 index 00000000..27039b2c --- /dev/null +++ b/io.sc.engine.rule.core/gradle.properties @@ -0,0 +1,3 @@ +commons_math3_version=3.6.1 +mxgraph_version=4.2.2.1 +jpmml_version=1.4.9 \ No newline at end of file diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/GroovySourceCodeGenerator.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/GroovySourceCodeGenerator.java new file mode 100644 index 00000000..a0c66ce8 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/GroovySourceCodeGenerator.java @@ -0,0 +1,126 @@ +package io.sc.engine.rule.core.code.impl; + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import io.sc.engine.rule.core.code.CodeGenerator; +import io.sc.engine.rule.core.code.SourceCode; +import io.sc.engine.rule.core.code.impl.support.ResourceWrapper; +import io.sc.engine.rule.core.code.impl.support.ResourceWrapper4Lib; +import io.sc.engine.rule.core.code.impl.support.ResourceWrapper4Resource; +import io.sc.engine.rule.core.enums.ResourceType; +import io.sc.engine.rule.core.po.lib.Lib; +import io.sc.engine.rule.core.po.resource.ModelResource; +import io.sc.engine.rule.core.po.resource.Resource; + +import freemarker.cache.ClassTemplateLoader; +import freemarker.ext.beans.BeansWrapper; +import freemarker.ext.beans.BeansWrapperBuilder; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateExceptionHandler; +import freemarker.template.TemplateHashModel; + +public class GroovySourceCodeGenerator implements CodeGenerator{ + private static final String PACKAGE_NAME ="io.sc.engine.rule.core.code.generated"; + private Map cache =new ConcurrentHashMap(); + + @Override + public SourceCode generateSourceCodeById(String resourceId, ResourceWrapper wrapper) throws Exception { + if(wrapper!=null) { + return _generateSourceCode(wrapper); + } + return null; + } + + @Override + public SourceCode generateSourceCodeByCode(String resourceCode, Integer version, ResourceWrapper wrapper) throws Exception { + if(wrapper!=null) { + if(version==null) { //未指定版本,不缓存 + return _generateSourceCode(wrapper); + }else { //指定了版本,缓存 + String key =getCacheKey(resourceCode,version); + SourceCode sourceCode =cache.get(key); + if(sourceCode==null) { + sourceCode =_generateSourceCode(wrapper); + cache.put(key, sourceCode); + return sourceCode; + }else { + return sourceCode; + } + } + } + return null; + } + + private SourceCode _generateSourceCode(ResourceWrapper wrapper) throws Exception{ + Configuration cfg = new Configuration(Configuration.VERSION_2_3_28); + cfg.setTemplateLoader(new ClassTemplateLoader(GroovySourceCodeGenerator.class,"/org/wsp/engine/rule/core/code/template/groovy")); + cfg.setDefaultEncoding("UTF-8"); + cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); + cfg.setLogTemplateExceptions(false); + cfg.setWrapUncheckedExceptions(true); + + Map root = new HashMap(); + + String wrapperCode =null; + if("RESOURCE".equals(wrapper.getType())){ + ResourceWrapper4Resource _wrapper =(ResourceWrapper4Resource)wrapper; + Resource resource =_wrapper.getResource(); + wrapperCode =resource.getCode(); + if(ResourceType.MODEL.equals(resource.getType())) { + ModelResource modelResource =(ModelResource)resource; + modelResource.getModel().buildFullName(); + } + }else if("LIB".equals(wrapper.getType())) { + ResourceWrapper4Lib _wrapper =(ResourceWrapper4Lib)wrapper; + Lib lib =_wrapper.getLib(); + wrapperCode =lib.getCode(); + } + + root.put("$wrapper", wrapper); + + root.put("CodeReplacer", getStaticMethod("io.sc.engine.rule.core.util.CodeReplacer")); + root.put("ExpressionReplacer", getStaticMethod("io.sc.engine.rule.core.util.ExpressionReplacer")); + root.put("ValueType", getStaticMethod("io.sc.engine.rule.core.enums.ValueType")); + + root.put("ConditionRange", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.ConditionRange")); + root.put("NumberRange", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.NumberRange")); + root.put("DecisionTable2C", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.DecisionTable2C")); + root.put("DecisionTable", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.DecisionTable")); + root.put("DecisionTree", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.DecisionTree")); + root.put("ExecutionFlow", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.ExecutionFlow")); + root.put("Option", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.Option")); + root.put("Rule", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.Rule")); + root.put("SingleRule", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.SingleRule")); + root.put("SqlFieldMapping", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.SqlFieldMapping")); + + root.put("LibUtil", getStaticMethod("io.sc.engine.rule.core.code.impl.support.lib.LibUtil")); + + + Template template =cfg.getTemplate("groovy.ftl"); + StringWriter out =new StringWriter(); + template.process(root, out); + out.close(); + return new SourceCode(PACKAGE_NAME,wrapperCode,out.toString()); + } + + private TemplateHashModel getStaticMethod(String className) throws Exception{ + BeansWrapper wrapper =new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build(); + TemplateHashModel staticModels = wrapper.getStaticModels(); + return (TemplateHashModel)staticModels.get(className); + } + + private String getCacheKey(String code,Integer version) { + String result =""; + if(code!=null && !"".equals(code.trim())) { + result +=code; + } + if(version!=null) { + result +="_" + version; + } + return result; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/FieldValidator.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/FieldValidator.java new file mode 100644 index 00000000..7b8d58dd --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/FieldValidator.java @@ -0,0 +1,161 @@ +package io.sc.engine.rule.core.code.impl.support; + +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 验证器 + * @author wangshaoping + * + */ +public class FieldValidator { + private static final Pattern EMAIL_PATTERN = Pattern.compile("[a-zA-Z0-9_\\\\-\\\\.]+@[a-zA-Z0-9]+(\\\\.(com))"); + + public static boolean empty(String fieldCode,String fieldName,Object obj,ValidateResult result) { + if(obj!=null) { + result.error(fieldCode,fieldName, "only null or empty string value can been accepted"); + return false; + } + return true; + } + + public static boolean notEmpty(String fieldCode,String fieldName,Object obj,ValidateResult result) { + if(obj==null) { + result.error(fieldCode,fieldName, "not null value can been accepted"); + return false; + } + if(obj instanceof String) { + if(obj.toString().isEmpty()) { + result.error(fieldCode,fieldName, "not empty string value can been accepted"); + return false; + } + } + return true; + } + + public static boolean trueValue(String fieldCode,String fieldName,Object obj,ValidateResult result) { + if(obj instanceof Boolean) { + if(!((Boolean)obj)) { + result.error(fieldCode,fieldName, "true value can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only boolean value can been accepted"); + return false; + } + + public static boolean falseValue(String fieldCode,String fieldName,Object obj,ValidateResult result) { + if(obj instanceof Boolean) { + if(((Boolean)obj)) { + result.error(fieldCode,fieldName, "false value can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only boolean value can been accepted"); + return false; + } + + public static boolean integerRange(String fieldCode,String fieldName,Object obj,Integer min,Integer max,ValidateResult result) { + if(obj instanceof Integer) { + if(min==null && max==null) { + return true; + } + Integer value =(Integer)obj; + if((min!=null && valuemax)) { + result.error(fieldCode,fieldName, "integer value between " + min + " and " + max + " can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only integer value can been accepted"); + return false; + } + + public static boolean decimalRange(String fieldCode,String fieldName,Object obj,Double min,Double max,ValidateResult result) { + if(obj instanceof Double) { + if(min==null && max==null) { + return true; + } + Double value =(Double)obj; + if((min!=null && valuemax)) { + result.error(fieldCode,fieldName, "double value between " + min + " and " + max + " can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only double value can been accepted"); + return false; + } + + public static boolean lengthRange(String fieldCode,String fieldName,Object obj,Integer min,Integer max,ValidateResult result) { + if(obj instanceof String) { + if(min==null && max==null) { + return true; + } + String value =(String)obj; + if((min!=null && value.length()max)) { + result.error(fieldCode,fieldName, "string value's length between " + min + " and " + max + " can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only string value can been accepted"); + return false; + } + + public static boolean dateRange(String fieldCode,String fieldName,Object obj,Date min,Date max,ValidateResult result) { + if(obj instanceof Date) { + if(min==null && max==null) { + return true; + } + Date value =(Date)obj; + if((min!=null && value.getTime()max.getTime())) { + result.error(fieldCode,fieldName, "date value's length between " + min + " and " + max + " can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only date value can been accepted"); + return false; + } + + public static boolean mail(String fieldCode,String fieldName,Object obj,ValidateResult result) { + if(obj instanceof String) { + String value =(String)obj; + Matcher m = EMAIL_PATTERN.matcher(value); + if(!m.matches()) { + result.error(fieldCode,fieldName, "only email address can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only string value can been accepted"); + return false; + } + + public static boolean pattern(String fieldCode,String fieldName,Object obj,String pattern,ValidateResult result) { + if(obj instanceof String) { + String value =(String)obj; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(value); + if(!m.matches()) { + result.error(fieldCode,fieldName, "only string value matched " + pattern + " pattern can been accepted"); + return false; + }else { + return true; + } + } + result.error(fieldCode,fieldName, "only string value can been accepted"); + return false; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpAuthorizationType.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpAuthorizationType.java new file mode 100644 index 00000000..e637579f --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpAuthorizationType.java @@ -0,0 +1,8 @@ +package io.sc.engine.rule.core.enums; + +public enum HttpAuthorizationType { + NONE, + API_KEY, + BASIC_AUTH, + BEARER +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpMethodType.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpMethodType.java new file mode 100644 index 00000000..e65bf74a --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpMethodType.java @@ -0,0 +1,10 @@ +package io.sc.engine.rule.core.enums; + +/** + * HTTP 请求方法类型 + * @author wangshaoping + * + */ +public enum HttpMethodType { + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/parser/ExecutionFlowParser.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/parser/ExecutionFlowParser.java new file mode 100644 index 00000000..f5ef9f29 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/parser/ExecutionFlowParser.java @@ -0,0 +1,185 @@ +package io.sc.engine.rule.core.mxgraph.parser; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.imageio.ImageIO; + +import org.w3c.dom.Document; +import io.sc.engine.rule.core.mxgraph.po.CommandSetNode; +import io.sc.engine.rule.core.mxgraph.po.ConditionNode; +import io.sc.engine.rule.core.mxgraph.po.ConfigurableResourceAbstractNode; +import io.sc.engine.rule.core.mxgraph.po.EdgeNode; +import io.sc.engine.rule.core.mxgraph.po.GraphNode; +import io.sc.engine.rule.core.mxgraph.po.ParallelNode; +import io.sc.engine.rule.core.mxgraph.po.ResourceAbstractNode; +import io.sc.engine.rule.core.mxgraph.po.StartNode; +import io.sc.engine.rule.core.mxgraph.po.SubModelAbstractNode; +import io.sc.engine.rule.core.mxgraph.support.ExecutionFlowMxGraph; + +import com.mxgraph.io.mxCodec; +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGraphModel; +import com.mxgraph.model.mxICell; +import com.mxgraph.util.mxCellRenderer; +import com.mxgraph.util.mxConstants; +import com.mxgraph.util.mxXmlUtils; +import com.mxgraph.view.mxGraph; + +/** + * 决策树解析器 + * @author wangshaoping + * + */ +public class ExecutionFlowParser { + /** + * 将 xml 解析成决策树对象,返回第一个有效节点 + * 使用者可通过该节点遍历整个决策树 + * @param xml mxgraph xml + * @return 决策树第一个有效节点 + */ + public GraphNode parse(String xml) { + Map nodes =parseNodes(xml); + return buildAndGetFirstEffectiveNode(nodes); + } + + /** + * 生成图片 + * @param xml mxgraph xml + * @param outputStream 输出流 + * @param format 图片格式 + * @throws IOException 违例 + */ + public synchronized void generateImage(String xml,OutputStream outputStream,String format) throws IOException { + Document doc = mxXmlUtils.parseXml(xml); + mxCodec codec = new mxCodec(doc); + mxGraphModel model =(mxGraphModel)codec.decode(doc.getDocumentElement()); + mxGraph graph = new ExecutionFlowMxGraph(model); + //graph.setHtmlLabels(true); + + //设置默认样式 + Map style = graph.getStylesheet().getDefaultVertexStyle(); + style.put(mxConstants.STYLE_GRADIENTCOLOR, "#FFFFFF"); + style.put(mxConstants.STYLE_ROUNDED, true); + style.put(mxConstants.STYLE_SHADOW, true); + + BufferedImage image = mxCellRenderer.createBufferedImage(graph, null,1, Color.WHITE, true, null); + if(image!=null) { + ImageIO.write(image, format, outputStream); + } + } + + private Map parseNodes(String xml){ + Document doc = mxXmlUtils.parseXml(xml); + mxCodec codec = new mxCodec(doc); + mxGraphModel model =(mxGraphModel)codec.decode(doc.getDocumentElement()); + mxCell root =(mxCell)model.getRoot(); //获取根( 标签对应的节点) + mxICell container =root.getChildAt(0);//.getChildAt(0); //获取包含自定义图形的容器 + Map result =new HashMap(); + int childCount =container.getChildCount(); + for(int i=0;i nodes) { + StartNode startNode =null; + for(String id : nodes.keySet()) { + GraphNode node =nodes.get(id); + if(node instanceof StartNode) { + startNode =(StartNode)node; + }else if(node instanceof EdgeNode) { + EdgeNode edgeNode =(EdgeNode)node; + String sourceId =edgeNode.getSourceId(); + String targetId =edgeNode.getTargetId(); + GraphNode source =nodes.get(sourceId); + GraphNode target =nodes.get(targetId); + if(source!=null) { + source.addOut(edgeNode); + edgeNode.addOut(target); + } + } + } + if(startNode!=null) { + List edges =startNode.getOuts(); + if(edges!=null && edges.size()>0) { + GraphNode edge =edges.get(0); + List outs =edge.getOuts(); + if(outs!=null && outs.size()>0) { + return outs.get(0); + } + } + } + return null; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/po/ExpressionNode.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/po/ExpressionNode.java new file mode 100644 index 00000000..0cc5993f --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/po/ExpressionNode.java @@ -0,0 +1,52 @@ +package io.sc.engine.rule.core.mxgraph.po; + +/** + * 表达式节点 + * @author wangshaoping + * + */ +public class ExpressionNode extends GraphNode{ + private String expression; //表达式 + private String commands; //附加指令 + + /** + * 获取表达式 + * @return 表达式 + */ + public String getExpression() { + return expression; + } + + /** + * 设置表达式 + * @param expression 表达式 + */ + public void setExpression(String expression) { + this.expression = expression; + } + + /** + * 获取附加指令 + * @return 附加指令 + */ + public String getCommands() { + return commands; + } + + /** + * 设置附加指令 + * @param commands 附加指令 + */ + public void setCommands(String commands) { + this.commands = commands; + } + + @Override + public String toString() { + return "ExpressionNode [id=" + id + + ", label=" + label + + ", expression=" + expression + + ", commands=" + commands + + ", outs=" + outs + "]"; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/po/GraphNode.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/po/GraphNode.java new file mode 100644 index 00000000..d6d96dba --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/mxgraph/po/GraphNode.java @@ -0,0 +1,82 @@ +package io.sc.engine.rule.core.mxgraph.po; + +import java.util.ArrayList; +import java.util.List; + +/** + * 节点 + * @author wangshaoping + * + */ +public class GraphNode { + public static final String START ="Start"; + public static final String CONDITION ="Condition"; + public static final String PARALLEL ="Parallel"; + public static final String EXPRESSION ="Expression"; + public static final String COMMAND_SET ="CommandSet"; + public static final String RESOURCE_ABSTRACT ="ResourceAbstract"; + public static final String CONFIGURABLE_RESOURCE_ABSTRACT ="ConfigurableResourceAbstract"; + public static final String SUB_MODEL_ABSTRACT ="SubModelAbstract"; + public static final String EDGE ="Edge"; + + protected String id; + protected String label; + + protected List outs =new ArrayList(); //出口列表 + + /** + * 添加出口节点 + * @param node 出口节点 + */ + public void addOut(GraphNode node) { + outs.add(node); + } + + /** + * 获取节点 ID + * @return 节点 ID + */ + public String getId() { + return id; + } + + /** + * 设置节点 ID + * @param id 节点 ID + */ + public void setId(String id) { + this.id = id; + } + + /** + * 获取节点显示名称 + * @return 节点显示名称 + */ + public String getLabel() { + return label; + } + + /** + * 设置节点显示名称 + * @param label 节点显示名称 + */ + public void setLabel(String label) { + this.label = label; + } + + /** + * 获取出口节点列表 + * @return 出口节点列表 + */ + public List getOuts() { + return outs; + } + + /** + * 设置出口节点列表 + * @param outs 出口节点列表 + */ + public void setOuts(List outs) { + this.outs = outs; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/FolderDictionary.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/FolderDictionary.java new file mode 100644 index 00000000..bd9f3a6d --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/FolderDictionary.java @@ -0,0 +1,10 @@ +package io.sc.engine.rule.core.po.dictionary; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeName("FOLDER") +@JsonIgnoreProperties(ignoreUnknown=true) +public class FolderDictionary extends Dictionary{ + +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/FolderLib.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/FolderLib.java new file mode 100644 index 00000000..65be955f --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/FolderLib.java @@ -0,0 +1,10 @@ +package io.sc.engine.rule.core.po.lib; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeName("FOLDER") +@JsonIgnoreProperties(ignoreUnknown=true) +public class FolderLib extends Lib{ + +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/processor/GroovyScriptIndicatorProcessor.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/processor/GroovyScriptIndicatorProcessor.java new file mode 100644 index 00000000..9cdc66bc --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/processor/GroovyScriptIndicatorProcessor.java @@ -0,0 +1,33 @@ +package io.sc.engine.rule.core.po.lib.processor; + +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.po.lib.IndicatorProcessor; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 指标处理器(脚本代码操作) + * @author wangshaoping + * + */ +@JsonTypeName("GROOVY_SCRIPT") +@JsonIgnoreProperties(ignoreUnknown=true) +public class GroovyScriptIndicatorProcessor extends IndicatorProcessor { + private String groovyScript;//脚本代码 + + @Override + public ProcessorType getType() { + return ProcessorType.GROOVY_SCRIPT; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } + + +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/processor/HttpRequestIndicatorProcessor.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/processor/HttpRequestIndicatorProcessor.java new file mode 100644 index 00000000..521f4979 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/processor/HttpRequestIndicatorProcessor.java @@ -0,0 +1,109 @@ +package io.sc.engine.rule.core.po.lib.processor; + +import io.sc.engine.rule.core.enums.HttpAuthorizationType; +import io.sc.engine.rule.core.enums.HttpMethodType; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.po.lib.IndicatorProcessor; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 指标处理器(SQL赋值操作) + * @author wangshaoping + * + */ +@JsonTypeName("HTTP_REQUEST") +@JsonIgnoreProperties(ignoreUnknown=true) +public class HttpRequestIndicatorProcessor extends IndicatorProcessor { + private HttpMethodType httpMethod; + private String httpUrl; + private HttpAuthorizationType httpAuthType; + private String httpAuthApikey; + private String httpAuthApiValue; + private String httpAuthApiAddTo; + private String httpAuthBasicUsername; + private String httpAuthBasicPassword; + private String httpAuthBearerToken; + private String httpParams; + private String httpBody; + private String httpResponseMapping; + + @Override + public ProcessorType getType() { + return ProcessorType.HTTP_REQUEST; + } + + public HttpMethodType getHttpMethod() { + return httpMethod; + } + public void setHttpMethod(HttpMethodType httpMethod) { + this.httpMethod = httpMethod; + } + public String getHttpUrl() { + return httpUrl; + } + public void setHttpUrl(String httpUrl) { + this.httpUrl = httpUrl; + } + public HttpAuthorizationType getHttpAuthType() { + return httpAuthType; + } + public void setHttpAuthType(HttpAuthorizationType httpAuthType) { + this.httpAuthType = httpAuthType; + } + public String getHttpAuthApikey() { + return httpAuthApikey; + } + public void setHttpAuthApikey(String httpAuthApikey) { + this.httpAuthApikey = httpAuthApikey; + } + public String getHttpAuthApiValue() { + return httpAuthApiValue; + } + public void setHttpAuthApiValue(String httpAuthApiValue) { + this.httpAuthApiValue = httpAuthApiValue; + } + public String getHttpAuthApiAddTo() { + return httpAuthApiAddTo; + } + public void setHttpAuthApiAddTo(String httpAuthApiAddTo) { + this.httpAuthApiAddTo = httpAuthApiAddTo; + } + public String getHttpAuthBasicUsername() { + return httpAuthBasicUsername; + } + public void setHttpAuthBasicUsername(String httpAuthBasicUsername) { + this.httpAuthBasicUsername = httpAuthBasicUsername; + } + public String getHttpAuthBasicPassword() { + return httpAuthBasicPassword; + } + public void setHttpAuthBasicPassword(String httpAuthBasicPassword) { + this.httpAuthBasicPassword = httpAuthBasicPassword; + } + public String getHttpAuthBearerToken() { + return httpAuthBearerToken; + } + public void setHttpAuthBearerToken(String httpAuthBearerToken) { + this.httpAuthBearerToken = httpAuthBearerToken; + } + public String getHttpParams() { + return httpParams; + } + public void setHttpParams(String httpParams) { + this.httpParams = httpParams; + } + public String getHttpBody() { + return httpBody; + } + public void setHttpBody(String httpBody) { + this.httpBody = httpBody; + } + public String getHttpResponseMapping() { + return httpResponseMapping; + } + public void setHttpResponseMapping(String httpResponseMapping) { + this.httpResponseMapping = httpResponseMapping; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/validator/FalseIndicatorValidator.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/validator/FalseIndicatorValidator.java new file mode 100644 index 00000000..a2d78690 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/lib/validator/FalseIndicatorValidator.java @@ -0,0 +1,21 @@ +package io.sc.engine.rule.core.po.lib.validator; + +import io.sc.engine.rule.core.enums.ValidatorType; +import io.sc.engine.rule.core.po.lib.IndicatorValidator; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 验证器(真) + * @author wangshaoping + * + */ +@JsonTypeName("FALSE") +@JsonIgnoreProperties(ignoreUnknown=true) +public class FalseIndicatorValidator extends IndicatorValidator { + @Override + public ValidatorType getType() { + return ValidatorType.FALSE; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/processor/GroovyScriptParameterProcessor.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/processor/GroovyScriptParameterProcessor.java new file mode 100644 index 00000000..c3a330b1 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/processor/GroovyScriptParameterProcessor.java @@ -0,0 +1,31 @@ +package io.sc.engine.rule.core.po.model.processor; + +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.po.model.ParameterProcessor; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 模型参数处理器(脚本代码操作) + * @author wangshaoping + * + */ +@JsonTypeName("GROOVY_SCRIPT") +@JsonIgnoreProperties(ignoreUnknown=true) +public class GroovyScriptParameterProcessor extends ParameterProcessor { + private String groovyScript;//脚本代码 + + @Override + public ProcessorType getType() { + return ProcessorType.GROOVY_SCRIPT; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/processor/HttpRequestParameterProcessor.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/processor/HttpRequestParameterProcessor.java new file mode 100644 index 00000000..47b5ac56 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/processor/HttpRequestParameterProcessor.java @@ -0,0 +1,109 @@ +package io.sc.engine.rule.core.po.model.processor; + +import io.sc.engine.rule.core.enums.HttpAuthorizationType; +import io.sc.engine.rule.core.enums.HttpMethodType; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.po.model.ParameterProcessor; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 模型参数处理器(Http请求操作) + * @author wangshaoping + * + */ +@JsonTypeName("HTTP_REQUEST") +@JsonIgnoreProperties(ignoreUnknown=true) +public class HttpRequestParameterProcessor extends ParameterProcessor { + private HttpMethodType httpMethod; + private String httpUrl; + private HttpAuthorizationType httpAuthType; + private String httpAuthApikey; + private String httpAuthApiValue; + private String httpAuthApiAddTo; + private String httpAuthBasicUsername; + private String httpAuthBasicPassword; + private String httpAuthBearerToken; + private String httpParams; + private String httpBody; + private String httpResponseMapping; + + @Override + public ProcessorType getType() { + return ProcessorType.HTTP_REQUEST; + } + + public HttpMethodType getHttpMethod() { + return httpMethod; + } + public void setHttpMethod(HttpMethodType httpMethod) { + this.httpMethod = httpMethod; + } + public String getHttpUrl() { + return httpUrl; + } + public void setHttpUrl(String httpUrl) { + this.httpUrl = httpUrl; + } + public HttpAuthorizationType getHttpAuthType() { + return httpAuthType; + } + public void setHttpAuthType(HttpAuthorizationType httpAuthType) { + this.httpAuthType = httpAuthType; + } + public String getHttpAuthApikey() { + return httpAuthApikey; + } + public void setHttpAuthApikey(String httpAuthApikey) { + this.httpAuthApikey = httpAuthApikey; + } + public String getHttpAuthApiValue() { + return httpAuthApiValue; + } + public void setHttpAuthApiValue(String httpAuthApiValue) { + this.httpAuthApiValue = httpAuthApiValue; + } + public String getHttpAuthApiAddTo() { + return httpAuthApiAddTo; + } + public void setHttpAuthApiAddTo(String httpAuthApiAddTo) { + this.httpAuthApiAddTo = httpAuthApiAddTo; + } + public String getHttpAuthBasicUsername() { + return httpAuthBasicUsername; + } + public void setHttpAuthBasicUsername(String httpAuthBasicUsername) { + this.httpAuthBasicUsername = httpAuthBasicUsername; + } + public String getHttpAuthBasicPassword() { + return httpAuthBasicPassword; + } + public void setHttpAuthBasicPassword(String httpAuthBasicPassword) { + this.httpAuthBasicPassword = httpAuthBasicPassword; + } + public String getHttpAuthBearerToken() { + return httpAuthBearerToken; + } + public void setHttpAuthBearerToken(String httpAuthBearerToken) { + this.httpAuthBearerToken = httpAuthBearerToken; + } + public String getHttpParams() { + return httpParams; + } + public void setHttpParams(String httpParams) { + this.httpParams = httpParams; + } + public String getHttpBody() { + return httpBody; + } + public void setHttpBody(String httpBody) { + this.httpBody = httpBody; + } + public String getHttpResponseMapping() { + return httpResponseMapping; + } + public void setHttpResponseMapping(String httpResponseMapping) { + this.httpResponseMapping = httpResponseMapping; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/validator/FalseParameterValidator.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/validator/FalseParameterValidator.java new file mode 100644 index 00000000..09a14e06 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/validator/FalseParameterValidator.java @@ -0,0 +1,17 @@ +package io.sc.engine.rule.core.po.model.validator; + +import io.sc.engine.rule.core.po.model.ParameterValidator; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 验证器(真) + * @author wangshaoping + * + */ +@JsonTypeName("FALSE") +@JsonIgnoreProperties(ignoreUnknown=true) +public class FalseParameterValidator extends ParameterValidator { + +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/resource/FolderResource.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/resource/FolderResource.java new file mode 100644 index 00000000..637bb980 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/resource/FolderResource.java @@ -0,0 +1,15 @@ +package io.sc.engine.rule.core.po.resource; + +import io.sc.engine.rule.core.enums.ResourceType; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeName("FOLDER") +@JsonIgnoreProperties(ignoreUnknown=true) +public class FolderResource extends Resource{ + @Override + public ResourceType getType() { + return ResourceType.FOLDER; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ExpressionReplacer.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ExpressionReplacer.java new file mode 100644 index 00000000..ad4b953f --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ExpressionReplacer.java @@ -0,0 +1,190 @@ +package io.sc.engine.rule.core.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import io.sc.engine.rule.core.enums.ValueType; + +public class ExpressionReplacer { + /** + * 转为 groovy 脚本时变量所属参数名 + */ + public static final String ARGUMENT_NAME ="arg"; + + /** + * 占位符正则表达式 + * 采用非贪婪模式匹配 + * 标记了两个组: + * 第一个组: ${xxx}, + * 第二个组: xxx + */ + private static final Pattern PLACE_HOLDER_REGEX_PATTERN =Pattern.compile("(\\$\\{(.+?)\\})"); //${xxxx} + private static final Pattern PLACE_HOLDER_REGEX_PATTERN2 =Pattern.compile("(`(.+?)`)"); //`xxxx` + private static final Pattern VAR_NAME_REGEX_PATTERN =Pattern.compile("([A-Za-z0-9_]+)"); //变量名正则表达式: + //private static final String VAR_FIELD_NAME_REGEX ="([A-Za-z0-9_]+\\.[A-Za-z0-9_]+)"; //字段名正则表达式: a.b + + /** + * 生成占位符字符串 + * @param varName 变量名 + * @param fieldName 字段名 + * @return 占位符字符串 + */ + public static String placeholder(String varName,String fieldName) { + if(varName!=null) { + if(fieldName!=null) { + return "${" + varName + "." + fieldName + "}"; + }else { + return "${" + varName + "}"; + } + } + return null; + } + + /** + * 替换字符串 + * @param expression 表达式 + * @param target 被替换的字符串 + * @param replacement 替换后的自妇产 + * @return 替换后的字符串 + */ + public static String replace(String expression,String target,String replacement) { + if(expression!=null && !expression.trim().isEmpty() && replacement!=null && !replacement.trim().isEmpty()) { + expression =expression.replace(target,replacement); + } + return expression; + } + + /** + * 替换字符串 + * @param expression 表达式 + * @param mapping 被替换和替换字符串 Map(key:被替换的字符串;value:替换后的字符串) + * @return 替换后的字符串 + */ + public static String replace(String expression,Map mapping) { + if(expression!=null && !expression.trim().isEmpty() && mapping!=null && mapping.size()>0) { + for(String key : mapping.keySet()) { + expression =expression.replace(key,mapping.get(key)); + } + return expression; + } + return expression; + } + + /** + * 将表达式转换为 groovy 可执行的脚本代码 + * groovy("${xxx} + ${yyy}", "java.lang.String");//结果: """${arg.xxx} + ${arg.yyy}""" + * groovy("${xxx} + ${yyy}", "java.lang.Double");//结果: arg.xxx + arg.yyy + * groovy("`${xxx} + ${yyy}`", "java.lang.String");//结果: """${arg.xxx + arg.yyy}""" + * groovy("`max(${xxx},${yyy})`", "java.lang.String");//结果: """${max(arg.xxx,arg.yyy)}""" + * @param expression 表达式 + * @param valueType 表达式返回值类型 + * @return groovy 可执行的脚本代码 + */ + public static String groovy(String expression,String valueType) { + if(expression==null) return null; + if(ValueType.String.getJavaType().equals(valueType)) { + //查找占位符模式(`xxx`) + Matcher matcher =PLACE_HOLDER_REGEX_PATTERN2.matcher(expression); + Map founds =new HashMap(); + while (matcher.find()) { + founds.put(matcher.group(1),matcher.group(2)); + } + String result =expression; + if(founds!=null && founds.size()>0) {//1) 先处理 `xxxx` 里面的内容,将其中的 ${yyyy} 进行替换 + for(String placeholder : founds.keySet()) { + String _expression =founds.get(placeholder); + _expression =replaceHolder(_expression,null,null); + result =result.replace(placeholder, "`" + _expression + "`"); + } + } + //2)再对其他 ${zzzz} 形式的字符串进行替换 + result =replaceHolder(result,"${","}"); + //最后把 1) 替换后的字符再次替换 + Matcher matcher2 =PLACE_HOLDER_REGEX_PATTERN2.matcher(result); + Map founds2 =new HashMap(); + while (matcher2.find()) { + founds2.put(matcher2.group(1),matcher2.group(2)); + } + if(founds2!=null && founds2.size()>0) { + for(String placeholder : founds2.keySet()) { + String _expression =founds2.get(placeholder); + result =result.replace(placeholder, "${" + _expression + "}"); + } + } + return "\"\"\"" + result + "\"\"\""; + }else { + return replaceHolder(expression,null,null); + } + } + + public static String groovyWithNoArgumentName(String expression,String valueType) { + if(expression==null) return null; + + //查找占位符模式 + Matcher matcher =PLACE_HOLDER_REGEX_PATTERN.matcher(expression); + Map founds =new HashMap(); + while (matcher.find()) { + founds.put(matcher.group(1),matcher.group(2)); + } + + if(ValueType.String.getJavaType().equals(valueType)) { + String result =expression; + if(founds!=null && founds.size()>0) { + for(String placeholder : founds.keySet()) { + String _expression =founds.get(placeholder); + result =result.replace(placeholder, _replace(_expression)); + } + } + return "\"" + result + "\""; + }else { + String result =expression; + if(founds!=null && founds.size()>0) { + for(String placeholder : founds.keySet()) { + String _expression =founds.get(placeholder); + result =result.replace(placeholder, _replace(_expression)); + } + } + return result; + } + } + + private static String replaceHolder(String expression,String wrapperPrefix,String wrapperSufix) { + if(expression==null) return null; + if(wrapperPrefix==null) wrapperPrefix =""; + if(wrapperSufix==null) wrapperSufix =""; + + //查找占位符模式(${xxx}) + Matcher matcher =PLACE_HOLDER_REGEX_PATTERN.matcher(expression); + Map founds =new HashMap(); + while (matcher.find()) { + founds.put(matcher.group(1),matcher.group(2)); + } + + String result =expression; + if(founds!=null && founds.size()>0) { + for(String placeholder : founds.keySet()) { + String _expression =founds.get(placeholder); + result =result.replace(placeholder, wrapperPrefix + ARGUMENT_NAME + "." + _replace(_expression) + wrapperSufix); + } + } + return result; + } + + private static String _replace(String expression) { + if(expression==null) return null; + + Matcher matcher =VAR_NAME_REGEX_PATTERN.matcher(expression); + List founds =new ArrayList(); + while (matcher.find()) { + founds.add(matcher.group(1)); + } + for(String found : founds) { + expression =expression.replace(found, CodeReplacer.varName(found)); + } + return expression; + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/FileUtil.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/FileUtil.java new file mode 100644 index 00000000..234a1f86 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/FileUtil.java @@ -0,0 +1,635 @@ +package io.sc.engine.rule.core.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class FileUtil { + private static final String NEW_LINE ="\n"; + private static final String DEFAULT_ENCODING ="UTF-8"; + + /** + * 向一个文本文件追加文本内容,采用默认字符编码 + * @param fileName 文件名 + * @param content 追加的内容 + * @throws Exception 违例 + */ + public static synchronized void append(String fileName,String content) throws Exception{ + append(fileName,content,DEFAULT_ENCODING); + } + + /** + * 向一个文本文件追加文本内容,采用指定的字符编码 + * @param fileName 文件名 + * @param content 追加的内容 + * @param encoding 追加内容字符编码 + * @throws Exception 违例 + */ + public static synchronized void append(String fileName,String content,String encoding) throws Exception{ + RandomAccessFile raf =null; + FileChannel fc =null; + try { + raf =new RandomAccessFile(fileName,"rw"); + fc =raf.getChannel(); + ByteBuffer bb =ByteBuffer.wrap(content.getBytes(encoding)); + fc.position(fc.size()); + fc.write(bb); + } catch (Exception e) { + throw e; + }finally{ + if(fc!=null){ + fc.close(); + } + if(raf!=null){ + raf.close(); + } + fc =null; + raf =null; + } + } + + /** + * 向一个文本文件追加文本内容,采用默认字符编码 + * @param fileName 文件名 + * @param content 追加的内容 + * @param header 文件头内容 + * @param tail 文件尾内容 + * @throws Exception 违例 + */ + public static synchronized void append(String fileName,String content,String header,String tail) throws Exception{ + append(fileName,content,header,tail,DEFAULT_ENCODING); + } + + /** + * 向一个文本文件追加文本内容 + * @param fileName 文件名 + * @param content 追加的内容 + * @param header 文件头内容 + * @param tail 文件尾内容 + * @param encoding 追加内容字符编码 + * @throws Exception 违例 + */ + public static synchronized void append(String fileName,String content,String header,String tail,String encoding) throws Exception{ + RandomAccessFile raf =null; + FileChannel fc =null; + boolean isNewFile =false; + try { + raf =new RandomAccessFile(fileName,"rw"); + fc =raf.getChannel(); + if(fc.size()==0){ + isNewFile =true; + } + ByteBuffer bb =ByteBuffer.wrap((content+tail).getBytes(encoding)); + if(isNewFile){ + fc.write(ByteBuffer.wrap(header.getBytes(encoding))); + fc.write(bb); + }else{ + fc.position(fc.size()-tail.getBytes(encoding).length); + fc.write(bb); + } + + } catch (Exception e) { + throw e; + }finally{ + if(fc!=null){ + fc.close(); + } + if(raf!=null){ + raf.close(); + } + fc =null; + raf =null; + } + } + + /** + * 读取一个文本文件的字符内容 + * @param file 文件名 + * @return 文件内容 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(String file) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + return readString(file,DEFAULT_ENCODING); + } + + /** + * 读取一个文本文件的字符内容 + * @param file 文件名 + * @param encoding 文件字符编码 + * @return 文件内容 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(String file,String encoding) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + return readString(new File(file),encoding); + } + + /** + * 从文本文件中读取所有文本 + * @param file 文件对象 + * @return 文件内容 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(File file) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + return readString(new FileInputStream(file),DEFAULT_ENCODING); + } + + /** + * 读取一个文本文件的字符内容 + * @param file 文件名 + * @param encoding 文件字符编码 + * @param newLine 文本换行符 + * @return 文件内容 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(String file,String encoding,String newLine) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + return readString(new File(file),encoding,newLine); + } + + /** + * 从文本文件中读取所有文本 + * @param file 文件对象 + * @param encoding 文件字符编码 + * @return 文件内容 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(File file,String encoding) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + return readString(new FileInputStream(file),encoding); + } + + /** + * 从文本文件中读取所有文本 + * @param file 文件对象 + * @param encoding 文件字符编码 + * @param newLine 换行符 + * @return 文件内容 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(File file,String encoding,String newLine) throws UnsupportedEncodingException,IOException{ + return readString(new FileInputStream(file),encoding,newLine); + } + + /** + * 从文本输入流中读取所有文本 + * @param inputstream 文本输入流 + * @return 输入流中文本内容 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(InputStream inputstream) throws UnsupportedEncodingException,IOException{ + return readString(inputstream,DEFAULT_ENCODING,NEW_LINE); + } + + /** + * 从文本输入流中读取所有文本 + * @param inputstream 文本输入流 + * @param encoding 文件字符编码 + * @return 输入流中文本内容 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(InputStream inputstream,String encoding) throws UnsupportedEncodingException,IOException{ + return readString(inputstream,encoding,NEW_LINE); + } + + /** + * 从文本输入流中读取所有文本 + * @param inputstream 文本输入流 + * @param encoding 文件字符编码 + * @param newLine 换行符 + * @return 输入流中文本内容 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(InputStream inputstream,String encoding,String newLine) throws UnsupportedEncodingException,IOException{ + return readString(inputstream,encoding,NEW_LINE,true); + } + + /** + * 从文本输入流中读取所有文本 + * @param inputstream 文本输入流 + * @param encoding 文件字符编码 + * @param newLine 换行符 + * @param isCloseInputStream 读取完毕后是否关闭输入流 + * @return 输入流中文本内容 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static String readString(InputStream inputstream,String encoding,String newLine,boolean isCloseInputStream) throws UnsupportedEncodingException,IOException{ + StringBuilder sb = new StringBuilder(); + BufferedReader br =null; + try { + br = new BufferedReader(new InputStreamReader(inputstream,encoding)); + String dataLine = ""; + while (null != (dataLine = br.readLine())){ + sb.append(dataLine); + sb.append(newLine==null?NEW_LINE:newLine); + } + return sb.toString(); + } catch (UnsupportedEncodingException e) { + throw e; + } catch (IOException e) { + throw e; + }finally{ + sb =null; + if(isCloseInputStream){ + if(br!=null){ + try { + br.close(); + } catch (IOException e) {} + } + } + } + } + + /** + * 采用默认字符编码从文件中读取所有文本列表,列表中每个元素为一行 + * @param file 文件名 + * @return 所有文本列表 + * @throws IOException 违例 + */ + public static List readStringAsList(String file) throws IOException{ + return readStringAsList(new File(file),DEFAULT_ENCODING); + } + + /** + * 采用指定字符编码从文件中读取所有文本列表,列表中每个元素为一行 + * @param file 文件名 + * @param encoding 字符编码 + * @return 所有文本列表 + * @throws IOException 违例 + */ + public static List readStringAsList(String file,String encoding) throws IOException{ + return readStringAsList(new File(file),encoding); + } + + /** + * 采用默认字符编码从文件中读取所有文本列表,列表中每个元素为一行 + * @param file 文件对象 + * @return 所有文本列表 + * @throws IOException 违例 + */ + public static List readStringAsList(File file) throws IOException{ + return readStringAsList(new FileInputStream(file),DEFAULT_ENCODING); + } + + /** + * 采用指定字符编码从文件中读取所有文本列表,列表中每个元素为一行 + * @param file 文件对象 + * @param encoding 字符编码 + * @return 所有文本列表 + * @throws IOException 违例 + */ + public static List readStringAsList(File file,String encoding) throws IOException{ + return readStringAsList(new FileInputStream(file),encoding); + } + + /** + * 采用默认字符编码从文本输入流中读取所有文本列表,列表中每个元素为一行 + * @param inputstream 文本输入流 + * @return 所有文本列表 + * @throws IOException 违例 + */ + public static List readStringAsList(InputStream inputstream) throws IOException{ + return readStringAsList(inputstream,DEFAULT_ENCODING); + } + + /** + * 采用指定字符编码从文本输入流中读取所有文本列表,列表中每个元素为一行 + * @param inputstream 文本输入流 + * @param encoding 字符编码 + * @return 所有文本列表 + * @throws IOException 违例 + */ + public static List readStringAsList(InputStream inputstream,String encoding) throws IOException{ + List result =new ArrayList(); + BufferedReader br =null; + try { + br = new BufferedReader(new InputStreamReader(inputstream,encoding)); + String dataLine = ""; + while (null != (dataLine = br.readLine())){ + result.add(dataLine); + } + return result; + } catch (IOException e) { + throw e; + }finally{ + if(br!=null){ + try { + br.close(); + } catch (IOException e) {} + } + } + } + + /** + * 读取文件最后多行数 + * @param filename 文件名 + * @param row 行数 + * @return 文件最后多行数 + * @throws Exception 违例 + */ + public static String readStringAsLastRow(String filename,int row) throws Exception{ + return readStringAsLastRow(new File(filename),row); + } + + /** + * 读取文件最后行数 + * @param file 文件名 + * @param row 行数 + * @return 文件最后行数 + * @throws Exception 违例 + */ + public static String readStringAsLastRow(File file,int row) throws Exception{ + RandomAccessFile rf =null; + try { + rf = new RandomAccessFile(file, "r"); + long len = rf.length(); + if (len == 0) { + return ""; + } + int _row = 0; + while (len > 0 && _row < row) { + len--; + rf.seek(len); + if (rf.readByte() == '\n') { + //pos=rf.getFilePointer(); + _row++; + } + } + StringBuffer buffer = new StringBuffer(); + String str = ""; + while ((str = rf.readLine()) != null) { + buffer.append(new String(str.getBytes("ISO-8859-1"),"UTF-8")).append("\n"); + } + return buffer.toString(); + } catch (Exception e) { + throw e; + } finally{ + if(rf!=null){ + rf.close(); + } + } + } + + /** + * 将字符串以默认编码写入指定的文件中 + * @param file 文件名 + * @param content 写入内容 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static void writeString(String file,String content) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + writeString(file,content,DEFAULT_ENCODING); + } + + /** + * 将字符串以特定编码写入指定的文件中 + * @param file 文件名 + * @param content 写入内容 + * @param encoding 内容编码 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + public static void writeString(String file,String content,String encoding) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + writeString(new File(file),content,encoding); + } + + /** + * 将字符串以特定编码写入指定的文件中 + * @param file 文件对象 + * @param content 写入内容 + * @param encoding 内容编码 + * @throws FileNotFoundException 违例 + * @throws UnsupportedEncodingException 违例 + * @throws IOException 违例 + */ + + public static void writeString(File file,String content,String encoding) throws FileNotFoundException,UnsupportedEncodingException,IOException{ + OutputStreamWriter writer =null; + try { + writer =new OutputStreamWriter(new FileOutputStream(file),encoding); + writer.write(content); + } catch (UnsupportedEncodingException e) { + throw e; + } catch (FileNotFoundException e) { + throw e; + } catch (IOException e) { + throw e; + }finally{ + if(writer!=null){ + try { + writer.close(); + } catch (IOException e) {} + } + } + } + + /** + * 获取某个目录下的所有扩展名为includes的文件 + * @param dir 路径 + * @param includes 扩展名数组 + * @return 所有文件集合 + */ + public static List listAllFile(File dir,String[] includes){ + List result =new ArrayList(); + File[] files =dir.listFiles(); + if(files!=null && files.length>0) { + for(int i=0;i() { + @Override + public int compare(File o1, File o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + return result; + } + + /** + * 移除目录路径的最后分隔符 + * @param path 目录路径 + * @return 无文件分隔符的文件路径 + */ + public static String removePathEndSeparator(String path){ + char lastChar =path.charAt(path.length()-1); + while(lastChar=='\\' || lastChar=='/'){ + path =path.substring(0,path.length()-1); + lastChar =path.charAt(path.length()-1); + } + return path; + } + + /** + * 创建目录,可同时创建多级目录 + * @param dir 目录路径能够 + */ + public static void mkdirs(String dir){ + File file =new File(dir); + if(!file.exists()){ + file.mkdirs(); + } + } + + /** + * 递归删除文件夹及其子文件 + * @param dir 文件夹 + */ + public static void deldirs(String dir){ + deldirs(new File(dir)); + } + + /** + * 递归删除文件夹及其子文件 + * @param dir 文件夹 + */ + public static void deldirs(File dir){ + if(dir.isDirectory()){ + File[] files =dir.listFiles(); + if(files!=null && files.length>0){ + for(File file : files){ + deldirs(file); + } + } + dir.delete(); + }else{ + dir.delete(); + } + } + + /** + * 拷贝文件 + * @param src 源文件 + * @param target 目标文件 + * @throws IOException 违例 + */ + public static void copyFile(InputStream src,String target) throws IOException{ + copyFile(src,new File(target)); + } + + /** + * 拷贝文件 + * @param src 源输入流 + * @param target 目标文件对象 + * @throws IOException 违例 + */ + public static void copyFile(InputStream src,File target) throws IOException{ + File parentFile =target.getParentFile(); + if(!parentFile.exists()){ + parentFile.mkdirs(); + } + OutputStream os =null; + byte[] buf = new byte[1024]; + try { + os = new FileOutputStream(target); + int read =-1; + while ((read = src.read(buf)) != -1) { + os.write(buf, 0, read); + } + } catch (IOException e) { + throw e; + } finally{ + try{if(src!=null)src.close();}catch(Exception e){throw new IOException(e);} + try{if(os!=null)os.close();}catch(Exception e){throw new IOException(e);} + buf =null; + } + } + + /** + * 拷贝文件 + * @param src 源输入流 + * @param os 目标输出流 + * @throws IOException 违例 + */ + public static void copyFile(InputStream src,OutputStream os) throws IOException{ + byte[] buf = new byte[1024]; + try { + int read =-1; + while ((read = src.read(buf)) != -1) { + os.write(buf, 0, read); + } + } catch (IOException e) { + throw e; + } finally{ + try{if(src!=null)src.close();}catch(Exception e){throw new IOException(e);} + try{if(os!=null)os.close();}catch(Exception e){throw new IOException(e);} + buf =null; + } + } + + /** + * 拷贝文件 + * @param src 源文件对象 + * @param target 目标文件对象 + * @throws IOException 违例 + */ + public static void copyFile(File src,File target) throws IOException{ + if(!target.getParentFile().exists()){ + target.getParentFile().mkdirs(); + } + InputStream is =new FileInputStream(src); + OutputStream os =new FileOutputStream(target); + byte[] buf = new byte[40960]; + int read =-1; + try { + while ((read = is.read(buf)) != -1) { + os.write(buf, 0, read); + } + } catch (IOException e) { + throw e; + } finally{ + try{if(is!=null)is.close();}catch(Exception e){throw new IOException(e);} + try{if(os!=null)os.close();}catch(Exception e){throw new IOException(e);} + buf =null; + } + } + + /** + * 拷贝文件 + * @param src 源文件 + * @param target 目标文件 + * @throws IOException 违例 + */ + public static void copyFile(String src,String target) throws IOException{ + copyFile(new File(src),new File(target)); + } +} diff --git a/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/HttpRequestUtil.java b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/HttpRequestUtil.java new file mode 100644 index 00000000..8b5dbf88 --- /dev/null +++ b/io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/HttpRequestUtil.java @@ -0,0 +1,227 @@ +package io.sc.engine.rule.core.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.Map; + +/** + * 简单 HTTP 请求工具类 + * @author wangshaoping + * + */ +public class HttpRequestUtil { + /** + * 发送 GET 请求 + * @param url 请求URL + * @return 返回结果 + * @throws Exception 违例 + */ + public static String get(String url) throws Exception{ + return get(url,""); + } + + /** + * 发送 GET 请求 + * @param url 请求URL + * @param key 参数名 + * @param value 参数值 + * @return 返回结果 + * @throws Exception 违例 + */ + public static String get(String url,String key,String value) throws Exception{ + if(key!=null && key.trim().length()>0) { + if(value!=null && value.length()>0) { + return get(url,key + "=" + URLEncoder.encode(value, "UTF-8")); + }else { + return get(url,key + "="); + } + } + return get(url); + } + + + /** + * 发送 GET 请求 + * @param url 请求URL + * @param parameters 请求参数 + * @return 返回结果 + * @throws Exception 违例 + */ + public static String get(String url,Map parameters) throws Exception{ + StringBuilder sb =new StringBuilder(); + if(parameters!=null && parameters.size()>0) { + for(String key : parameters.keySet()) { + String value =parameters.get(key); + if(value!=null && value.length()>0) { + sb.append(key).append("=").append(URLEncoder.encode(value, "UTF-8")).append("&"); + }else { + sb.append(key).append("=").append("&"); + } + } + if(sb.length()>0) { + sb.setLength(sb.length()-1); + } + } + return get(sb.toString()); + } + + /** + * 发送 GET 请求 + * @param url 请求URL + * @param encodedParametersString 编码后的参数串 + * @return 返回结果 + * @throws Exception 违例 + */ + public static String get(String url,String encodedParametersString) throws Exception{ + if(url==null || url.trim().length()==0) { + throw new IllegalArgumentException("url is null"); + } + BufferedReader in = null; + try { + URL getUrl =getEncodedUrl(url,encodedParametersString); + if(getUrl!=null) { + URLConnection connection = getUrl.openConnection(); + connection.setRequestProperty("accept", "application/json"); + connection.setRequestProperty("Accept-Charset", "utf-8"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8")); + + StringBuilder sb =new StringBuilder(); + String line =null; + while ((line = in.readLine()) != null) { + sb.append(line); + } + return sb.toString(); + } + return null; + } catch (Exception e) { + throw e; + } + finally { + try {if (in != null) { in.close(); }} catch (IOException e) {} + } + } + + /** + * 发送 POST 请求 + * @param url 请求URL + * @param key 参数名 + * @param value 参数值 + * @param data post 数据 + * @return 返回结果 + * @throws Exception 违例 + */ + public static String post(String url,String key,String value,String data) throws Exception{ + if(key!=null && key.trim().length()>0) { + if(value!=null && value.length()>0) { + return post(url,key + "=" + URLEncoder.encode(value, "UTF-8"),data); + }else { + return post(url,key + "=",data); + } + } + return post(url,"",data); + } + + /** + * 发送 POST 请求 + * @param url 请求URL + * @param parameters URL请求参数 + * @param data post 数据 + * @return 返回结果 + * @throws Exception 违例 + */ + public static String post(String url,Map parameters,String data) throws Exception{ + StringBuilder sb =new StringBuilder(); + if(parameters!=null && parameters.size()>0) { + for(String key : parameters.keySet()) { + String value =parameters.get(key); + if(value!=null && value.length()>0) { + sb.append(key).append("=").append(URLEncoder.encode(value, "UTF-8")).append("&"); + }else { + sb.append(key).append("=").append("&"); + } + } + if(sb.length()>0) { + sb.setLength(sb.length()-1); + } + } + return post(url,sb.toString(),data); + } + + /** + * 发送 POST 请求 + * @param url 请求URL + * @param encodedParametersString 编码后的参数串 + * @param data post 数据 + * @return 返回结果 + * @throws Exception 违例 + */ + public static String post(String url, String encodedParametersString,String data) throws Exception{ + if(url==null || url.trim().length()==0) { + throw new IllegalArgumentException("url is null"); + } + PrintWriter out = null; + BufferedReader in = null; + StringBuilder sb =new StringBuilder(); + try { + URL postUrl =getEncodedUrl(url,encodedParametersString); + if(postUrl!=null) { + URLConnection conn = postUrl.openConnection(); + conn.setRequestProperty("accept", "application/json"); + conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + // 发送POST请求必须设置如下两行 + conn.setDoOutput(true); + conn.setDoInput(true); + + out = new PrintWriter(conn.getOutputStream()); + // 发送请求参数 + out.print(data); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + sb.append(line); + } + } + } catch (Exception e) { + throw e; + } + //使用finally块来关闭输出流、输入流 + finally{ + try {if (in != null) { in.close(); }} catch (IOException e) {} + if(out!=null) {out.close();} + } + return sb.toString(); + } + + private static URL getEncodedUrl(String url, String encodedParametersString) throws MalformedURLException { + if(url!=null && url.length()>0) { + if(encodedParametersString!=null && encodedParametersString.length()>0) { + if(url.indexOf('?')>-1) {//url 中有 ?号 + if(url.indexOf('?')==(url.length()-1)) {//最后一个是 ?号 + return new URL(url + encodedParametersString); + }else { + return new URL(url + "&" + encodedParametersString); + } + }else { + return new URL(url + "?" + encodedParametersString); + } + }else { + return new URL(url); + } + } + return null; + } +} diff --git a/io.sc.engine.rule.frontend/frontend-register.json b/io.sc.engine.rule.frontend/frontend-register.json new file mode 100644 index 00000000..2fdc3765 --- /dev/null +++ b/io.sc.engine.rule.frontend/frontend-register.json @@ -0,0 +1,7 @@ +{ + "enable": false, + "protocol": "http", + "host": "localhost", + "port": 8080, + "path": "/api/mvc/frontend/regist" +} \ No newline at end of file diff --git a/io.sc.engine.rule.frontend/public/favicon.svg b/io.sc.engine.rule.frontend/public/favicon.svg new file mode 100644 index 00000000..eab5885e --- /dev/null +++ b/io.sc.engine.rule.frontend/public/favicon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/assets/iconfont/HanaleiFill-Regular.ttf b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/assets/iconfont/HanaleiFill-Regular.ttf new file mode 100644 index 00000000..b7e94ffb Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/assets/iconfont/HanaleiFill-Regular.ttf differ diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/FontAwesome.otf b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/FontAwesome.otf new file mode 100644 index 00000000..401ec0f3 Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/FontAwesome.otf differ diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.eot b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.eot differ diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.svg b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.ttf b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.ttf differ diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.woff b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.woff differ diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.woff2 b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/fonts/fontawesome-webfont.woff2 differ diff --git a/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/plugins/images/icon_dropCell.png b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/plugins/images/icon_dropCell.png new file mode 100644 index 00000000..649a73a9 Binary files /dev/null and b/io.sc.engine.rule.frontend/public/webjars/luckysheet/2.1.13/plugins/images/icon_dropCell.png differ diff --git a/io.sc.engine.rule.sample/gradle.properties b/io.sc.engine.rule.sample/gradle.properties new file mode 100644 index 00000000..e69de29b diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/FolderDictionaryEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/FolderDictionaryEntity.java new file mode 100644 index 00000000..7371addd --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/FolderDictionaryEntity.java @@ -0,0 +1,49 @@ +package io.sc.engine.rule.server.dictionary.entity; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.DictionaryType; +import io.sc.engine.rule.server.dictionary.vo.FolderDictionaryVo; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +/** + * 文件夹实体类 + */ +@Entity +@DiscriminatorValue("FOLDER") +@JsonTypeName("FOLDER") +public class FolderDictionaryEntity extends DictionaryEntity { + @Override + public FolderDictionaryVo toVo() { + FolderDictionaryVo vo =new FolderDictionaryVo(); + super.toVo(vo); + return vo; + } + + public FolderDictionaryEntity() {} + public FolderDictionaryEntity(String id) { + this.id =id; + } + + @Override + public DictionaryType getType() { + return DictionaryType.FOLDER; + } + + @Override + public String toString() { + return "FolderDictionaryEntity [" + + " type=" + type + + " id=" + id + + ", code=" + code + + ", name=" + name + + ", description=" + description + + ", order=" + order + + ", creator=" + creator + + ", createDate=" + createDate + + ", lastModifier=" + lastModifier + + ", lastModifyDate=" + lastModifyDate + + "]"; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/exception/FolderAlreadyExistsException.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/exception/FolderAlreadyExistsException.java new file mode 100644 index 00000000..6988693d --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/exception/FolderAlreadyExistsException.java @@ -0,0 +1,26 @@ +package io.sc.engine.rule.server.dictionary.exception; + +/** + * 数据字典文件夹已经存在违例类 + */ +public class FolderAlreadyExistsException extends RuntimeException{ + public FolderAlreadyExistsException() { + super(); + } + + public FolderAlreadyExistsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public FolderAlreadyExistsException(String message, Throwable cause) { + super(message, cause); + } + + public FolderAlreadyExistsException(String message) { + super(message); + } + + public FolderAlreadyExistsException(Throwable cause) { + super(cause); + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/vo/FolderDictionaryVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/vo/FolderDictionaryVo.java new file mode 100644 index 00000000..b66b66d8 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/vo/FolderDictionaryVo.java @@ -0,0 +1,18 @@ +package io.sc.engine.rule.server.dictionary.vo; + +import io.sc.engine.rule.core.enums.DictionaryType; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +/** + * 文件夹 VO 类 + */ +@Entity +@DiscriminatorValue("FOLDER") +public class FolderDictionaryVo extends DictionaryVo { + @Override + public DictionaryType getType() { + return DictionaryType.FOLDER; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/FolderLibEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/FolderLibEntity.java new file mode 100644 index 00000000..aa8dba88 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/FolderLibEntity.java @@ -0,0 +1,52 @@ +package io.sc.engine.rule.server.lib.entity; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.LibType; +import io.sc.engine.rule.server.lib.vo.FolderLibVo; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +/** + * 文件夹实体类 + * @author wangshaoping + * + */ +@Entity +@DiscriminatorValue("FOLDER") +@JsonTypeName("FOLDER") +public class FolderLibEntity extends LibEntity { + + @Override + public FolderLibVo toVo() { + FolderLibVo vo =new FolderLibVo(); + super.toVo(vo); + return vo; + } + + public FolderLibEntity() {} + public FolderLibEntity(String id) { + this.id =id; + } + + @Override + public LibType getType() { + return LibType.FOLDER; + } + + @Override + public String toString() { + return "FolderLibEntity [" + + " type=" + type + + " id=" + id + + ", code=" + code + + ", name=" + name + + ", description=" + description + + ", order=" + order + + ", creator=" + creator + + ", createDate=" + createDate + + ", lastModifier=" + lastModifier + + ", lastModifyDate=" + lastModifyDate + + "]"; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/processor/GroovyScriptIndicatorProcessorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/processor/GroovyScriptIndicatorProcessorEntity.java new file mode 100644 index 00000000..e78871d5 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/processor/GroovyScriptIndicatorProcessorEntity.java @@ -0,0 +1,58 @@ +package io.sc.engine.rule.server.lib.entity.processor; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.util.ExpressionReplacer; +import io.sc.engine.rule.server.lib.entity.IndicatorProcessorEntity; +import io.sc.engine.rule.server.lib.vo.processor.GroovyScriptIndicatorProcessorVo; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import java.util.Map; + +/** + * 指标处理器(脚本代码操作)实体类 + */ +@Entity +@DiscriminatorValue("GROOVY_SCRIPT") +@JsonTypeName("GROOVY_SCRIPT") +public class GroovyScriptIndicatorProcessorEntity extends IndicatorProcessorEntity { + //脚本代码 + @Column(name="GROOVY_SCRIPT_") + private String groovyScript; + + @Override + public GroovyScriptIndicatorProcessorVo toVo() { + GroovyScriptIndicatorProcessorVo vo =new GroovyScriptIndicatorProcessorVo(); + super.toVo(vo); + vo.setType(this.getType()); + vo.setGroovyScript(this.getGroovyScript()); + return vo; + } + + @Override + public ProcessorType getType() { + return ProcessorType.GROOVY_SCRIPT; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } + + @Override + public boolean replace(Map mapping) { + String replaced =ExpressionReplacer.replace(this.groovyScript, mapping); + replaced =(replaced==null?"":replaced); + boolean result =false; + if(!replaced.equals(this.groovyScript)) { + result =true; + } + this.groovyScript =replaced; + return result; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/processor/HttpRequestIndicatorProcessorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/processor/HttpRequestIndicatorProcessorEntity.java new file mode 100644 index 00000000..11426932 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/processor/HttpRequestIndicatorProcessorEntity.java @@ -0,0 +1,229 @@ +package io.sc.engine.rule.server.lib.entity.processor; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.HttpAuthorizationType; +import io.sc.engine.rule.core.enums.HttpMethodType; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.util.ExpressionReplacer; +import io.sc.engine.rule.server.lib.entity.IndicatorProcessorEntity; +import io.sc.engine.rule.server.lib.vo.processor.HttpRequestIndicatorProcessorVo; + +import javax.persistence.*; +import java.util.Map; + +/** + * 指标处理器(Http请求操作)实体类 + */ +@Entity +@DiscriminatorValue("HTTP_REQUEST") +@JsonTypeName("HTTP_REQUEST") +public class HttpRequestIndicatorProcessorEntity extends IndicatorProcessorEntity { + // Method + @Column(name="HTTP_METHOD_") + @Enumerated(EnumType.STRING) + private HttpMethodType httpMethod; + + // Url + @Column(name="HTTP_URL_") + private String httpUrl; + + // 认证类型 + @Column(name="HTTP_AUTH_TYPE_") + @Enumerated(EnumType.STRING) + private HttpAuthorizationType httpAuthType; + + // Api Key's key + @Column(name="HTTP_AUTH_API_KEY_") + private String httpAuthApikey; + + // Api Key's value + @Column(name="HTTP_AUTH_API_VALUE_") + private String httpAuthApiValue; + + // Api Key's value + @Column(name="HTTP_AUTH_API_ADDTO_") + private String httpAuthApiAddTo; + + @Column(name="HTTP_AUTH_BASIC_USERNAME_") + private String httpAuthBasicUsername; + + @Column(name="HTTP_AUTH_BASIC_PASSWORD_") + private String httpAuthBasicPassword; + + @Column(name="HTTP_AUTH_BEARER_TOKEN_") + private String httpAuthBearerToken; + + @Column(name="HTTP_PARAMS_") + private String httpParams; + + @Column(name="HTTP_BODY_") + private String httpBody; + + @Column(name="HTTP_RESPONSE_MAPPING_") + private String httpResponseMapping; + + + @Override + public HttpRequestIndicatorProcessorVo toVo() { + HttpRequestIndicatorProcessorVo vo =new HttpRequestIndicatorProcessorVo(); + super.toVo(vo); + vo.setType(this.getType()); + vo.setHttpMethod(this.getHttpMethod()); + vo.setHttpUrl(this.getHttpUrl()); + vo.setHttpAuthType(this.getHttpAuthType()); + vo.setHttpAuthApikey(this.getHttpAuthApikey()); + vo.setHttpAuthApiValue(this.getHttpAuthApiValue()); + vo.setHttpAuthApiAddTo(this.getHttpAuthApiAddTo()); + vo.setHttpAuthBasicUsername(this.getHttpAuthBasicUsername()); + vo.setHttpAuthBasicPassword(this.getHttpAuthBasicPassword()); + vo.setHttpAuthBearerToken(this.getHttpAuthBearerToken()); + vo.setHttpParams(this.getHttpParams()); + vo.setHttpBody(this.getHttpBody()); + vo.setHttpResponseMapping(this.getHttpResponseMapping()); + return vo; + } + @Override + public ProcessorType getType() { + return ProcessorType.HTTP_REQUEST; + } + + + public HttpMethodType getHttpMethod() { + return httpMethod; + } + + + public void setHttpMethod(HttpMethodType httpMethod) { + this.httpMethod = httpMethod; + } + + + public String getHttpUrl() { + return httpUrl; + } + + + public void setHttpUrl(String httpUrl) { + this.httpUrl = httpUrl; + } + + + public HttpAuthorizationType getHttpAuthType() { + return httpAuthType; + } + + + public void setHttpAuthType(HttpAuthorizationType httpAuthType) { + this.httpAuthType = httpAuthType; + } + + + public String getHttpAuthApikey() { + return httpAuthApikey; + } + + + public void setHttpAuthApikey(String httpAuthApikey) { + this.httpAuthApikey = httpAuthApikey; + } + + + public String getHttpAuthApiValue() { + return httpAuthApiValue; + } + + + public void setHttpAuthApiValue(String httpAuthApiValue) { + this.httpAuthApiValue = httpAuthApiValue; + } + + + public String getHttpAuthApiAddTo() { + return httpAuthApiAddTo; + } + + + public void setHttpAuthApiAddTo(String httpAuthApiAddTo) { + this.httpAuthApiAddTo = httpAuthApiAddTo; + } + + + public String getHttpAuthBasicUsername() { + return httpAuthBasicUsername; + } + + + public void setHttpAuthBasicUsername(String httpAuthBasicUsername) { + this.httpAuthBasicUsername = httpAuthBasicUsername; + } + + + public String getHttpAuthBasicPassword() { + return httpAuthBasicPassword; + } + + + public void setHttpAuthBasicPassword(String httpAuthBasicPassword) { + this.httpAuthBasicPassword = httpAuthBasicPassword; + } + + + public String getHttpAuthBearerToken() { + return httpAuthBearerToken; + } + + + public void setHttpAuthBearerToken(String httpAuthBearerToken) { + this.httpAuthBearerToken = httpAuthBearerToken; + } + + + public String getHttpParams() { + return httpParams; + } + + + public void setHttpParams(String httpParams) { + this.httpParams = httpParams; + } + + + public String getHttpBody() { + return httpBody; + } + + + public void setHttpBody(String httpBody) { + this.httpBody = httpBody; + } + + + public String getHttpResponseMapping() { + return httpResponseMapping; + } + + + public void setHttpResponseMapping(String httpResponseMapping) { + this.httpResponseMapping = httpResponseMapping; + } + + + @Override + public boolean replace(Map mapping) { + String replaced =ExpressionReplacer.replace(this.httpParams, mapping); + replaced =(replaced==null?"":replaced); + boolean result =false; + if(!replaced.equals(this.httpParams)) { + result =true; + } + this.httpParams =replaced; + + replaced =ExpressionReplacer.replace(this.httpResponseMapping, mapping); + replaced =(replaced==null?"":replaced); + if(!replaced.equals(this.httpResponseMapping)) { + result =true; + } + this.httpResponseMapping =replaced; + return result; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/validator/FalseIndicatorValidatorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/validator/FalseIndicatorValidatorEntity.java new file mode 100644 index 00000000..0d5858d8 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/validator/FalseIndicatorValidatorEntity.java @@ -0,0 +1,30 @@ +package io.sc.engine.rule.server.lib.entity.validator; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.ValidatorType; +import io.sc.engine.rule.server.lib.entity.IndicatorValidatorEntity; +import io.sc.engine.rule.server.lib.vo.validator.FalseIndicatorValidatorVo; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +/** + * 验证器(真)实体类 + */ +@Entity +@DiscriminatorValue("FALSE") +@JsonTypeName("FALSE") +public class FalseIndicatorValidatorEntity extends IndicatorValidatorEntity { + @Override + public FalseIndicatorValidatorVo toVo() { + FalseIndicatorValidatorVo vo =new FalseIndicatorValidatorVo(); + super.toVo(vo); + vo.setType(this.getType()); + return vo; + } + + @Override + public ValidatorType getType() { + return ValidatorType.FALSE; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/exception/FolderAlreadyExistsException.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/exception/FolderAlreadyExistsException.java new file mode 100644 index 00000000..e23d5d9c --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/exception/FolderAlreadyExistsException.java @@ -0,0 +1,26 @@ +package io.sc.engine.rule.server.lib.exception; + +/** + * 库文件夹已经存在违例类 + */ +public class FolderAlreadyExistsException extends RuntimeException{ + public FolderAlreadyExistsException() { + super(); + } + + public FolderAlreadyExistsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public FolderAlreadyExistsException(String message, Throwable cause) { + super(message, cause); + } + + public FolderAlreadyExistsException(String message) { + super(message); + } + + public FolderAlreadyExistsException(Throwable cause) { + super(cause); + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/FolderLibVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/FolderLibVo.java new file mode 100644 index 00000000..d7e1ab01 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/FolderLibVo.java @@ -0,0 +1,13 @@ +package io.sc.engine.rule.server.lib.vo; + +import io.sc.engine.rule.core.enums.LibType; + +/** + * 文件夹实体类 + */ +public class FolderLibVo extends LibVo { + @Override + public LibType getType() { + return LibType.FOLDER; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/processor/GroovyScriptIndicatorProcessorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/processor/GroovyScriptIndicatorProcessorVo.java new file mode 100644 index 00000000..dc75b0ff --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/processor/GroovyScriptIndicatorProcessorVo.java @@ -0,0 +1,25 @@ +package io.sc.engine.rule.server.lib.vo.processor; + +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.server.lib.vo.IndicatorProcessorVo; + +/** + * 指标处理器(脚本代码操作)Vo 类 + */ +public class GroovyScriptIndicatorProcessorVo extends IndicatorProcessorVo { + //脚本代码 + private String groovyScript; + + @Override + public ProcessorType getType() { + return ProcessorType.GROOVY_SCRIPT; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/processor/HttpRequestIndicatorProcessorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/processor/HttpRequestIndicatorProcessorVo.java new file mode 100644 index 00000000..af6b9867 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/processor/HttpRequestIndicatorProcessorVo.java @@ -0,0 +1,167 @@ +package io.sc.engine.rule.server.lib.vo.processor; + +import io.sc.engine.rule.core.enums.HttpAuthorizationType; +import io.sc.engine.rule.core.enums.HttpMethodType; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.server.lib.vo.IndicatorProcessorVo; + +/** + * 指标处理器(Http请求操作)Vo 类 + */ +public class HttpRequestIndicatorProcessorVo extends IndicatorProcessorVo { + // Method + private HttpMethodType httpMethod; + + // Url + private String httpUrl; + + // 认证类型 + private HttpAuthorizationType httpAuthType; + + // Api Key's key + private String httpAuthApikey; + + // Api Key's value + private String httpAuthApiValue; + + // Api Key's value + private String httpAuthApiAddTo; + + private String httpAuthBasicUsername; + + private String httpAuthBasicPassword; + + private String httpAuthBearerToken; + + private String httpParams; + + private String httpBody; + + private String httpResponseMapping; + + @Override + public ProcessorType getType() { + return ProcessorType.HTTP_REQUEST; + } + + + public HttpMethodType getHttpMethod() { + return httpMethod; + } + + + public void setHttpMethod(HttpMethodType httpMethod) { + this.httpMethod = httpMethod; + } + + + public String getHttpUrl() { + return httpUrl; + } + + + public void setHttpUrl(String httpUrl) { + this.httpUrl = httpUrl; + } + + + public HttpAuthorizationType getHttpAuthType() { + return httpAuthType; + } + + + public void setHttpAuthType(HttpAuthorizationType httpAuthType) { + this.httpAuthType = httpAuthType; + } + + + public String getHttpAuthApikey() { + return httpAuthApikey; + } + + + public void setHttpAuthApikey(String httpAuthApikey) { + this.httpAuthApikey = httpAuthApikey; + } + + + public String getHttpAuthApiValue() { + return httpAuthApiValue; + } + + + public void setHttpAuthApiValue(String httpAuthApiValue) { + this.httpAuthApiValue = httpAuthApiValue; + } + + + public String getHttpAuthApiAddTo() { + return httpAuthApiAddTo; + } + + + public void setHttpAuthApiAddTo(String httpAuthApiAddTo) { + this.httpAuthApiAddTo = httpAuthApiAddTo; + } + + + public String getHttpAuthBasicUsername() { + return httpAuthBasicUsername; + } + + + public void setHttpAuthBasicUsername(String httpAuthBasicUsername) { + this.httpAuthBasicUsername = httpAuthBasicUsername; + } + + + public String getHttpAuthBasicPassword() { + return httpAuthBasicPassword; + } + + + public void setHttpAuthBasicPassword(String httpAuthBasicPassword) { + this.httpAuthBasicPassword = httpAuthBasicPassword; + } + + + public String getHttpAuthBearerToken() { + return httpAuthBearerToken; + } + + + public void setHttpAuthBearerToken(String httpAuthBearerToken) { + this.httpAuthBearerToken = httpAuthBearerToken; + } + + + public String getHttpParams() { + return httpParams; + } + + + public void setHttpParams(String httpParams) { + this.httpParams = httpParams; + } + + + public String getHttpBody() { + return httpBody; + } + + + public void setHttpBody(String httpBody) { + this.httpBody = httpBody; + } + + + public String getHttpResponseMapping() { + return httpResponseMapping; + } + + + public void setHttpResponseMapping(String httpResponseMapping) { + this.httpResponseMapping = httpResponseMapping; + } + +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/validator/FalseIndicatorValidatorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/validator/FalseIndicatorValidatorVo.java new file mode 100644 index 00000000..c135d0df --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/vo/validator/FalseIndicatorValidatorVo.java @@ -0,0 +1,14 @@ +package io.sc.engine.rule.server.lib.vo.validator; + +import io.sc.engine.rule.core.enums.ValidatorType; +import io.sc.engine.rule.server.lib.vo.IndicatorValidatorVo; + +/** + * 验证器(真)Vo 类 + */ +public class FalseIndicatorValidatorVo extends IndicatorValidatorVo { + @Override + public ValidatorType getType() { + return ValidatorType.FALSE; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/ExecutionFlowParameterProcessorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/ExecutionFlowParameterProcessorEntity.java new file mode 100644 index 00000000..373c2341 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/ExecutionFlowParameterProcessorEntity.java @@ -0,0 +1,59 @@ +package io.sc.engine.rule.server.model.entity.processor; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.util.ExpressionReplacer; +import io.sc.engine.rule.server.model.entity.ParameterProcessorEntity; +import io.sc.engine.rule.server.model.vo.processor.ExecutionFlowParameterProcessorVo; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import java.util.Map; + +/** + * 模型参数处理器(执行流)实体类 + * @author wangshaoping + * + */ +@Entity +@DiscriminatorValue("EXECUTION_FLOW") +@JsonTypeName("EXECUTION_FLOW") +public class ExecutionFlowParameterProcessorEntity extends ParameterProcessorEntity { + //执行流 + @Column(name="EXECUTION_FLOW_") + private String executionFlow; + + @Override + public ExecutionFlowParameterProcessorVo toVo() { + ExecutionFlowParameterProcessorVo vo =new ExecutionFlowParameterProcessorVo(); + super.toVo(vo); + vo.setExecutionFlow(this.getExecutionFlow()); + return vo; + } + + @Override + public ProcessorType getType() { + return ProcessorType.EXECUTION_FLOW; + } + + public String getExecutionFlow() { + return executionFlow; + } + + public void setExecutionFlow(String executionFlow) { + this.executionFlow = executionFlow; + } + + @Override + public boolean replace(Map mapping) { + String replaced =ExpressionReplacer.replace(this.executionFlow, mapping); + replaced =(replaced==null?"":replaced); + boolean result =false; + if(!replaced.equals(this.executionFlow)) { + result =true; + } + this.executionFlow =replaced; + return result; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/GroovyScriptParameterProcessorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/GroovyScriptParameterProcessorEntity.java new file mode 100644 index 00000000..d235403d --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/GroovyScriptParameterProcessorEntity.java @@ -0,0 +1,57 @@ +package io.sc.engine.rule.server.model.entity.processor; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.util.ExpressionReplacer; +import io.sc.engine.rule.server.model.entity.ParameterProcessorEntity; +import io.sc.engine.rule.server.model.vo.processor.GroovyScriptParameterProcessorVo; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import java.util.Map; + +/** + * 模型参数处理器(脚本代码操作)实体类 + */ +@Entity +@DiscriminatorValue("GROOVY_SCRIPT") +@JsonTypeName("GROOVY_SCRIPT") +public class GroovyScriptParameterProcessorEntity extends ParameterProcessorEntity { + //脚本代码 + @Column(name="GROOVY_SCRIPT_") + private String groovyScript; + + @Override + public GroovyScriptParameterProcessorVo toVo() { + GroovyScriptParameterProcessorVo vo =new GroovyScriptParameterProcessorVo(); + super.toVo(vo); + vo.setGroovyScript(this.getGroovyScript()); + return vo; + } + + @Override + public ProcessorType getType() { + return ProcessorType.GROOVY_SCRIPT; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } + + @Override + public boolean replace(Map mapping) { + String replaced =ExpressionReplacer.replace(this.groovyScript, mapping); + replaced =(replaced==null?"":replaced); + boolean result =false; + if(!replaced.equals(this.groovyScript)) { + result =true; + } + this.groovyScript =replaced; + return result; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/HttpRequestParameterProcessorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/HttpRequestParameterProcessorEntity.java new file mode 100644 index 00000000..0b795df6 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/HttpRequestParameterProcessorEntity.java @@ -0,0 +1,227 @@ +package io.sc.engine.rule.server.model.entity.processor; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.HttpAuthorizationType; +import io.sc.engine.rule.core.enums.HttpMethodType; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.core.util.ExpressionReplacer; +import io.sc.engine.rule.server.model.entity.ParameterProcessorEntity; +import io.sc.engine.rule.server.model.vo.processor.HttpRequestParameterProcessorVo; + +import javax.persistence.*; +import java.util.Map; + +/** + * 模型参数处理器(Http 请求操作)实体类 + */ +@Entity +@DiscriminatorValue("HTTP_REQUEST") +@JsonTypeName("HTTP_REQUEST") +public class HttpRequestParameterProcessorEntity extends ParameterProcessorEntity { + // Method + @Column(name="HTTP_METHOD_") + @Enumerated(EnumType.STRING) + private HttpMethodType httpMethod; + + // Url + @Column(name="HTTP_URL_") + private String httpUrl; + + // 认证类型 + @Column(name="HTTP_AUTH_TYPE_") + @Enumerated(EnumType.STRING) + private HttpAuthorizationType httpAuthType; + + // Api Key's key + @Column(name="HTTP_AUTH_API_KEY_") + private String httpAuthApikey; + + // Api Key's value + @Column(name="HTTP_AUTH_API_VALUE_") + private String httpAuthApiValue; + + // Api Key's value + @Column(name="HTTP_AUTH_API_ADDTO_") + private String httpAuthApiAddTo; + + @Column(name="HTTP_AUTH_BASIC_USERNAME_") + private String httpAuthBasicUsername; + + @Column(name="HTTP_AUTH_BASIC_PASSWORD_") + private String httpAuthBasicPassword; + + @Column(name="HTTP_AUTH_BEARER_TOKEN_") + private String httpAuthBearerToken; + + @Column(name="HTTP_PARAMS_") + private String httpParams; + + @Column(name="HTTP_BODY_") + private String httpBody; + + @Column(name="HTTP_RESPONSE_MAPPING_") + private String httpResponseMapping; + + @Override + public HttpRequestParameterProcessorVo toVo() { + HttpRequestParameterProcessorVo vo =new HttpRequestParameterProcessorVo(); + super.toVo(vo); + vo.setHttpUrl(this.getHttpUrl()); + vo.setHttpAuthType(this.getHttpAuthType()); + vo.setHttpAuthApikey(this.getHttpAuthApikey()); + vo.setHttpAuthApiValue(this.getHttpAuthApiValue()); + vo.setHttpAuthApiAddTo(this.getHttpAuthApiAddTo()); + vo.setHttpAuthBasicUsername(this.getHttpAuthBasicUsername()); + vo.setHttpAuthBasicPassword(this.getHttpAuthBasicPassword()); + vo.setHttpAuthBearerToken(this.getHttpAuthBearerToken()); + vo.setHttpParams(this.getHttpParams()); + vo.setHttpBody(this.getHttpBody()); + vo.setHttpResponseMapping(this.getHttpResponseMapping()); + return vo; + } + + @Override + public ProcessorType getType() { + return ProcessorType.HTTP_REQUEST; + } + + + public HttpMethodType getHttpMethod() { + return httpMethod; + } + + + public void setHttpMethod(HttpMethodType httpMethod) { + this.httpMethod = httpMethod; + } + + + public String getHttpUrl() { + return httpUrl; + } + + + public void setHttpUrl(String httpUrl) { + this.httpUrl = httpUrl; + } + + + public HttpAuthorizationType getHttpAuthType() { + return httpAuthType; + } + + + public void setHttpAuthType(HttpAuthorizationType httpAuthType) { + this.httpAuthType = httpAuthType; + } + + + public String getHttpAuthApikey() { + return httpAuthApikey; + } + + + public void setHttpAuthApikey(String httpAuthApikey) { + this.httpAuthApikey = httpAuthApikey; + } + + + public String getHttpAuthApiValue() { + return httpAuthApiValue; + } + + + public void setHttpAuthApiValue(String httpAuthApiValue) { + this.httpAuthApiValue = httpAuthApiValue; + } + + + public String getHttpAuthApiAddTo() { + return httpAuthApiAddTo; + } + + + public void setHttpAuthApiAddTo(String httpAuthApiAddTo) { + this.httpAuthApiAddTo = httpAuthApiAddTo; + } + + + public String getHttpAuthBasicUsername() { + return httpAuthBasicUsername; + } + + + public void setHttpAuthBasicUsername(String httpAuthBasicUsername) { + this.httpAuthBasicUsername = httpAuthBasicUsername; + } + + + public String getHttpAuthBasicPassword() { + return httpAuthBasicPassword; + } + + + public void setHttpAuthBasicPassword(String httpAuthBasicPassword) { + this.httpAuthBasicPassword = httpAuthBasicPassword; + } + + + public String getHttpAuthBearerToken() { + return httpAuthBearerToken; + } + + + public void setHttpAuthBearerToken(String httpAuthBearerToken) { + this.httpAuthBearerToken = httpAuthBearerToken; + } + + + public String getHttpParams() { + return httpParams; + } + + + public void setHttpParams(String httpParams) { + this.httpParams = httpParams; + } + + + public String getHttpBody() { + return httpBody; + } + + + public void setHttpBody(String httpBody) { + this.httpBody = httpBody; + } + + + public String getHttpResponseMapping() { + return httpResponseMapping; + } + + + public void setHttpResponseMapping(String httpResponseMapping) { + this.httpResponseMapping = httpResponseMapping; + } + + + @Override + public boolean replace(Map mapping) { + String replaced =ExpressionReplacer.replace(this.httpParams, mapping); + replaced =(replaced==null?"":replaced); + boolean result =false; + if(!replaced.equals(this.httpParams)) { + result =true; + } + this.httpParams =replaced; + + replaced =ExpressionReplacer.replace(this.httpResponseMapping, mapping); + replaced =(replaced==null?"":replaced); + if(!replaced.equals(this.httpResponseMapping)) { + result =true; + } + this.httpResponseMapping =replaced; + return result; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/validator/FalseParameterValidatorEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/validator/FalseParameterValidatorEntity.java new file mode 100644 index 00000000..e9f40730 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/validator/FalseParameterValidatorEntity.java @@ -0,0 +1,29 @@ +package io.sc.engine.rule.server.model.entity.validator; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.ValidatorType; +import io.sc.engine.rule.server.model.entity.ParameterValidatorEntity; +import io.sc.engine.rule.server.model.vo.validator.FalseParameterValidatorVo; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +/** + * 验证器(真)实体类 + */ +@Entity +@DiscriminatorValue("FALSE") +@JsonTypeName("FALSE") +public class FalseParameterValidatorEntity extends ParameterValidatorEntity { + @Override + public FalseParameterValidatorVo toVo() { + FalseParameterValidatorVo vo =new FalseParameterValidatorVo(); + super.toVo(vo); + return vo; + } + + @Override + public ValidatorType getType() { + return ValidatorType.FALSE; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/ExecutionFlowParameterProcessorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/ExecutionFlowParameterProcessorVo.java new file mode 100644 index 00000000..34474533 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/ExecutionFlowParameterProcessorVo.java @@ -0,0 +1,26 @@ +package io.sc.engine.rule.server.model.vo.processor; + +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.server.model.vo.ParameterProcessorVo; + +/** + * 模型参数处理器(执行流)Vo 类 + */ +public class ExecutionFlowParameterProcessorVo extends ParameterProcessorVo { + //执行流 + private String executionFlow; + + @Override + public ProcessorType getType() { + return ProcessorType.EXECUTION_FLOW; + } + + public String getExecutionFlow() { + return executionFlow; + } + + public void setExecutionFlow(String executionFlow) { + this.executionFlow = executionFlow; + } + +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/GroovyScriptParameterProcessorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/GroovyScriptParameterProcessorVo.java new file mode 100644 index 00000000..ae161182 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/GroovyScriptParameterProcessorVo.java @@ -0,0 +1,26 @@ +package io.sc.engine.rule.server.model.vo.processor; + +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.server.model.vo.ParameterProcessorVo; + +/** + * 模型参数处理器(脚本代码操作)Vo 类 + */ +public class GroovyScriptParameterProcessorVo extends ParameterProcessorVo { + //脚本代码 + private String groovyScript; + + @Override + public ProcessorType getType() { + return ProcessorType.GROOVY_SCRIPT; + } + + public String getGroovyScript() { + return groovyScript; + } + + public void setGroovyScript(String groovyScript) { + this.groovyScript = groovyScript; + } + +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/HttpRequestParameterProcessorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/HttpRequestParameterProcessorVo.java new file mode 100644 index 00000000..c49a1eb4 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/processor/HttpRequestParameterProcessorVo.java @@ -0,0 +1,167 @@ +package io.sc.engine.rule.server.model.vo.processor; + +import io.sc.engine.rule.core.enums.HttpAuthorizationType; +import io.sc.engine.rule.core.enums.HttpMethodType; +import io.sc.engine.rule.core.enums.ProcessorType; +import io.sc.engine.rule.server.model.vo.ParameterProcessorVo; + +/** + * 模型参数处理器(Http 请求操作)Vo 类 + */ +public class HttpRequestParameterProcessorVo extends ParameterProcessorVo { + // Method + private HttpMethodType httpMethod; + + // Url + private String httpUrl; + + // 认证类型 + private HttpAuthorizationType httpAuthType; + + // Api Key's key + private String httpAuthApikey; + + // Api Key's value + private String httpAuthApiValue; + + // Api Key's value + private String httpAuthApiAddTo; + + private String httpAuthBasicUsername; + + private String httpAuthBasicPassword; + + private String httpAuthBearerToken; + + private String httpParams; + + private String httpBody; + + private String httpResponseMapping; + + @Override + public ProcessorType getType() { + return ProcessorType.HTTP_REQUEST; + } + + + public HttpMethodType getHttpMethod() { + return httpMethod; + } + + + public void setHttpMethod(HttpMethodType httpMethod) { + this.httpMethod = httpMethod; + } + + + public String getHttpUrl() { + return httpUrl; + } + + + public void setHttpUrl(String httpUrl) { + this.httpUrl = httpUrl; + } + + + public HttpAuthorizationType getHttpAuthType() { + return httpAuthType; + } + + + public void setHttpAuthType(HttpAuthorizationType httpAuthType) { + this.httpAuthType = httpAuthType; + } + + + public String getHttpAuthApikey() { + return httpAuthApikey; + } + + + public void setHttpAuthApikey(String httpAuthApikey) { + this.httpAuthApikey = httpAuthApikey; + } + + + public String getHttpAuthApiValue() { + return httpAuthApiValue; + } + + + public void setHttpAuthApiValue(String httpAuthApiValue) { + this.httpAuthApiValue = httpAuthApiValue; + } + + + public String getHttpAuthApiAddTo() { + return httpAuthApiAddTo; + } + + + public void setHttpAuthApiAddTo(String httpAuthApiAddTo) { + this.httpAuthApiAddTo = httpAuthApiAddTo; + } + + + public String getHttpAuthBasicUsername() { + return httpAuthBasicUsername; + } + + + public void setHttpAuthBasicUsername(String httpAuthBasicUsername) { + this.httpAuthBasicUsername = httpAuthBasicUsername; + } + + + public String getHttpAuthBasicPassword() { + return httpAuthBasicPassword; + } + + + public void setHttpAuthBasicPassword(String httpAuthBasicPassword) { + this.httpAuthBasicPassword = httpAuthBasicPassword; + } + + + public String getHttpAuthBearerToken() { + return httpAuthBearerToken; + } + + + public void setHttpAuthBearerToken(String httpAuthBearerToken) { + this.httpAuthBearerToken = httpAuthBearerToken; + } + + + public String getHttpParams() { + return httpParams; + } + + + public void setHttpParams(String httpParams) { + this.httpParams = httpParams; + } + + + public String getHttpBody() { + return httpBody; + } + + + public void setHttpBody(String httpBody) { + this.httpBody = httpBody; + } + + + public String getHttpResponseMapping() { + return httpResponseMapping; + } + + + public void setHttpResponseMapping(String httpResponseMapping) { + this.httpResponseMapping = httpResponseMapping; + } + +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/validator/FalseParameterValidatorVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/validator/FalseParameterValidatorVo.java new file mode 100644 index 00000000..2e9acbed --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/validator/FalseParameterValidatorVo.java @@ -0,0 +1,14 @@ +package io.sc.engine.rule.server.model.vo.validator; + +import io.sc.engine.rule.core.enums.ValidatorType; +import io.sc.engine.rule.server.model.vo.ParameterValidatorVo; + +/** + * 验证器(真)实体类 + */ +public class FalseParameterValidatorVo extends ParameterValidatorVo { + @Override + public ValidatorType getType() { + return ValidatorType.FALSE; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/FolderResourceEntity.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/FolderResourceEntity.java new file mode 100644 index 00000000..f7ebd030 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/FolderResourceEntity.java @@ -0,0 +1,52 @@ +package io.sc.engine.rule.server.resource.entity; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.sc.engine.rule.core.enums.ResourceType; +import io.sc.engine.rule.server.resource.vo.FolderResourceVo; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +/** + * 文件夹资源实体类 + * @author wangshaoping + * + */ +@Entity +@DiscriminatorValue("FOLDER") +@JsonTypeName("FOLDER") +public class FolderResourceEntity extends ResourceEntity { + @Override + public FolderResourceVo toVo() { + FolderResourceVo vo =new FolderResourceVo(); + super.toVo(vo); + vo.setType(this.getType()); + return vo; + } + + public FolderResourceEntity() {} + public FolderResourceEntity(String id) { + this.id =id; + } + + @Override + public ResourceType getType() { + return ResourceType.FOLDER; + } + + @Override + public String toString() { + return "FolderResourceEntity [" + + " type=" + type + + " id=" + id + + ", code=" + code + + ", name=" + name + + ", description=" + description + + ", order=" + order + + ", creator=" + creator + + ", createDate=" + createDate + + ", lastModifier=" + lastModifier + + ", lastModifyDate=" + lastModifyDate + + "]"; + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/exception/FolderAlreadyExistsException.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/exception/FolderAlreadyExistsException.java new file mode 100644 index 00000000..8d6e7493 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/exception/FolderAlreadyExistsException.java @@ -0,0 +1,30 @@ +package io.sc.engine.rule.server.resource.exception; + +/** + * 文件夹已经存在违例类 + * @author wangshaoping + * + */ +public class FolderAlreadyExistsException extends RuntimeException{ + private static final long serialVersionUID = -4300506761652664174L; + + public FolderAlreadyExistsException() { + super(); + } + + public FolderAlreadyExistsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public FolderAlreadyExistsException(String message, Throwable cause) { + super(message, cause); + } + + public FolderAlreadyExistsException(String message) { + super(message); + } + + public FolderAlreadyExistsException(Throwable cause) { + super(cause); + } +} diff --git a/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/FolderResourceVo.java b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/FolderResourceVo.java new file mode 100644 index 00000000..394aa666 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/FolderResourceVo.java @@ -0,0 +1,13 @@ +package io.sc.engine.rule.server.resource.vo; + +import io.sc.engine.rule.core.enums.ResourceType; + +/** + * 文件夹资源实体类 + */ +public class FolderResourceVo extends ResourceVo { + @Override + public ResourceType getType() { + return ResourceType.FOLDER; + } +} diff --git a/io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/graph/graph_editor.properties b/io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/graph/graph_editor.properties new file mode 100644 index 00000000..30d07e66 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/graph/graph_editor.properties @@ -0,0 +1,43 @@ +# \u7ec4\u4ef6\u9762\u677f\u6807\u9898 +mxgraph.re.editor.Palette.title=Available + +# \u5f00\u59cb\u7ec4\u4ef6 +mxgraph.re.editor.component.start.title=Start + +# \u6761\u4ef6\u5224\u65ad\u7ec4\u4ef6 +mxgraph.re.editor.component.condition.title=Condition +mxgraph.re.editor.component.condition.entity.condition=Condition + +# \u5e76\u53d1\u7ec4\u4ef6 +mxgraph.re.editor.component.parallel.title=Paralleler + +# \u6761\u4ef6\u5206\u503c\u8fde\u7ebf\u7ec4\u4ef6 +mxgraph.re.editor.component.condition.edge.conditionValue=Condition Value +mxgraph.re.editor.component.condition.edge.type=Value Type +mxgraph.re.editor.component.condition.edge.type.string=String +mxgraph.re.editor.component.condition.edge.type.number=Number +mxgraph.re.editor.component.condition.edge.type.boolean=Boolean + +# \u8868\u8fbe\u5f0f\u7ec4\u4ef6 +mxgraph.re.editor.component.expression.title=Expression +mxgraph.re.editor.component.expression.entity.expression=Expression +mxgraph.re.editor.component.expression.entity.commands=Commands + +# \u6307\u4ee4\u96c6\u7ec4\u4ef6 +mxgraph.re.editor.component.commandSet.title=Command Set +mxgraph.re.editor.component.commandSet.entity.commands=Command Set + +# \u8d44\u6e90\u6458\u8981\u4fe1\u606f\u7ec4\u4ef6 +mxgraph.re.editor.component.resourceAbstract.title=Resource +mxgraph.re.editor.component.resourceAbstract.entity.resource=Resource + +# \u53ef\u914d\u7f6e\u8f93\u5165\u8f93\u51fa\u6307\u4ee4\u7684\u8d44\u6e90\u6458\u8981\u4fe1\u606f\u7ec4\u4ef6 +mxgraph.re.editor.component.configurableResourceAbstract.title=Configurable Resource +mxgraph.re.editor.component.configurableResourceAbstract.entity.resource=Resource +mxgraph.re.editor.component.configurableResourceAbstract.entity.inputCommands=Input Command Set +mxgraph.re.editor.component.configurableResourceAbstract.entity.outputCommands=Output Command Set + +# \u6a21\u578b\u7ec4\u4ef6 +mxgraph.re.editor.component.submodel.title=Model +mxgraph.re.editor.component.submodel.entity.model=Model + diff --git a/io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/graph/graph_editor_zh_CN.properties b/io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/graph/graph_editor_zh_CN.properties new file mode 100644 index 00000000..4d293a98 --- /dev/null +++ b/io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/graph/graph_editor_zh_CN.properties @@ -0,0 +1,42 @@ +# \u7ec4\u4ef6\u9762\u677f\u6807\u9898 +mxgraph.re.editor.Palette.title=\u53ef\u7528\u7ec4\u4ef6 + +# \u5f00\u59cb\u7ec4\u4ef6 +mxgraph.re.editor.component.start.title=\u5f00\u59cb + +# \u6761\u4ef6\u5224\u65ad\u7ec4\u4ef6 +mxgraph.re.editor.component.condition.title=\u6761\u4ef6\u5224\u65ad +mxgraph.re.editor.component.condition.entity.condition=\u6761\u4ef6 + +# \u5e76\u53d1\u7ec4\u4ef6 +mxgraph.re.editor.component.parallel.title=\u5e76\u53d1\u5668 + +# \u6761\u4ef6\u5206\u503c\u8fde\u7ebf\u7ec4\u4ef6 +mxgraph.re.editor.component.condition.edge.conditionValue=\u6761\u4ef6\u503c +mxgraph.re.editor.component.condition.edge.type=\u503c\u7c7b\u578b +mxgraph.re.editor.component.condition.edge.type.string=\u5b57\u7b26\u4e32 +mxgraph.re.editor.component.condition.edge.type.number=\u6570\u5b57 +mxgraph.re.editor.component.condition.edge.type.boolean=\u5e03\u5c14 + +# \u8868\u8fbe\u5f0f\u7ec4\u4ef6 +mxgraph.re.editor.component.expression.title=\u8868\u8fbe\u5f0f +mxgraph.re.editor.component.expression.entity.expression=\u8868\u8fbe\u5f0f +mxgraph.re.editor.component.expression.entity.commands=\u9644\u52a0\u6307\u4ee4\u96c6 + +# \u6307\u4ee4\u96c6\u7ec4\u4ef6 +mxgraph.re.editor.component.commandSet.title=\u6307\u4ee4\u96c6 +mxgraph.re.editor.component.commandSet.entity.commands=\u6307\u4ee4\u96c6 + +# \u8d44\u6e90\u6458\u8981\u4fe1\u606f\u7ec4\u4ef6 +mxgraph.re.editor.component.resourceAbstract.title=\u8d44\u6e90 +mxgraph.re.editor.component.resourceAbstract.entity.resource=\u8d44\u6e90 + +# \u53ef\u914d\u7f6e\u8f93\u5165\u8f93\u51fa\u6307\u4ee4\u7684\u8d44\u6e90\u6458\u8981\u4fe1\u606f\u7ec4\u4ef6 +mxgraph.re.editor.component.configurableResourceAbstract.title=\u8f93\u5165\u8f93\u51fa\u6307\u4ee4\u8d44\u6e90 +mxgraph.re.editor.component.configurableResourceAbstract.entity.resource=\u8d44\u6e90 +mxgraph.re.editor.component.configurableResourceAbstract.entity.inputCommands=\u8f93\u5165\u6307\u4ee4\u96c6 +mxgraph.re.editor.component.configurableResourceAbstract.entity.outputCommands=\u8f93\u51fa\u6307\u4ee4\u96c6 + +# \u6a21\u578b\u7ec4\u4ef6 +mxgraph.re.editor.component.submodel.title=\u5b50\u6a21\u578b +mxgraph.re.editor.component.submodel.entity.model=\u5b50\u6a21\u578b \ No newline at end of file diff --git a/io.sc.platform.attachment/gradle.properties b/io.sc.platform.attachment/gradle.properties new file mode 100644 index 00000000..27039b2c --- /dev/null +++ b/io.sc.platform.attachment/gradle.properties @@ -0,0 +1,3 @@ +commons_math3_version=3.6.1 +mxgraph_version=4.2.2.1 +jpmml_version=1.4.9 \ No newline at end of file diff --git a/io.sc.platform.core.frontend/template-project/src/views/FormElements.vue b/io.sc.platform.core.frontend/template-project/src/views/FormElements.vue index af32143c..a4261d9c 100644 --- a/io.sc.platform.core.frontend/template-project/src/views/FormElements.vue +++ b/io.sc.platform.core.frontend/template-project/src/views/FormElements.vue @@ -1,61 +1,258 @@