加入格式化代码插件,并提交格式化后的代码
This commit is contained in:
parent
1f13db48fc
commit
ec50e3a0af
|
@ -0,0 +1 @@
|
||||||
|
java-baseline=8
|
|
@ -1,6 +1,7 @@
|
||||||
package com.yomahub.liteflow.annotation;
|
package com.yomahub.liteflow.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
|
@ -9,5 +10,6 @@ import java.lang.annotation.*;
|
||||||
@Documented
|
@Documented
|
||||||
public @interface AliasFor {
|
public @interface AliasFor {
|
||||||
|
|
||||||
String value() default "";
|
String value() default "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,16 @@ package com.yomahub.liteflow.annotation;
|
||||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE})
|
@Target({ ElementType.TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface LiteflowCmpDefine {
|
public @interface LiteflowCmpDefine {
|
||||||
|
|
||||||
NodeTypeEnum value() default NodeTypeEnum.COMMON;
|
NodeTypeEnum value() default NodeTypeEnum.COMMON;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,24 +8,24 @@ import java.lang.annotation.*;
|
||||||
/**
|
/**
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.METHOD})
|
@Target({ ElementType.METHOD })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface LiteflowMethod {
|
public @interface LiteflowMethod {
|
||||||
|
|
||||||
LiteFlowMethodEnum value();
|
LiteFlowMethodEnum value();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点ID,用于区分节点
|
* 节点ID,用于区分节点 默认为空 则按照Spring模式下BeanName为准。
|
||||||
* 默认为空 则按照Spring模式下BeanName为准。
|
* @return
|
||||||
* @return
|
*/
|
||||||
*/
|
String nodeId() default "";
|
||||||
String nodeId() default "";
|
|
||||||
|
/**
|
||||||
|
* CMP类型定义
|
||||||
|
* @return AnnotationNodeTypeEnum
|
||||||
|
*/
|
||||||
|
NodeTypeEnum nodeType() default NodeTypeEnum.COMMON;
|
||||||
|
|
||||||
/**
|
|
||||||
* CMP类型定义
|
|
||||||
* @return AnnotationNodeTypeEnum
|
|
||||||
*/
|
|
||||||
NodeTypeEnum nodeType() default NodeTypeEnum.COMMON;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,18 @@ import java.lang.annotation.*;
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE,ElementType.METHOD})
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface LiteflowRetry {
|
public @interface LiteflowRetry {
|
||||||
|
|
||||||
@AliasFor("retry")
|
@AliasFor("retry")
|
||||||
int value() default 0;
|
int value() default 0;
|
||||||
|
|
||||||
@AliasFor("value")
|
@AliasFor("value")
|
||||||
int retry() default 0;
|
int retry() default 0;
|
||||||
|
|
||||||
|
Class<? extends Exception>[] forExceptions() default { Exception.class };
|
||||||
|
|
||||||
Class<? extends Exception>[] forExceptions() default {Exception.class};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,44 +11,48 @@ import java.lang.reflect.AnnotatedElement;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注解工具类
|
* 注解工具类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public class AnnoUtil {
|
public class AnnoUtil {
|
||||||
|
|
||||||
public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
|
public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
|
||||||
A annotation = AnnotationUtil.getAnnotation(annotatedElement, annotationType);
|
A annotation = AnnotationUtil.getAnnotation(annotatedElement, annotationType);
|
||||||
if (ObjectUtil.isNull(annotation)){
|
if (ObjectUtil.isNull(annotation)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> aliasMap = new HashMap<>();
|
Map<String, String> aliasMap = new HashMap<>();
|
||||||
Map<String, Object> defaultValueMap = new HashMap<>();
|
Map<String, Object> defaultValueMap = new HashMap<>();
|
||||||
Arrays.stream(ReflectUtil.getMethods(annotationType)).forEach(method -> {
|
Arrays.stream(ReflectUtil.getMethods(annotationType)).forEach(method -> {
|
||||||
AliasFor aliasFor = AnnotationUtil.getAnnotation(method, AliasFor.class);
|
AliasFor aliasFor = AnnotationUtil.getAnnotation(method, AliasFor.class);
|
||||||
if (ObjectUtil.isNotNull(aliasFor)){
|
if (ObjectUtil.isNotNull(aliasFor)) {
|
||||||
aliasMap.put(method.getName(), aliasFor.value());
|
aliasMap.put(method.getName(), aliasFor.value());
|
||||||
defaultValueMap.put(method.getName(), getDefaultValue(annotationType, method.getName()));
|
defaultValueMap.put(method.getName(), getDefaultValue(annotationType, method.getName()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
aliasMap.forEach((key, value1) -> {
|
aliasMap.forEach((key, value1) -> {
|
||||||
Object value = ReflectUtil.invoke(annotation, key);
|
Object value = ReflectUtil.invoke(annotation, key);
|
||||||
Object defaultValue = defaultValueMap.get(key);
|
Object defaultValue = defaultValueMap.get(key);
|
||||||
if (ObjectUtil.notEqual(value, defaultValue)) {
|
if (ObjectUtil.notEqual(value, defaultValue)) {
|
||||||
AnnotationUtil.setValue(annotation, value1, value);
|
AnnotationUtil.setValue(annotation, value1, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <A extends Annotation> Object getDefaultValue(Class<A> annotationType, String property) {
|
||||||
|
try {
|
||||||
|
return annotationType.getMethod(property).getDefaultValue();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static <A extends Annotation> Object getDefaultValue(Class<A> annotationType, String property){
|
|
||||||
try{
|
|
||||||
return annotationType.getMethod(property).getDefaultValue();
|
|
||||||
}catch (Exception e){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,23 +11,24 @@ package com.yomahub.liteflow.aop;
|
||||||
import com.yomahub.liteflow.slot.Slot;
|
import com.yomahub.liteflow.slot.Slot;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局组件拦截器接口
|
* 全局组件拦截器接口 实现这个接口并注入到spring上下文即可
|
||||||
* 实现这个接口并注入到spring上下文即可
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public interface ICmpAroundAspect {
|
public interface ICmpAroundAspect {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前置处理
|
* 前置处理
|
||||||
* @param nodeId 节点ID
|
* @param nodeId 节点ID
|
||||||
* @param slot
|
* @param slot
|
||||||
*/
|
*/
|
||||||
void beforeProcess(String nodeId, Slot slot);
|
void beforeProcess(String nodeId, Slot slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理
|
||||||
|
* @param nodeId 节点ID
|
||||||
|
* @param slot
|
||||||
|
*/
|
||||||
|
void afterProcess(String nodeId, Slot slot);
|
||||||
|
|
||||||
/**
|
|
||||||
* 后置处理
|
|
||||||
* @param nodeId 节点ID
|
|
||||||
* @param slot
|
|
||||||
*/
|
|
||||||
void afterProcess(String nodeId, Slot slot);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,170 +18,178 @@ import java.util.Objects;
|
||||||
|
|
||||||
public class LiteFlowNodeBuilder {
|
public class LiteFlowNodeBuilder {
|
||||||
|
|
||||||
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
private final Node node;
|
private final Node node;
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createNode() {
|
public static LiteFlowNodeBuilder createNode() {
|
||||||
return new LiteFlowNodeBuilder();
|
return new LiteFlowNodeBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createCommonNode() {
|
public static LiteFlowNodeBuilder createCommonNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.COMMON);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.COMMON);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createSwitchNode() {
|
public static LiteFlowNodeBuilder createSwitchNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.SWITCH);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createIfNode() {
|
public static LiteFlowNodeBuilder createIfNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.IF);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.IF);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createForNode() {
|
public static LiteFlowNodeBuilder createForNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.FOR);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.FOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createWhileNode() {
|
public static LiteFlowNodeBuilder createWhileNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.WHILE);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.WHILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createBreakNode() {
|
public static LiteFlowNodeBuilder createBreakNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.BREAK);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.BREAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createIteratorNode() {
|
public static LiteFlowNodeBuilder createIteratorNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.ITERATOR);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.ITERATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createScriptNode() {
|
public static LiteFlowNodeBuilder createScriptNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.SCRIPT);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createScriptSwitchNode() {
|
public static LiteFlowNodeBuilder createScriptSwitchNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.SWITCH_SCRIPT);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.SWITCH_SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createScriptIfNode() {
|
public static LiteFlowNodeBuilder createScriptIfNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.IF_SCRIPT);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.IF_SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createScriptForNode() {
|
public static LiteFlowNodeBuilder createScriptForNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.FOR_SCRIPT);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.FOR_SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createScriptWhileNode() {
|
public static LiteFlowNodeBuilder createScriptWhileNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.WHILE_SCRIPT);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.WHILE_SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteFlowNodeBuilder createScriptBreakNode() {
|
public static LiteFlowNodeBuilder createScriptBreakNode() {
|
||||||
return new LiteFlowNodeBuilder(NodeTypeEnum.BREAK_SCRIPT);
|
return new LiteFlowNodeBuilder(NodeTypeEnum.BREAK_SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder() {
|
public LiteFlowNodeBuilder() {
|
||||||
this.node = new Node();
|
this.node = new Node();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder(NodeTypeEnum type) {
|
public LiteFlowNodeBuilder(NodeTypeEnum type) {
|
||||||
this.node = new Node();
|
this.node = new Node();
|
||||||
this.node.setType(type);
|
this.node.setType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setId(String nodeId) {
|
public LiteFlowNodeBuilder setId(String nodeId) {
|
||||||
if (StrUtil.isBlank(nodeId)) {
|
if (StrUtil.isBlank(nodeId)) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
this.node.setId(nodeId.trim());
|
this.node.setId(nodeId.trim());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setName(String name) {
|
public LiteFlowNodeBuilder setName(String name) {
|
||||||
if (StrUtil.isBlank(name)) {
|
if (StrUtil.isBlank(name)) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
this.node.setName(name.trim());
|
this.node.setName(name.trim());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setClazz(String clazz) {
|
public LiteFlowNodeBuilder setClazz(String clazz) {
|
||||||
if (StrUtil.isBlank(clazz)) {
|
if (StrUtil.isBlank(clazz)) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
this.node.setClazz(clazz.trim());
|
this.node.setClazz(clazz.trim());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setClazz(Class<?> clazz) {
|
public LiteFlowNodeBuilder setClazz(Class<?> clazz) {
|
||||||
assert clazz != null;
|
assert clazz != null;
|
||||||
setClazz(clazz.getName());
|
setClazz(clazz.getName());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setType(NodeTypeEnum type) {
|
public LiteFlowNodeBuilder setType(NodeTypeEnum type) {
|
||||||
this.node.setType(type);
|
this.node.setType(type);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setScript(String script) {
|
public LiteFlowNodeBuilder setScript(String script) {
|
||||||
this.node.setScript(script);
|
this.node.setScript(script);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setFile(String filePath) {
|
public LiteFlowNodeBuilder setFile(String filePath) {
|
||||||
if (StrUtil.isBlank(filePath)) {
|
if (StrUtil.isBlank(filePath)) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
List<String> scriptList = PathContentParserHolder.loadContextAware().parseContent(ListUtil.toList(filePath));
|
List<String> scriptList = PathContentParserHolder.loadContextAware()
|
||||||
String script = CollUtil.getFirst(scriptList);
|
.parseContent(ListUtil.toList(filePath));
|
||||||
setScript(script);
|
String script = CollUtil.getFirst(scriptList);
|
||||||
|
setScript(script);
|
||||||
|
|
||||||
// 添加脚本文件监听
|
// 添加脚本文件监听
|
||||||
List<String> fileAbsolutePath = PathContentParserHolder.loadContextAware().getFileAbsolutePath(ListUtil.toList(filePath));
|
List<String> fileAbsolutePath = PathContentParserHolder.loadContextAware()
|
||||||
MonitorFile.getInstance().addMonitorFilePaths(fileAbsolutePath);
|
.getFileAbsolutePath(ListUtil.toList(filePath));
|
||||||
} catch (Exception e) {
|
MonitorFile.getInstance().addMonitorFilePaths(fileAbsolutePath);
|
||||||
String errMsg = StrUtil.format("An exception occurred while building the node[{}],{}", this.node.getId(), e.getMessage());
|
}
|
||||||
throw new NodeBuildException(errMsg);
|
catch (Exception e) {
|
||||||
}
|
String errMsg = StrUtil.format("An exception occurred while building the node[{}],{}", this.node.getId(),
|
||||||
return this;
|
e.getMessage());
|
||||||
}
|
throw new NodeBuildException(errMsg);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LiteFlowNodeBuilder setLanguage(String language) {
|
public LiteFlowNodeBuilder setLanguage(String language) {
|
||||||
this.node.setLanguage(language);
|
this.node.setLanguage(language);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build() {
|
public void build() {
|
||||||
checkBuild();
|
checkBuild();
|
||||||
try {
|
try {
|
||||||
// 用于处理脚本 node
|
// 用于处理脚本 node
|
||||||
if (this.node.getType().isScript()){
|
if (this.node.getType().isScript()) {
|
||||||
FlowBus.addScriptNode(this.node.getId(), this.node.getName(), this.node.getType(), this.node.getScript(), this.node.getLanguage());
|
FlowBus.addScriptNode(this.node.getId(), this.node.getName(), this.node.getType(),
|
||||||
}
|
this.node.getScript(), this.node.getLanguage());
|
||||||
// 用于处理普通 node
|
}
|
||||||
else{
|
// 用于处理普通 node
|
||||||
FlowBus.addNode(this.node.getId(), this.node.getName(), this.node.getType(), this.node.getClazz());
|
else {
|
||||||
}
|
FlowBus.addNode(this.node.getId(), this.node.getName(), this.node.getType(), this.node.getClazz());
|
||||||
} catch (Exception e) {
|
}
|
||||||
String errMsg = StrUtil.format("An exception occurred while building the node[{}],{}", this.node.getId(), e.getMessage());
|
}
|
||||||
LOG.error(errMsg, e);
|
catch (Exception e) {
|
||||||
throw new NodeBuildException(errMsg);
|
String errMsg = StrUtil.format("An exception occurred while building the node[{}],{}", this.node.getId(),
|
||||||
}
|
e.getMessage());
|
||||||
}
|
LOG.error(errMsg, e);
|
||||||
|
throw new NodeBuildException(errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build 前简单校验
|
||||||
|
*/
|
||||||
|
private void checkBuild() {
|
||||||
|
List<String> errorList = new ArrayList<>();
|
||||||
|
if (StrUtil.isBlank(this.node.getId())) {
|
||||||
|
errorList.add("id is blank");
|
||||||
|
}
|
||||||
|
if (Objects.isNull(this.node.getType())) {
|
||||||
|
errorList.add("type is null");
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(errorList)) {
|
||||||
|
throw new NodeBuildException(CollUtil.join(errorList, ",", "[", "]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* build 前简单校验
|
|
||||||
*/
|
|
||||||
private void checkBuild() {
|
|
||||||
List<String> errorList = new ArrayList<>();
|
|
||||||
if (StrUtil.isBlank(this.node.getId())) {
|
|
||||||
errorList.add("id is blank");
|
|
||||||
}
|
|
||||||
if (Objects.isNull(this.node.getType())) {
|
|
||||||
errorList.add("type is null");
|
|
||||||
}
|
|
||||||
if (CollUtil.isNotEmpty(errorList)) {
|
|
||||||
throw new NodeBuildException(CollUtil.join(errorList, ",", "[", "]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,238 +25,245 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chain基于代码形式的组装器
|
* Chain基于代码形式的组装器 EL表达式规则专属组装器
|
||||||
* EL表达式规则专属组装器
|
|
||||||
*
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.8.0
|
* @since 2.8.0
|
||||||
*/
|
*/
|
||||||
public class LiteFlowChainELBuilder {
|
public class LiteFlowChainELBuilder {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(LiteFlowChainELBuilder.class);
|
private static final Logger LOG = LoggerFactory.getLogger(LiteFlowChainELBuilder.class);
|
||||||
|
|
||||||
|
private Chain chain;
|
||||||
|
|
||||||
private Chain chain;
|
/**
|
||||||
|
* //这是主体的Condition //声明这个变量,而不是用chain.getConditionList的目的,是为了辅助平滑加载
|
||||||
|
* //虽然FlowBus里面的map都是CopyOnWrite类型的,但是在buildCondition的时候,为了平滑加载,所以不能事先把chain.getConditionList给设为空List
|
||||||
|
* //所以在这里做一个缓存,等conditionList全部build完毕后,再去一次性替换chain里面的conditionList
|
||||||
|
*/
|
||||||
|
private final List<Condition> conditionList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* //这是主体的Condition
|
* EL解析引擎
|
||||||
* //声明这个变量,而不是用chain.getConditionList的目的,是为了辅助平滑加载
|
*/
|
||||||
* //虽然FlowBus里面的map都是CopyOnWrite类型的,但是在buildCondition的时候,为了平滑加载,所以不能事先把chain.getConditionList给设为空List
|
public final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();
|
||||||
* //所以在这里做一个缓存,等conditionList全部build完毕后,再去一次性替换chain里面的conditionList
|
|
||||||
*/
|
|
||||||
private final List<Condition> conditionList;
|
|
||||||
|
|
||||||
/**
|
static {
|
||||||
* EL解析引擎
|
// 初始化QLExpress的Runner
|
||||||
*/
|
EXPRESS_RUNNER.addFunction(ChainConstant.THEN, new ThenOperator());
|
||||||
public final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();
|
EXPRESS_RUNNER.addFunction(ChainConstant.WHEN, new WhenOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.SWITCH, new SwitchOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.PRE, new PreOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.FINALLY, new FinallyOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.IF, new IfOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.NODE.toUpperCase(), new NodeOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.NODE, new NodeOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.FOR, new ForOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.WHILE, new WhileOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.ITERATOR, new IteratorOperator());
|
||||||
|
EXPRESS_RUNNER.addFunction(ChainConstant.CATCH, new CatchOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ELSE, Object.class, new ElseOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ELIF, Object.class, new ElifOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TO, Object.class, new ToOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TO.toLowerCase(), Object.class, new ToOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DEFAULT, Object.class, new DefaultOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TAG, Object.class, new TagOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ANY, Object.class, new AnyOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ID, Object.class, new IdOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.IGNORE_ERROR, Object.class, new IgnoreErrorOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.THREAD_POOL, Object.class, new ThreadPoolOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DO, Object.class, new DoOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.BREAK, Object.class, new BreakOperator());
|
||||||
|
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DATA, Object.class, new DataOperator());
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
public static LiteFlowChainELBuilder createChain() {
|
||||||
//初始化QLExpress的Runner
|
return new LiteFlowChainELBuilder();
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.THEN, new ThenOperator());
|
}
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.WHEN, new WhenOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.SWITCH, new SwitchOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.PRE, new PreOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.FINALLY, new FinallyOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.IF, new IfOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.NODE.toUpperCase(), new NodeOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.NODE, new NodeOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.FOR, new ForOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.WHILE, new WhileOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.ITERATOR, new IteratorOperator());
|
|
||||||
EXPRESS_RUNNER.addFunction(ChainConstant.CATCH, new CatchOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ELSE, Object.class, new ElseOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ELIF, Object.class, new ElifOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TO, Object.class, new ToOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TO.toLowerCase(), Object.class, new ToOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DEFAULT, Object.class, new DefaultOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TAG, Object.class, new TagOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ANY, Object.class, new AnyOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ID, Object.class, new IdOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.IGNORE_ERROR, Object.class, new IgnoreErrorOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.THREAD_POOL, Object.class, new ThreadPoolOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DO, Object.class, new DoOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.BREAK, Object.class, new BreakOperator());
|
|
||||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DATA, Object.class, new DataOperator());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LiteFlowChainELBuilder createChain() {
|
public LiteFlowChainELBuilder() {
|
||||||
return new LiteFlowChainELBuilder();
|
chain = new Chain();
|
||||||
}
|
conditionList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
public LiteFlowChainELBuilder() {
|
// 在parser中chain的build是2段式的,因为涉及到依赖问题,以前是递归parser
|
||||||
chain = new Chain();
|
// 2.6.8之后取消了递归的模式,两段式组装,先把带有chainName的chain对象放进去,第二段再组装chain里面的condition
|
||||||
conditionList = new ArrayList<>();
|
// 所以这里setChainName的时候需要判断下
|
||||||
}
|
|
||||||
|
|
||||||
//在parser中chain的build是2段式的,因为涉及到依赖问题,以前是递归parser
|
/**
|
||||||
//2.6.8之后取消了递归的模式,两段式组装,先把带有chainName的chain对象放进去,第二段再组装chain里面的condition
|
* @return LiteFlowChainELBuilder
|
||||||
//所以这里setChainName的时候需要判断下
|
* @deprecated 请使用 {@link #setChainId(String)}
|
||||||
|
*/
|
||||||
|
public LiteFlowChainELBuilder setChainName(String chainName) {
|
||||||
|
if (FlowBus.containChain(chainName)) {
|
||||||
|
this.chain = FlowBus.getChain(chainName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.chain.setChainName(chainName);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public LiteFlowChainELBuilder setChainId(String chainId) {
|
||||||
* @return LiteFlowChainELBuilder
|
if (FlowBus.containChain(chainId)) {
|
||||||
* @deprecated 请使用 {@link #setChainId(String)}
|
this.chain = FlowBus.getChain(chainId);
|
||||||
*/
|
}
|
||||||
public LiteFlowChainELBuilder setChainName(String chainName) {
|
else {
|
||||||
if (FlowBus.containChain(chainName)) {
|
this.chain.setChainId(chainId);
|
||||||
this.chain = FlowBus.getChain(chainName);
|
}
|
||||||
} else {
|
return this;
|
||||||
this.chain.setChainName(chainName);
|
}
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiteFlowChainELBuilder setChainId(String chainId) {
|
public LiteFlowChainELBuilder setEL(String elStr) {
|
||||||
if (FlowBus.containChain(chainId)) {
|
if (StrUtil.isBlank(elStr)) {
|
||||||
this.chain = FlowBus.getChain(chainId);
|
String errMsg = StrUtil.format("no content in this chain[{}]", chain.getChainId());
|
||||||
} else {
|
throw new FlowSystemException(errMsg);
|
||||||
this.chain.setChainId(chainId);
|
}
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiteFlowChainELBuilder setEL(String elStr) {
|
List<String> errorList = new ArrayList<>();
|
||||||
if (StrUtil.isBlank(elStr)) {
|
try {
|
||||||
String errMsg = StrUtil.format("no content in this chain[{}]", chain.getChainId());
|
DefaultContext<String, Object> context = new DefaultContext<>();
|
||||||
throw new FlowSystemException(errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> errorList = new ArrayList<>();
|
// 这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain
|
||||||
try {
|
// 往上下文里放入所有的chain,是的el表达式可以直接引用到chain
|
||||||
DefaultContext<String, Object> context = new DefaultContext<>();
|
FlowBus.getChainMap().values().forEach(chain -> context.put(chain.getChainId(), chain));
|
||||||
|
|
||||||
//这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain
|
// 往上下文里放入所有的node,使得el表达式可以直接引用到nodeId
|
||||||
//往上下文里放入所有的chain,是的el表达式可以直接引用到chain
|
FlowBus.getNodeMap().keySet().forEach(nodeId -> context.put(nodeId, FlowBus.getNode(nodeId)));
|
||||||
FlowBus.getChainMap().values().forEach(chain -> context.put(chain.getChainId(), chain));
|
|
||||||
|
|
||||||
//往上下文里放入所有的node,使得el表达式可以直接引用到nodeId
|
// 放入当前主chain的ID
|
||||||
FlowBus.getNodeMap().keySet().forEach(nodeId -> context.put(nodeId, FlowBus.getNode(nodeId)));
|
context.put(ChainConstant.CURR_CHAIN_ID, this.chain.getChainId());
|
||||||
|
|
||||||
//放入当前主chain的ID
|
// 解析el成为一个Condition
|
||||||
context.put(ChainConstant.CURR_CHAIN_ID, this.chain.getChainId());
|
// 为什么这里只是一个Condition,而不是一个List<Condition>呢
|
||||||
|
// 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样
|
||||||
|
Condition condition = (Condition) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true);
|
||||||
|
|
||||||
//解析el成为一个Condition
|
// 从condition的第一层嵌套结构里拿出Pre和Finally节点
|
||||||
//为什么这里只是一个Condition,而不是一个List<Condition>呢
|
// 为什么只寻找第一层,而不往下寻找了呢?
|
||||||
//这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样
|
// 因为这是一个规范,如果在后面的层级中出现pre和finally,语义上也不好理解,所以pre和finally只能定义在第一层
|
||||||
Condition condition = (Condition) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true);
|
// 如果硬是要在后面定义,则执行的时候会忽略,相关代码已做了判断
|
||||||
|
/*
|
||||||
|
* for (Executable executable : condition.getExecutableList()) { if
|
||||||
|
* (executable instanceof PreCondition) {
|
||||||
|
* this.preConditionList.add((PreCondition) executable); } else if (executable
|
||||||
|
* instanceof FinallyCondition) {
|
||||||
|
* this.finallyConditionList.add((FinallyCondition) executable); } }
|
||||||
|
*/
|
||||||
|
|
||||||
//从condition的第一层嵌套结构里拿出Pre和Finally节点
|
// 把主要的condition加入
|
||||||
//为什么只寻找第一层,而不往下寻找了呢?
|
this.conditionList.add(condition);
|
||||||
//因为这是一个规范,如果在后面的层级中出现pre和finally,语义上也不好理解,所以pre和finally只能定义在第一层
|
return this;
|
||||||
//如果硬是要在后面定义,则执行的时候会忽略,相关代码已做了判断
|
}
|
||||||
/*for (Executable executable : condition.getExecutableList()) {
|
catch (QLException e) {
|
||||||
if (executable instanceof PreCondition) {
|
// EL 底层会包装异常,这里是曲线处理
|
||||||
this.preConditionList.add((PreCondition) executable);
|
if (Objects.equals(e.getCause().getMessage(), DataNotFoundException.MSG)) {
|
||||||
} else if (executable instanceof FinallyCondition) {
|
// 构建错误信息
|
||||||
this.finallyConditionList.add((FinallyCondition) executable);
|
String msg = buildDataNotFoundExceptionMsg(elStr);
|
||||||
}
|
throw new ELParseException(msg);
|
||||||
}*/
|
}
|
||||||
|
throw new ELParseException(e.getCause().getMessage());
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new ELParseException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//把主要的condition加入
|
/**
|
||||||
this.conditionList.add(condition);
|
* EL表达式校验
|
||||||
return this;
|
* @param elStr EL表达式
|
||||||
} catch (QLException e) {
|
* @return true 校验成功 false 校验失败
|
||||||
// EL 底层会包装异常,这里是曲线处理
|
*/
|
||||||
if (Objects.equals(e.getCause().getMessage(), DataNotFoundException.MSG)) {
|
public static boolean validate(String elStr) {
|
||||||
// 构建错误信息
|
try {
|
||||||
String msg = buildDataNotFoundExceptionMsg(elStr);
|
LiteFlowChainELBuilder.createChain().setEL(elStr);
|
||||||
throw new ELParseException(msg);
|
return Boolean.TRUE;
|
||||||
}
|
}
|
||||||
throw new ELParseException(e.getCause().getMessage());
|
catch (ELParseException e) {
|
||||||
} catch (Exception e) {
|
LOG.error(e.getMessage());
|
||||||
throw new ELParseException(e.getMessage());
|
}
|
||||||
}
|
return Boolean.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void build() {
|
||||||
* EL表达式校验
|
this.chain.setConditionList(this.conditionList);
|
||||||
*
|
|
||||||
* @param elStr EL表达式
|
|
||||||
* @return true 校验成功 false 校验失败
|
|
||||||
*/
|
|
||||||
public static boolean validate(String elStr) {
|
|
||||||
try {
|
|
||||||
LiteFlowChainELBuilder.createChain().setEL(elStr);
|
|
||||||
return Boolean.TRUE;
|
|
||||||
} catch (ELParseException e) {
|
|
||||||
LOG.error(e.getMessage());
|
|
||||||
}
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void build() {
|
checkBuild();
|
||||||
this.chain.setConditionList(this.conditionList);
|
|
||||||
|
|
||||||
checkBuild();
|
FlowBus.addChain(this.chain);
|
||||||
|
}
|
||||||
|
|
||||||
FlowBus.addChain(this.chain);
|
// #region private method
|
||||||
}
|
|
||||||
|
|
||||||
//#region private method
|
/**
|
||||||
|
* build 前简单校验
|
||||||
|
*/
|
||||||
|
private void checkBuild() {
|
||||||
|
List<String> errorList = new ArrayList<>();
|
||||||
|
if (StrUtil.isBlank(this.chain.getChainId())) {
|
||||||
|
errorList.add("name is blank");
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(errorList)) {
|
||||||
|
throw new RuntimeException(CollUtil.join(errorList, ",", "[", "]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* build 前简单校验
|
* 解析 EL 表达式,查找未定义的 id 并构建错误信息
|
||||||
*/
|
* @param elStr el 表达式
|
||||||
private void checkBuild() {
|
*/
|
||||||
List<String> errorList = new ArrayList<>();
|
private String buildDataNotFoundExceptionMsg(String elStr) {
|
||||||
if (StrUtil.isBlank(this.chain.getChainId())) {
|
String msg = String.format("[node/chain is not exist or node/chain not register]\n EL: %s",
|
||||||
errorList.add("name is blank");
|
StrUtil.trim(elStr));
|
||||||
}
|
try {
|
||||||
if (CollUtil.isNotEmpty(errorList)) {
|
InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr);
|
||||||
throw new RuntimeException(CollUtil.join(errorList, ",", "[", "]"));
|
if (parseResult == null) {
|
||||||
}
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
String[] outAttrNames = parseResult.getOutAttrNames();
|
||||||
* 解析 EL 表达式,查找未定义的 id 并构建错误信息
|
if (ArrayUtil.isEmpty(outAttrNames)) {
|
||||||
*
|
return msg;
|
||||||
* @param elStr el 表达式
|
}
|
||||||
*/
|
|
||||||
private String buildDataNotFoundExceptionMsg(String elStr) {
|
|
||||||
String msg = String.format("[node/chain is not exist or node/chain not register]\n EL: %s", StrUtil.trim(elStr));
|
|
||||||
try {
|
|
||||||
InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr);
|
|
||||||
if (parseResult == null) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] outAttrNames = parseResult.getOutAttrNames();
|
List<String> chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true);
|
||||||
if (ArrayUtil.isEmpty(outAttrNames)) {
|
List<String> nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true);
|
||||||
return msg;
|
for (String attrName : outAttrNames) {
|
||||||
}
|
if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) {
|
||||||
|
msg = String.format(
|
||||||
|
"[%s] is not exist or [%s] is not registered, you need to define a node or chain with id [%s] and register it \n EL: ",
|
||||||
|
attrName, attrName, attrName);
|
||||||
|
|
||||||
List<String> chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true);
|
// 去除 EL 表达式中的空格和换行符
|
||||||
List<String> nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true);
|
String sourceEl = StrUtil.removeAll(elStr, CharUtil.SPACE, CharUtil.LF, CharUtil.CR);
|
||||||
for (String attrName : outAttrNames) {
|
// 这里需要注意的是,nodeId 和 chainId 可能是关键字的一部分,如果直接 indexOf(attrName) 会出现误判
|
||||||
if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) {
|
// 所以需要判断 attrName 前后是否有 ","
|
||||||
msg = String.format("[%s] is not exist or [%s] is not registered, you need to define a node or chain with id [%s] and register it \n EL: ", attrName, attrName, attrName);
|
int commaRightIndex = sourceEl.indexOf(attrName + StrUtil.COMMA);
|
||||||
|
if (commaRightIndex != -1) {
|
||||||
|
// 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1
|
||||||
|
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true);
|
||||||
|
}
|
||||||
|
int commaLeftIndex = sourceEl.indexOf(StrUtil.COMMA + attrName);
|
||||||
|
if (commaLeftIndex != -1) {
|
||||||
|
// 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,再加上 "," 的长度 1,indexOf 从 0
|
||||||
|
// 开始,所以还需要加 1
|
||||||
|
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true);
|
||||||
|
}
|
||||||
|
// 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a")
|
||||||
|
int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName));
|
||||||
|
if (nodeIndex != -1) {
|
||||||
|
// 需要加上 "EL: " 的长度 4,再加上 “node("” 长度 6,再加上 "^" 的长度 1,indexOf 从 0
|
||||||
|
// 开始,所以还需要加 1
|
||||||
|
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
// 去除 EL 表达式中的空格和换行符
|
|
||||||
String sourceEl = StrUtil.removeAll(elStr, CharUtil.SPACE, CharUtil.LF, CharUtil.CR);
|
|
||||||
// 这里需要注意的是,nodeId 和 chainId 可能是关键字的一部分,如果直接 indexOf(attrName) 会出现误判
|
|
||||||
// 所以需要判断 attrName 前后是否有 ","
|
|
||||||
int commaRightIndex = sourceEl.indexOf(attrName + StrUtil.COMMA);
|
|
||||||
if (commaRightIndex != -1) {
|
|
||||||
// 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1
|
|
||||||
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true);
|
|
||||||
}
|
|
||||||
int commaLeftIndex = sourceEl.indexOf(StrUtil.COMMA + attrName);
|
|
||||||
if (commaLeftIndex != -1) {
|
|
||||||
// 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,再加上 "," 的长度 1,indexOf 从 0 开始,所以还需要加 1
|
|
||||||
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true);
|
|
||||||
}
|
|
||||||
// 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a")
|
|
||||||
int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName));
|
|
||||||
if (nodeIndex != -1) {
|
|
||||||
// 需要加上 "EL: " 的长度 4,再加上 “node("” 长度 6,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1
|
|
||||||
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,15 @@ import com.yomahub.liteflow.flow.element.condition.WhenCondition;
|
||||||
*/
|
*/
|
||||||
public class AnyOperator extends BaseOperator<WhenCondition> {
|
public class AnyOperator extends BaseOperator<WhenCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WhenCondition build(Object[] objects) throws Exception {
|
public WhenCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
|
|
||||||
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
|
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
|
||||||
|
|
||||||
|
Boolean any = OperatorHelper.convert(objects[1], Boolean.class);
|
||||||
|
whenCondition.setAny(any);
|
||||||
|
return whenCondition;
|
||||||
|
}
|
||||||
|
|
||||||
Boolean any = OperatorHelper.convert(objects[1], Boolean.class);
|
|
||||||
whenCondition.setAny(any);
|
|
||||||
return whenCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,30 @@ import com.yomahub.liteflow.flow.element.Node;
|
||||||
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
|
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL规则中的BREAK的操作符
|
* EL规则中的BREAK的操作符 有两种用法 FOR...DO...BREAK WHILE...DO...BREAK
|
||||||
* 有两种用法
|
|
||||||
* FOR...DO...BREAK
|
|
||||||
* WHILE...DO...BREAK
|
|
||||||
*
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class BreakOperator extends BaseOperator<LoopCondition> {
|
public class BreakOperator extends BaseOperator<LoopCondition> {
|
||||||
@Override
|
|
||||||
public LoopCondition build(Object[] objects) throws Exception {
|
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
|
||||||
|
|
||||||
//DO关键字有可能用在FOR后面,也有可能用于WHILE后面,所以这里要进行判断是不是这两种类型的超类LoopCondition
|
@Override
|
||||||
String errorMsg = "The caller must be ForCondition or WhileCondition item";
|
public LoopCondition build(Object[] objects) throws Exception {
|
||||||
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
|
|
||||||
|
// DO关键字有可能用在FOR后面,也有可能用于WHILE后面,所以这里要进行判断是不是这两种类型的超类LoopCondition
|
||||||
|
String errorMsg = "The caller must be ForCondition or WhileCondition item";
|
||||||
|
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
|
||||||
|
|
||||||
|
// 获得需要执行的可执行表达式
|
||||||
|
Node breakNode = OperatorHelper.convert(objects[1], Node.class);
|
||||||
|
if (ListUtil.toList(NodeTypeEnum.BREAK, NodeTypeEnum.BREAK_SCRIPT).contains(breakNode.getType())) {
|
||||||
|
condition.setBreakNode(breakNode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new QLException("The parameter must be node-break item");
|
||||||
|
}
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
//获得需要执行的可执行表达式
|
|
||||||
Node breakNode = OperatorHelper.convert(objects[1], Node.class);
|
|
||||||
if (ListUtil.toList(NodeTypeEnum.BREAK, NodeTypeEnum.BREAK_SCRIPT).contains(breakNode.getType())) {
|
|
||||||
condition.setBreakNode(breakNode);
|
|
||||||
} else {
|
|
||||||
throw new QLException("The parameter must be node-break item");
|
|
||||||
}
|
|
||||||
return condition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,21 +6,23 @@ import com.yomahub.liteflow.flow.element.Executable;
|
||||||
import com.yomahub.liteflow.flow.element.condition.CatchCondition;
|
import com.yomahub.liteflow.flow.element.condition.CatchCondition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL规则中的CATCH的操作符
|
* EL规则中的CATCH的操作符 用法:CATCH...DO...
|
||||||
* 用法:CATCH...DO...
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.10.0
|
* @since 2.10.0
|
||||||
*/
|
*/
|
||||||
public class CatchOperator extends BaseOperator<CatchCondition> {
|
public class CatchOperator extends BaseOperator<CatchCondition> {
|
||||||
@Override
|
|
||||||
public CatchCondition build(Object[] objects) throws Exception {
|
|
||||||
OperatorHelper.checkObjectSizeEq(objects, 1);
|
|
||||||
|
|
||||||
Executable catchItem = OperatorHelper.convert(objects[0], Executable.class);
|
@Override
|
||||||
|
public CatchCondition build(Object[] objects) throws Exception {
|
||||||
|
OperatorHelper.checkObjectSizeEq(objects, 1);
|
||||||
|
|
||||||
CatchCondition catchCondition = new CatchCondition();
|
Executable catchItem = OperatorHelper.convert(objects[0], Executable.class);
|
||||||
catchCondition.setCatchItem(catchItem);
|
|
||||||
|
CatchCondition catchCondition = new CatchCondition();
|
||||||
|
catchCondition.setCatchItem(catchItem);
|
||||||
|
|
||||||
|
return catchCondition;
|
||||||
|
}
|
||||||
|
|
||||||
return catchCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,17 @@ import com.yomahub.liteflow.flow.element.Node;
|
||||||
*/
|
*/
|
||||||
public class DataOperator extends BaseOperator<Node> {
|
public class DataOperator extends BaseOperator<Node> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node build(Object[] objects) throws Exception {
|
public Node build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
|
|
||||||
Node node = OperatorHelper.convert(objects[0], Node.class);
|
Node node = OperatorHelper.convert(objects[0], Node.class);
|
||||||
|
|
||||||
String cmpData = OperatorHelper.convert(objects[1], String.class);
|
String cmpData = OperatorHelper.convert(objects[1], String.class);
|
||||||
|
|
||||||
node.setCmpData(cmpData);
|
node.setCmpData(cmpData);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,16 @@ import com.yomahub.liteflow.flow.element.condition.SwitchCondition;
|
||||||
*/
|
*/
|
||||||
public class DefaultOperator extends BaseOperator<SwitchCondition> {
|
public class DefaultOperator extends BaseOperator<SwitchCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SwitchCondition build(Object[] objects) throws Exception {
|
public SwitchCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
|
|
||||||
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
|
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
|
||||||
|
|
||||||
Executable target = OperatorHelper.convert(objects[1], Executable.class);
|
Executable target = OperatorHelper.convert(objects[1], Executable.class);
|
||||||
switchCondition.setDefaultExecutor(target);
|
switchCondition.setDefaultExecutor(target);
|
||||||
|
|
||||||
|
return switchCondition;
|
||||||
|
}
|
||||||
|
|
||||||
return switchCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,38 +9,38 @@ import com.yomahub.liteflow.flow.element.condition.Condition;
|
||||||
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
|
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL规则中的DO的操作符
|
* EL规则中的DO的操作符 有三种用法 FOR...DO...BREAK WHILE...DO...BREAK CATCH...DO
|
||||||
* 有三种用法
|
|
||||||
* FOR...DO...BREAK
|
|
||||||
* WHILE...DO...BREAK
|
|
||||||
* CATCH...DO
|
|
||||||
*
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class DoOperator extends BaseOperator<Condition> {
|
public class DoOperator extends BaseOperator<Condition> {
|
||||||
@Override
|
|
||||||
public Condition build(Object[] objects) throws Exception {
|
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
|
||||||
|
|
||||||
if (objects[0] instanceof CatchCondition){
|
@Override
|
||||||
String errorMsg = "The caller must be CatchCondition item";
|
public Condition build(Object[] objects) throws Exception {
|
||||||
CatchCondition condition = OperatorHelper.convert(objects[0], CatchCondition.class, errorMsg);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
//获得需要执行的可执行表达式
|
|
||||||
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
if (objects[0] instanceof CatchCondition) {
|
||||||
condition.setDoItem(doExecutableItem);
|
String errorMsg = "The caller must be CatchCondition item";
|
||||||
return condition;
|
CatchCondition condition = OperatorHelper.convert(objects[0], CatchCondition.class, errorMsg);
|
||||||
}else if(objects[0] instanceof LoopCondition){
|
// 获得需要执行的可执行表达式
|
||||||
String errorMsg = "The caller must be LoopCondition item";
|
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
||||||
//DO关键字有可能用在FOR后面,也有可能用于WHILE后面,所以这里要进行判断是不是这两种类型的超类LoopCondition
|
condition.setDoItem(doExecutableItem);
|
||||||
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
|
return condition;
|
||||||
//获得需要执行的可执行表达式
|
}
|
||||||
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
else if (objects[0] instanceof LoopCondition) {
|
||||||
condition.setDoExecutor(doExecutableItem);
|
String errorMsg = "The caller must be LoopCondition item";
|
||||||
return condition;
|
// DO关键字有可能用在FOR后面,也有可能用于WHILE后面,所以这里要进行判断是不是这两种类型的超类LoopCondition
|
||||||
}else{
|
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
|
||||||
String errorMsg = "The caller must be LoopCondition or CatchCondition item";
|
// 获得需要执行的可执行表达式
|
||||||
throw new QLException(errorMsg);
|
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
||||||
}
|
condition.setDoExecutor(doExecutableItem);
|
||||||
}
|
return condition;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String errorMsg = "The caller must be LoopCondition or CatchCondition item";
|
||||||
|
throw new QLException(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,35 +21,37 @@ public class ElifOperator extends BaseOperator<IfCondition> {
|
||||||
public IfCondition build(Object[] objects) throws Exception {
|
public IfCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEqThree(objects);
|
OperatorHelper.checkObjectSizeEqThree(objects);
|
||||||
|
|
||||||
//解析caller
|
// 解析caller
|
||||||
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
|
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
|
||||||
|
|
||||||
//解析第一个参数
|
// 解析第一个参数
|
||||||
Node ifNode = OperatorHelper.convert(objects[1], Node.class);
|
Node ifNode = OperatorHelper.convert(objects[1], Node.class);
|
||||||
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
|
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
|
||||||
throw new QLException("The first parameter must be If item");
|
throw new QLException("The first parameter must be If item");
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析第二个参数
|
// 解析第二个参数
|
||||||
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
|
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
|
||||||
|
|
||||||
//构建一个内部的IfCondition
|
// 构建一个内部的IfCondition
|
||||||
IfCondition ifConditionItem = new IfCondition();
|
IfCondition ifConditionItem = new IfCondition();
|
||||||
ifConditionItem.setIfNode(ifNode);
|
ifConditionItem.setIfNode(ifNode);
|
||||||
ifConditionItem.setTrueCaseExecutableItem(trueCaseExecutableItem);
|
ifConditionItem.setTrueCaseExecutableItem(trueCaseExecutableItem);
|
||||||
|
|
||||||
//因为可能会有多个ELIF,所以每一次拿到的caller总是最开始大的if,需要遍历到没有falseCaseExecutable的地方。
|
// 因为可能会有多个ELIF,所以每一次拿到的caller总是最开始大的if,需要遍历到没有falseCaseExecutable的地方。
|
||||||
//塞进去是一个新的IfCondition
|
// 塞进去是一个新的IfCondition
|
||||||
IfCondition loopIfCondition = ifCondition;
|
IfCondition loopIfCondition = ifCondition;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (loopIfCondition.getFalseCaseExecutableItem() == null) {
|
if (loopIfCondition.getFalseCaseExecutableItem() == null) {
|
||||||
loopIfCondition.setFalseCaseExecutableItem(ifConditionItem);
|
loopIfCondition.setFalseCaseExecutableItem(ifConditionItem);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
loopIfCondition = (IfCondition) loopIfCondition.getFalseCaseExecutableItem();
|
loopIfCondition = (IfCondition) loopIfCondition.getFalseCaseExecutableItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ifCondition;
|
return ifCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,13 @@ public class ElseOperator extends BaseOperator<IfCondition> {
|
||||||
if (loopIfCondition.getFalseCaseExecutableItem() == null) {
|
if (loopIfCondition.getFalseCaseExecutableItem() == null) {
|
||||||
loopIfCondition.setFalseCaseExecutableItem(elseExecutableItem);
|
loopIfCondition.setFalseCaseExecutableItem(elseExecutableItem);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
loopIfCondition = (IfCondition) loopIfCondition.getFalseCaseExecutableItem();
|
loopIfCondition = (IfCondition) loopIfCondition.getFalseCaseExecutableItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ifCondition;
|
return ifCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,5 @@ public class FinallyOperator extends BaseOperator<FinallyCondition> {
|
||||||
}
|
}
|
||||||
return finallyCondition;
|
return finallyCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,34 +19,38 @@ import com.yomahub.liteflow.flow.element.condition.ForCondition;
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class ForOperator extends BaseOperator<ForCondition> {
|
public class ForOperator extends BaseOperator<ForCondition> {
|
||||||
@Override
|
|
||||||
public ForCondition build(Object[] objects) throws Exception {
|
|
||||||
OperatorHelper.checkObjectSizeEq(objects, 1);
|
|
||||||
|
|
||||||
Node node;
|
@Override
|
||||||
if (objects[0] instanceof Node) {
|
public ForCondition build(Object[] objects) throws Exception {
|
||||||
node = OperatorHelper.convert(objects[0], Node.class);
|
OperatorHelper.checkObjectSizeEq(objects, 1);
|
||||||
if (!ListUtil.toList(NodeTypeEnum.FOR, NodeTypeEnum.FOR_SCRIPT).contains(node.getType())) {
|
|
||||||
throw new QLException("The parameter must be for-node item");
|
Node node;
|
||||||
}
|
if (objects[0] instanceof Node) {
|
||||||
}else if(objects[0] instanceof Integer){
|
node = OperatorHelper.convert(objects[0], Node.class);
|
||||||
Integer forCount = OperatorHelper.convert(objects[0], Integer.class);
|
if (!ListUtil.toList(NodeTypeEnum.FOR, NodeTypeEnum.FOR_SCRIPT).contains(node.getType())) {
|
||||||
node = new Node();
|
throw new QLException("The parameter must be for-node item");
|
||||||
NodeForComponent nodeForComponent = new NodeForComponent() {
|
}
|
||||||
@Override
|
}
|
||||||
public int processFor() {
|
else if (objects[0] instanceof Integer) {
|
||||||
return forCount;
|
Integer forCount = OperatorHelper.convert(objects[0], Integer.class);
|
||||||
}
|
node = new Node();
|
||||||
};
|
NodeForComponent nodeForComponent = new NodeForComponent() {
|
||||||
nodeForComponent.setSelf(nodeForComponent);
|
@Override
|
||||||
nodeForComponent.setNodeId(StrUtil.format("LOOP_{}", forCount));
|
public int processFor() {
|
||||||
node.setInstance(nodeForComponent);
|
return forCount;
|
||||||
}else{
|
}
|
||||||
throw new QLException("The parameter must be Node item");
|
};
|
||||||
}
|
nodeForComponent.setSelf(nodeForComponent);
|
||||||
|
nodeForComponent.setNodeId(StrUtil.format("LOOP_{}", forCount));
|
||||||
|
node.setInstance(nodeForComponent);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new QLException("The parameter must be Node item");
|
||||||
|
}
|
||||||
|
|
||||||
|
ForCondition forCondition = new ForCondition();
|
||||||
|
forCondition.setForNode(node);
|
||||||
|
return forCondition;
|
||||||
|
}
|
||||||
|
|
||||||
ForCondition forCondition = new ForCondition();
|
|
||||||
forCondition.setForNode(node);
|
|
||||||
return forCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,17 @@ import com.yomahub.liteflow.flow.element.condition.Condition;
|
||||||
*/
|
*/
|
||||||
public class IdOperator extends BaseOperator<Condition> {
|
public class IdOperator extends BaseOperator<Condition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Condition build(Object[] objects) throws Exception {
|
public Condition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
|
|
||||||
Condition condition = OperatorHelper.convert(objects[0], Condition.class);
|
Condition condition = OperatorHelper.convert(objects[0], Condition.class);
|
||||||
|
|
||||||
String id = OperatorHelper.convert(objects[1], String.class);
|
String id = OperatorHelper.convert(objects[1], String.class);
|
||||||
|
|
||||||
condition.setId(id);
|
condition.setId(id);
|
||||||
|
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
return condition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,29 +17,30 @@ import com.yomahub.liteflow.flow.element.condition.IfCondition;
|
||||||
*/
|
*/
|
||||||
public class IfOperator extends BaseOperator<IfCondition> {
|
public class IfOperator extends BaseOperator<IfCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IfCondition build(Object[] objects) throws Exception {
|
public IfCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEq(objects, 2, 3);
|
OperatorHelper.checkObjectSizeEq(objects, 2, 3);
|
||||||
|
|
||||||
//解析第一个参数
|
// 解析第一个参数
|
||||||
Node ifNode = OperatorHelper.convert(objects[0], Node.class);
|
Node ifNode = OperatorHelper.convert(objects[0], Node.class);
|
||||||
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
|
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
|
||||||
throw new QLException("The first parameter must be If item");
|
throw new QLException("The first parameter must be If item");
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析第二个参数
|
// 解析第二个参数
|
||||||
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
||||||
|
|
||||||
//解析第三个参数,如果有的话
|
// 解析第三个参数,如果有的话
|
||||||
Executable falseCaseExecutableItem = null;
|
Executable falseCaseExecutableItem = null;
|
||||||
if (objects.length == 3) {
|
if (objects.length == 3) {
|
||||||
falseCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
|
falseCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfCondition ifCondition = new IfCondition();
|
||||||
|
ifCondition.setIfNode(ifNode);
|
||||||
|
ifCondition.setTrueCaseExecutableItem(trueCaseExecutableItem);
|
||||||
|
ifCondition.setFalseCaseExecutableItem(falseCaseExecutableItem);
|
||||||
|
return ifCondition;
|
||||||
|
}
|
||||||
|
|
||||||
IfCondition ifCondition = new IfCondition();
|
|
||||||
ifCondition.setIfNode(ifNode);
|
|
||||||
ifCondition.setTrueCaseExecutableItem(trueCaseExecutableItem);
|
|
||||||
ifCondition.setFalseCaseExecutableItem(falseCaseExecutableItem);
|
|
||||||
return ifCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,5 @@ public class IgnoreErrorOperator extends BaseOperator<WhenCondition> {
|
||||||
|
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,18 +9,20 @@ import com.yomahub.liteflow.flow.element.Node;
|
||||||
import com.yomahub.liteflow.flow.element.condition.IteratorCondition;
|
import com.yomahub.liteflow.flow.element.condition.IteratorCondition;
|
||||||
|
|
||||||
public class IteratorOperator extends BaseOperator<IteratorCondition> {
|
public class IteratorOperator extends BaseOperator<IteratorCondition> {
|
||||||
@Override
|
|
||||||
public IteratorCondition build(Object[] objects) throws Exception {
|
|
||||||
OperatorHelper.checkObjectSizeEq(objects, 1);
|
|
||||||
|
|
||||||
Node node = OperatorHelper.convert(objects[0], Node.class);
|
@Override
|
||||||
if (!ListUtil.toList(NodeTypeEnum.ITERATOR).contains(node.getType())) {
|
public IteratorCondition build(Object[] objects) throws Exception {
|
||||||
throw new QLException("The parameter must be iterator-node item");
|
OperatorHelper.checkObjectSizeEq(objects, 1);
|
||||||
}
|
|
||||||
|
|
||||||
IteratorCondition iteratorCondition = new IteratorCondition();
|
Node node = OperatorHelper.convert(objects[0], Node.class);
|
||||||
iteratorCondition.setIteratorNode(node);
|
if (!ListUtil.toList(NodeTypeEnum.ITERATOR).contains(node.getType())) {
|
||||||
|
throw new QLException("The parameter must be iterator-node item");
|
||||||
|
}
|
||||||
|
|
||||||
|
IteratorCondition iteratorCondition = new IteratorCondition();
|
||||||
|
iteratorCondition.setIteratorNode(node);
|
||||||
|
|
||||||
|
return iteratorCondition;
|
||||||
|
}
|
||||||
|
|
||||||
return iteratorCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,21 +26,33 @@ public class NodeOperator extends BaseOperator<Node> {
|
||||||
|
|
||||||
if (FlowBus.containNode(nodeId)) {
|
if (FlowBus.containNode(nodeId)) {
|
||||||
return FlowBus.getNode(nodeId);
|
return FlowBus.getNode(nodeId);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
|
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
|
||||||
if (StrUtil.isNotBlank(liteflowConfig.getSubstituteCmpClass())) {
|
if (StrUtil.isNotBlank(liteflowConfig.getSubstituteCmpClass())) {
|
||||||
Node substituteNode = FlowBus.getNodeMap().values().stream().filter(node
|
Node substituteNode = FlowBus.getNodeMap()
|
||||||
-> node.getInstance().getClass().getName().equals(liteflowConfig.getSubstituteCmpClass())).findFirst().orElse(null);
|
.values()
|
||||||
|
.stream()
|
||||||
|
.filter(node -> node.getInstance()
|
||||||
|
.getClass()
|
||||||
|
.getName()
|
||||||
|
.equals(liteflowConfig.getSubstituteCmpClass()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
if (ObjectUtil.isNotNull(substituteNode)) {
|
if (ObjectUtil.isNotNull(substituteNode)) {
|
||||||
return substituteNode;
|
return substituteNode;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
String error = StrUtil.format("This node[{}] cannot be found", nodeId);
|
String error = StrUtil.format("This node[{}] cannot be found", nodeId);
|
||||||
throw new QLException(error);
|
throw new QLException(error);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
String error = StrUtil.format("This node[{}] cannot be found, or you can configure an substitute node", nodeId);
|
else {
|
||||||
|
String error = StrUtil.format("This node[{}] cannot be found, or you can configure an substitute node",
|
||||||
|
nodeId);
|
||||||
throw new QLException(error);
|
throw new QLException(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,15 @@ import com.yomahub.liteflow.flow.element.condition.PreCondition;
|
||||||
*/
|
*/
|
||||||
public class PreOperator extends BaseOperator<PreCondition> {
|
public class PreOperator extends BaseOperator<PreCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreCondition build(Object[] objects) throws Exception {
|
public PreCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeGtZero(objects);
|
OperatorHelper.checkObjectSizeGtZero(objects);
|
||||||
|
|
||||||
|
PreCondition preCondition = new PreCondition();
|
||||||
|
for (Object obj : objects) {
|
||||||
|
preCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
|
||||||
|
}
|
||||||
|
return preCondition;
|
||||||
|
}
|
||||||
|
|
||||||
PreCondition preCondition = new PreCondition();
|
|
||||||
for (Object obj : objects) {
|
|
||||||
preCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
|
|
||||||
}
|
|
||||||
return preCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,4 +30,5 @@ public class SwitchOperator extends BaseOperator<SwitchCondition> {
|
||||||
|
|
||||||
return switchCondition;
|
return switchCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,4 +26,5 @@ public class TagOperator extends BaseOperator<Node> {
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,15 @@ import com.yomahub.liteflow.flow.element.condition.ThenCondition;
|
||||||
*/
|
*/
|
||||||
public class ThenOperator extends BaseOperator<ThenCondition> {
|
public class ThenOperator extends BaseOperator<ThenCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ThenCondition build(Object[] objects) throws Exception {
|
public ThenCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeGtZero(objects);
|
OperatorHelper.checkObjectSizeGtZero(objects);
|
||||||
|
|
||||||
|
ThenCondition thenCondition = new ThenCondition();
|
||||||
|
for (Object obj : objects) {
|
||||||
|
thenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
|
||||||
|
}
|
||||||
|
return thenCondition;
|
||||||
|
}
|
||||||
|
|
||||||
ThenCondition thenCondition = new ThenCondition();
|
|
||||||
for (Object obj : objects) {
|
|
||||||
thenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
|
|
||||||
}
|
|
||||||
return thenCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,15 @@ import com.yomahub.liteflow.flow.element.condition.WhenCondition;
|
||||||
*/
|
*/
|
||||||
public class ThreadPoolOperator extends BaseOperator<WhenCondition> {
|
public class ThreadPoolOperator extends BaseOperator<WhenCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WhenCondition build(Object[] objects) throws Exception {
|
public WhenCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||||
|
|
||||||
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
|
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
|
||||||
|
|
||||||
whenCondition.setThreadExecutorClass(OperatorHelper.convert(objects[1], String.class));
|
whenCondition.setThreadExecutorClass(OperatorHelper.convert(objects[1], String.class));
|
||||||
|
|
||||||
|
return whenCondition;
|
||||||
|
}
|
||||||
|
|
||||||
return whenCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,17 @@ import com.yomahub.liteflow.flow.element.condition.SwitchCondition;
|
||||||
*/
|
*/
|
||||||
public class ToOperator extends BaseOperator<SwitchCondition> {
|
public class ToOperator extends BaseOperator<SwitchCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SwitchCondition build(Object[] objects) throws Exception {
|
public SwitchCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeGtTwo(objects);
|
OperatorHelper.checkObjectSizeGtTwo(objects);
|
||||||
|
|
||||||
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
|
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
|
||||||
|
|
||||||
|
for (int i = 1; i < objects.length; i++) {
|
||||||
|
Executable target = OperatorHelper.convert(objects[i], Executable.class);
|
||||||
|
switchCondition.addTargetItem(target);
|
||||||
|
}
|
||||||
|
return switchCondition;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 1; i < objects.length; i++) {
|
|
||||||
Executable target = OperatorHelper.convert(objects[i], Executable.class);
|
|
||||||
switchCondition.addTargetItem(target);
|
|
||||||
}
|
|
||||||
return switchCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,21 @@ import com.yomahub.liteflow.flow.element.condition.WhenCondition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL规则中的WHEN的操作符
|
* EL规则中的WHEN的操作符
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.8.0
|
* @since 2.8.0
|
||||||
*/
|
*/
|
||||||
public class WhenOperator extends BaseOperator<WhenCondition> {
|
public class WhenOperator extends BaseOperator<WhenCondition> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WhenCondition build(Object[] objects) throws Exception {
|
public WhenCondition build(Object[] objects) throws Exception {
|
||||||
OperatorHelper.checkObjectSizeGtZero(objects);
|
OperatorHelper.checkObjectSizeGtZero(objects);
|
||||||
|
|
||||||
|
WhenCondition whenCondition = new WhenCondition();
|
||||||
|
for (Object obj : objects) {
|
||||||
|
whenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
|
||||||
|
}
|
||||||
|
return whenCondition;
|
||||||
|
}
|
||||||
|
|
||||||
WhenCondition whenCondition = new WhenCondition();
|
|
||||||
for (Object obj : objects) {
|
|
||||||
whenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
|
|
||||||
}
|
|
||||||
return whenCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,19 @@ import com.yomahub.liteflow.flow.element.condition.WhileCondition;
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class WhileOperator extends BaseOperator<WhileCondition> {
|
public class WhileOperator extends BaseOperator<WhileCondition> {
|
||||||
@Override
|
|
||||||
public WhileCondition build(Object[] objects) throws Exception {
|
|
||||||
OperatorHelper.checkObjectSizeEq(objects, 1);
|
|
||||||
|
|
||||||
Node node = OperatorHelper.convert(objects[0], Node.class);
|
@Override
|
||||||
if (!ListUtil.toList(NodeTypeEnum.WHILE, NodeTypeEnum.WHILE_SCRIPT).contains(node.getType())) {
|
public WhileCondition build(Object[] objects) throws Exception {
|
||||||
throw new QLException("The parameter must be while-node item");
|
OperatorHelper.checkObjectSizeEq(objects, 1);
|
||||||
}
|
|
||||||
|
Node node = OperatorHelper.convert(objects[0], Node.class);
|
||||||
|
if (!ListUtil.toList(NodeTypeEnum.WHILE, NodeTypeEnum.WHILE_SCRIPT).contains(node.getType())) {
|
||||||
|
throw new QLException("The parameter must be while-node item");
|
||||||
|
}
|
||||||
|
|
||||||
|
WhileCondition whileCondition = new WhileCondition();
|
||||||
|
whileCondition.setWhileNode(node);
|
||||||
|
return whileCondition;
|
||||||
|
}
|
||||||
|
|
||||||
WhileCondition whileCondition = new WhileCondition();
|
|
||||||
whileCondition.setWhileNode(node);
|
|
||||||
return whileCondition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,27 @@ import com.yomahub.liteflow.flow.element.Executable;
|
||||||
*/
|
*/
|
||||||
public abstract class BaseOperator<T extends Executable> extends Operator {
|
public abstract class BaseOperator<T extends Executable> extends Operator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T executeInner(Object[] objects) throws Exception {
|
public T executeInner(Object[] objects) throws Exception {
|
||||||
try {
|
try {
|
||||||
// 检查 node 和 chain 是否已经注册
|
// 检查 node 和 chain 是否已经注册
|
||||||
OperatorHelper.checkNodeAndChainExist(objects);
|
OperatorHelper.checkNodeAndChainExist(objects);
|
||||||
return build(objects);
|
return build(objects);
|
||||||
} catch (QLException e) {
|
}
|
||||||
throw e;
|
catch (QLException e) {
|
||||||
} catch (Exception e) {
|
throw e;
|
||||||
throw new ELParseException("errors occurred in EL parsing");
|
}
|
||||||
}
|
catch (Exception e) {
|
||||||
}
|
throw new ELParseException("errors occurred in EL parsing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建 EL 条件
|
||||||
|
* @param objects objects
|
||||||
|
* @return Condition
|
||||||
|
* @throws Exception Exception
|
||||||
|
*/
|
||||||
|
public abstract T build(Object[] objects) throws Exception;
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建 EL 条件
|
|
||||||
*
|
|
||||||
* @param objects objects
|
|
||||||
* @return Condition
|
|
||||||
* @throws Exception Exception
|
|
||||||
*/
|
|
||||||
public abstract T build(Object[] objects) throws Exception;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,149 +15,140 @@ import java.util.Objects;
|
||||||
*/
|
*/
|
||||||
public class OperatorHelper {
|
public class OperatorHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,不等于1
|
* 检查参数数量,不等于1
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeNeqOne(Object[] objects) throws QLException {
|
||||||
public static void checkObjectSizeNeqOne(Object[] objects) throws QLException {
|
checkObjectSizeNeq(objects, 1);
|
||||||
checkObjectSizeNeq(objects, 1);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,不等于 size
|
* 检查参数数量,不等于 size
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @param size 参数数量
|
||||||
* @param size 参数数量
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeNeq(Object[] objects, int size) throws QLException {
|
||||||
public static void checkObjectSizeNeq(Object[] objects, int size) throws QLException {
|
checkObjectSizeGtZero(objects);
|
||||||
checkObjectSizeGtZero(objects);
|
if (objects.length != size) {
|
||||||
if (objects.length != size) {
|
throw new QLException("parameter error");
|
||||||
throw new QLException("parameter error");
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,大于 0
|
* 检查参数数量,大于 0
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeGtZero(Object[] objects) throws QLException {
|
||||||
public static void checkObjectSizeGtZero(Object[] objects) throws QLException {
|
if (objects.length == 0) {
|
||||||
if (objects.length == 0) {
|
throw new QLException("parameter is empty");
|
||||||
throw new QLException("parameter is empty");
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,大于 2
|
* 检查参数数量,大于 2
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeGtTwo(Object[] objects) throws QLException {
|
||||||
public static void checkObjectSizeGtTwo(Object[] objects) throws QLException {
|
checkObjectSizeGtZero(objects);
|
||||||
checkObjectSizeGtZero(objects);
|
if (objects.length <= 1) {
|
||||||
if (objects.length <= 1) {
|
throw new QLException("parameter error");
|
||||||
throw new QLException("parameter error");
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,等于 2
|
* 检查参数数量,等于 2
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeEqTwo(Object[] objects) throws QLException {
|
||||||
public static void checkObjectSizeEqTwo(Object[] objects) throws QLException {
|
checkObjectSizeEq(objects, 2);
|
||||||
checkObjectSizeEq(objects, 2);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,等于 3
|
* 检查参数数量,等于 3
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeEqThree(Object[] objects) throws QLException {
|
||||||
public static void checkObjectSizeEqThree(Object[] objects) throws QLException {
|
checkObjectSizeEq(objects, 3);
|
||||||
checkObjectSizeEq(objects, 3);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,等于 size
|
* 检查参数数量,等于 size
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @param size 参数数量
|
||||||
* @param size 参数数量
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeEq(Object[] objects, int size) throws QLException {
|
||||||
public static void checkObjectSizeEq(Object[] objects, int size) throws QLException {
|
checkObjectSizeGtZero(objects);
|
||||||
checkObjectSizeGtZero(objects);
|
|
||||||
|
|
||||||
if (objects.length != size) {
|
if (objects.length != size) {
|
||||||
throw new QLException("parameter error");
|
throw new QLException("parameter error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查参数数量,等于 size1 或 size2
|
* 检查参数数量,等于 size1 或 size2
|
||||||
*
|
* @param objects objects
|
||||||
* @param objects objects
|
* @param size1 参数数量1
|
||||||
* @param size1 参数数量1
|
* @param size2 参数数量2
|
||||||
* @param size2 参数数量2
|
* @throws QLException QLException
|
||||||
* @throws QLException QLException
|
*/
|
||||||
*/
|
public static void checkObjectSizeEq(Object[] objects, int size1, int size2) throws QLException {
|
||||||
public static void checkObjectSizeEq(Object[] objects, int size1, int size2) throws QLException {
|
checkObjectSizeGtZero(objects);
|
||||||
checkObjectSizeGtZero(objects);
|
|
||||||
|
|
||||||
if (objects.length != size1 && objects.length != size2) {
|
if (objects.length != size1 && objects.length != size2) {
|
||||||
throw new QLException("parameter error");
|
throw new QLException("parameter error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换 object 为指定的类型
|
* 转换 object 为指定的类型 如果是Node类型的则进行copy
|
||||||
* 如果是Node类型的则进行copy
|
* 为什么要进行copy呢?因为原先的Node都是存放在FlowBus的NodeMap中的。有些属性在EL中不是全局的,属于当前这个chain的。 所以要进行copy动作
|
||||||
* 为什么要进行copy呢?因为原先的Node都是存放在FlowBus的NodeMap中的。有些属性在EL中不是全局的,属于当前这个chain的。
|
*/
|
||||||
* 所以要进行copy动作
|
public static <T> T convert(Object object, Class<T> clazz) throws QLException {
|
||||||
*/
|
String errorMsg = StrUtil.format("The parameter must be {} item", clazz.getSimpleName());
|
||||||
public static <T> T convert(Object object, Class<T> clazz) throws QLException {
|
return convert(object, clazz, errorMsg);
|
||||||
String errorMsg = StrUtil.format("The parameter must be {} item", clazz.getSimpleName());
|
}
|
||||||
return convert(object, clazz, errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换 object 为指定的类型,自定义错误信息
|
* 转换 object 为指定的类型,自定义错误信息 如果是Node类型的则进行copy
|
||||||
* 如果是Node类型的则进行copy
|
*/
|
||||||
*/
|
public static <T> T convert(Object object, Class<T> clazz, String errorMsg) throws QLException {
|
||||||
public static <T> T convert(Object object, Class<T> clazz, String errorMsg) throws QLException {
|
try {
|
||||||
try {
|
if (clazz.isAssignableFrom(object.getClass())) {
|
||||||
if (clazz.isAssignableFrom(object.getClass())) {
|
if (clazz.equals(Node.class)) {
|
||||||
if (clazz.equals(Node.class)) {
|
Node node = (Node) object;
|
||||||
Node node = (Node) object;
|
return (T) node.copy();
|
||||||
return (T) node.copy();
|
}
|
||||||
} else {
|
else {
|
||||||
return (T) object;
|
return (T) object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
throw new QLException("An error occurred while copying an object");
|
catch (Exception e) {
|
||||||
}
|
throw new QLException("An error occurred while copying an object");
|
||||||
|
}
|
||||||
|
|
||||||
throw new QLException(errorMsg);
|
throw new QLException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 node 和 chain 是否已经注册
|
||||||
|
* @param objects objects
|
||||||
|
* @throws QLException QLException
|
||||||
|
*/
|
||||||
|
public static void checkNodeAndChainExist(Object[] objects) throws QLException {
|
||||||
|
for (Object object : objects) {
|
||||||
|
if (Objects.isNull(object)) {
|
||||||
|
throw new QLException(DataNotFoundException.MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查 node 和 chain 是否已经注册
|
|
||||||
*
|
|
||||||
* @param objects objects
|
|
||||||
* @throws QLException QLException
|
|
||||||
*/
|
|
||||||
public static void checkNodeAndChainExist(Object[] objects) throws QLException {
|
|
||||||
for (Object object : objects) {
|
|
||||||
if (Objects.isNull(object)) {
|
|
||||||
throw new QLException(DataNotFoundException.MSG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,4 +90,5 @@ public class ChainPropBean {
|
||||||
this.conditionType = conditionType;
|
this.conditionType = conditionType;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,4 +102,5 @@ public class NodePropBean {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,71 +7,72 @@ package com.yomahub.liteflow.common;
|
||||||
*/
|
*/
|
||||||
public interface ChainConstant {
|
public interface ChainConstant {
|
||||||
|
|
||||||
String CHAIN = "chain";
|
String CHAIN = "chain";
|
||||||
|
|
||||||
String FLOW = "flow";
|
String FLOW = "flow";
|
||||||
|
|
||||||
String NODES = "nodes";
|
String NODES = "nodes";
|
||||||
|
|
||||||
String NODE = "node";
|
String NODE = "node";
|
||||||
|
|
||||||
String ID = "id";
|
String ID = "id";
|
||||||
|
|
||||||
String _CLASS = "class";
|
String _CLASS = "class";
|
||||||
|
|
||||||
String FILE = "file";
|
String FILE = "file";
|
||||||
|
|
||||||
String NAME = "name";
|
String NAME = "name";
|
||||||
|
|
||||||
String LANGUAGE = "language";
|
String LANGUAGE = "language";
|
||||||
|
|
||||||
String VALUE = "value";
|
String VALUE = "value";
|
||||||
|
|
||||||
String ANY = "any";
|
String ANY = "any";
|
||||||
|
|
||||||
String TYPE = "type";
|
String TYPE = "type";
|
||||||
|
|
||||||
String THEN = "THEN";
|
String THEN = "THEN";
|
||||||
|
|
||||||
String WHEN = "WHEN";
|
String WHEN = "WHEN";
|
||||||
|
|
||||||
String SWITCH = "SWITCH";
|
String SWITCH = "SWITCH";
|
||||||
|
|
||||||
String PRE = "PRE";
|
String PRE = "PRE";
|
||||||
|
|
||||||
String FINALLY = "FINALLY";
|
String FINALLY = "FINALLY";
|
||||||
|
|
||||||
String IF = "IF";
|
String IF = "IF";
|
||||||
|
|
||||||
String ELSE = "ELSE";
|
String ELSE = "ELSE";
|
||||||
|
|
||||||
String ELIF = "ELIF";
|
String ELIF = "ELIF";
|
||||||
|
|
||||||
String TO = "TO";
|
String TO = "TO";
|
||||||
|
|
||||||
String TAG = "tag";
|
String TAG = "tag";
|
||||||
|
|
||||||
String IGNORE_ERROR = "ignoreError";
|
String IGNORE_ERROR = "ignoreError";
|
||||||
|
|
||||||
String THREAD_POOL = "threadPool";
|
String THREAD_POOL = "threadPool";
|
||||||
|
|
||||||
String WHILE = "WHILE";
|
String WHILE = "WHILE";
|
||||||
|
|
||||||
String FOR = "FOR";
|
String FOR = "FOR";
|
||||||
|
|
||||||
String DO = "DO";
|
String DO = "DO";
|
||||||
|
|
||||||
String BREAK = "BREAK";
|
String BREAK = "BREAK";
|
||||||
|
|
||||||
String DATA = "data";
|
String DATA = "data";
|
||||||
|
|
||||||
String ITERATOR = "ITERATOR";
|
String ITERATOR = "ITERATOR";
|
||||||
|
|
||||||
String MONITOR_BUS = "monitorBus";
|
String MONITOR_BUS = "monitorBus";
|
||||||
|
|
||||||
String CURR_CHAIN_ID = "currChainId";
|
String CURR_CHAIN_ID = "currChainId";
|
||||||
|
|
||||||
String DEFAULT = "DEFAULT";
|
String DEFAULT = "DEFAULT";
|
||||||
|
|
||||||
|
String CATCH = "CATCH";
|
||||||
|
|
||||||
String CATCH = "CATCH";
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,7 @@ package com.yomahub.liteflow.common;
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class LocalDefaultFlowConstant {
|
public class LocalDefaultFlowConstant {
|
||||||
public static final String DEFAULT="default";
|
|
||||||
|
public static final String DEFAULT = "default";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,20 @@ import java.lang.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于标注上下文bean的别名,以便在脚本或者组件中通过别名来获取上下文对象
|
* 用于标注上下文bean的别名,以便在脚本或者组件中通过别名来获取上下文对象
|
||||||
|
*
|
||||||
* @since 2.9.7
|
* @since 2.9.7
|
||||||
* @author Tingliang Wang
|
* @author Tingliang Wang
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE})
|
@Target({ ElementType.TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
public @interface ContextBean {
|
public @interface ContextBean {
|
||||||
@AliasFor("name")
|
|
||||||
String value() default "";
|
|
||||||
|
|
||||||
@AliasFor("value")
|
@AliasFor("name")
|
||||||
String name() default "";
|
String value() default "";
|
||||||
|
|
||||||
|
@AliasFor("value")
|
||||||
|
String name() default "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,57 +21,61 @@ import com.yomahub.liteflow.spi.holder.LiteflowComponentSupportHolder;
|
||||||
*/
|
*/
|
||||||
public class ComponentInitializer {
|
public class ComponentInitializer {
|
||||||
|
|
||||||
private static ComponentInitializer instance;
|
private static ComponentInitializer instance;
|
||||||
|
|
||||||
public static ComponentInitializer loadInstance() {
|
public static ComponentInitializer loadInstance() {
|
||||||
if (ObjectUtil.isNull(instance)) {
|
if (ObjectUtil.isNull(instance)) {
|
||||||
instance = new ComponentInitializer();
|
instance = new ComponentInitializer();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeComponent initComponent(NodeComponent nodeComponent, NodeTypeEnum type, String name, String nodeId) {
|
public NodeComponent initComponent(NodeComponent nodeComponent, NodeTypeEnum type, String name, String nodeId) {
|
||||||
nodeComponent.setNodeId(nodeId);
|
nodeComponent.setNodeId(nodeId);
|
||||||
nodeComponent.setSelf(nodeComponent);
|
nodeComponent.setSelf(nodeComponent);
|
||||||
nodeComponent.setType(type);
|
nodeComponent.setType(type);
|
||||||
|
|
||||||
//设置MonitorBus,如果没有就不注入
|
// 设置MonitorBus,如果没有就不注入
|
||||||
if (ContextAwareHolder.loadContextAware().hasBean(ChainConstant.MONITOR_BUS)) {
|
if (ContextAwareHolder.loadContextAware().hasBean(ChainConstant.MONITOR_BUS)) {
|
||||||
MonitorBus monitorBus = ContextAwareHolder.loadContextAware().getBean(MonitorBus.class);
|
MonitorBus monitorBus = ContextAwareHolder.loadContextAware().getBean(MonitorBus.class);
|
||||||
if (ObjectUtil.isNotNull(monitorBus)) {
|
if (ObjectUtil.isNotNull(monitorBus)) {
|
||||||
nodeComponent.setMonitorBus(monitorBus);
|
nodeComponent.setMonitorBus(monitorBus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//先取传进来的name值(配置文件中配置的),再看有没有配置@LiteflowComponent标注
|
// 先取传进来的name值(配置文件中配置的),再看有没有配置@LiteflowComponent标注
|
||||||
//@LiteflowComponent标注只在spring体系下生效,这里用了spi机制取到相应环境下的实现类
|
// @LiteflowComponent标注只在spring体系下生效,这里用了spi机制取到相应环境下的实现类
|
||||||
nodeComponent.setName(name);
|
nodeComponent.setName(name);
|
||||||
if (!type.isScript() && StrUtil.isBlank(nodeComponent.getName())) {
|
if (!type.isScript() && StrUtil.isBlank(nodeComponent.getName())) {
|
||||||
nodeComponent.setName(LiteflowComponentSupportHolder.loadLiteflowComponentSupport().getCmpName(nodeComponent));
|
nodeComponent
|
||||||
}
|
.setName(LiteflowComponentSupportHolder.loadLiteflowComponentSupport().getCmpName(nodeComponent));
|
||||||
|
}
|
||||||
|
|
||||||
//先从组件上取@RetryCount标注,如果没有,则看全局配置,全局配置如果不配置的话,默认是0
|
// 先从组件上取@RetryCount标注,如果没有,则看全局配置,全局配置如果不配置的话,默认是0
|
||||||
//默认retryForExceptions为Exception.class
|
// 默认retryForExceptions为Exception.class
|
||||||
LiteflowRetry liteFlowRetryAnnotation = AnnoUtil.getAnnotation(nodeComponent.getClass(), LiteflowRetry.class);
|
LiteflowRetry liteFlowRetryAnnotation = AnnoUtil.getAnnotation(nodeComponent.getClass(), LiteflowRetry.class);
|
||||||
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
|
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
|
||||||
if (liteFlowRetryAnnotation != null) {
|
if (liteFlowRetryAnnotation != null) {
|
||||||
nodeComponent.setRetryCount(liteFlowRetryAnnotation.retry());
|
nodeComponent.setRetryCount(liteFlowRetryAnnotation.retry());
|
||||||
nodeComponent.setRetryForExceptions(liteFlowRetryAnnotation.forExceptions());
|
nodeComponent.setRetryForExceptions(liteFlowRetryAnnotation.forExceptions());
|
||||||
} else {
|
}
|
||||||
nodeComponent.setRetryCount(liteflowConfig.getRetryCount());
|
else {
|
||||||
}
|
nodeComponent.setRetryCount(liteflowConfig.getRetryCount());
|
||||||
nodeComponent.setNodeExecutorClass(buildNodeExecutorClass(liteflowConfig));
|
}
|
||||||
|
nodeComponent.setNodeExecutorClass(buildNodeExecutorClass(liteflowConfig));
|
||||||
|
|
||||||
return nodeComponent;
|
return nodeComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Class<? extends NodeExecutor> buildNodeExecutorClass(LiteflowConfig liteflowConfig) {
|
||||||
|
Class<?> nodeExecutorClass;
|
||||||
|
try {
|
||||||
|
nodeExecutorClass = Class.forName(liteflowConfig.getNodeExecutorClass());
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
return (Class<? extends NodeExecutor>) nodeExecutorClass;
|
||||||
|
}
|
||||||
|
|
||||||
private Class<? extends NodeExecutor> buildNodeExecutorClass(LiteflowConfig liteflowConfig) {
|
|
||||||
Class<?> nodeExecutorClass;
|
|
||||||
try {
|
|
||||||
nodeExecutorClass = Class.forName(liteflowConfig.getNodeExecutorClass());
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new RuntimeException(e.getMessage());
|
|
||||||
}
|
|
||||||
return (Class<? extends NodeExecutor>) nodeExecutorClass;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,379 +43,399 @@ import java.util.concurrent.Future;
|
||||||
*/
|
*/
|
||||||
public class FlowExecutor {
|
public class FlowExecutor {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FlowExecutor.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FlowExecutor.class);
|
||||||
|
|
||||||
private static final String PREFIX_FORMAT_CONFIG_REGEX = "xml:|json:|yml:|el_xml:|el_json:|el_yml:";
|
private static final String PREFIX_FORMAT_CONFIG_REGEX = "xml:|json:|yml:|el_xml:|el_json:|el_yml:";
|
||||||
|
|
||||||
private LiteflowConfig liteflowConfig;
|
private LiteflowConfig liteflowConfig;
|
||||||
|
|
||||||
public FlowExecutor() {
|
public FlowExecutor() {
|
||||||
//设置FlowExecutor的Holder,虽然大部分地方都可以通过Spring上下文获取到,但放入Holder,还是为了某些地方能方便的取到
|
// 设置FlowExecutor的Holder,虽然大部分地方都可以通过Spring上下文获取到,但放入Holder,还是为了某些地方能方便的取到
|
||||||
FlowExecutorHolder.setHolder(this);
|
FlowExecutorHolder.setHolder(this);
|
||||||
//初始化DataBus
|
// 初始化DataBus
|
||||||
DataBus.init();
|
DataBus.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FlowExecutor(LiteflowConfig liteflowConfig) {
|
public FlowExecutor(LiteflowConfig liteflowConfig) {
|
||||||
this.liteflowConfig = liteflowConfig;
|
this.liteflowConfig = liteflowConfig;
|
||||||
//把liteFlowConfig设到LiteFlowGetter中去
|
// 把liteFlowConfig设到LiteFlowGetter中去
|
||||||
LiteflowConfigGetter.setLiteflowConfig(liteflowConfig);
|
LiteflowConfigGetter.setLiteflowConfig(liteflowConfig);
|
||||||
//设置FlowExecutor的Holder,虽然大部分地方都可以通过Spring上下文获取到,但放入Holder,还是为了某些地方能方便的取到
|
// 设置FlowExecutor的Holder,虽然大部分地方都可以通过Spring上下文获取到,但放入Holder,还是为了某些地方能方便的取到
|
||||||
FlowExecutorHolder.setHolder(this);
|
FlowExecutorHolder.setHolder(this);
|
||||||
if (BooleanUtil.isTrue(liteflowConfig.isParseOnStart())) {
|
if (BooleanUtil.isTrue(liteflowConfig.isParseOnStart())) {
|
||||||
this.init(true);
|
this.init(true);
|
||||||
}
|
}
|
||||||
//初始化DataBus
|
// 初始化DataBus
|
||||||
DataBus.init();
|
DataBus.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FlowExecutor的初始化化方式,主要用于parse规则文件
|
* FlowExecutor的初始化化方式,主要用于parse规则文件
|
||||||
*/
|
*/
|
||||||
public void init(boolean hook) {
|
public void init(boolean hook) {
|
||||||
if (ObjectUtil.isNull(liteflowConfig)) {
|
if (ObjectUtil.isNull(liteflowConfig)) {
|
||||||
throw new ConfigErrorException("config error, please check liteflow config property");
|
throw new ConfigErrorException("config error, please check liteflow config property");
|
||||||
}
|
}
|
||||||
|
|
||||||
//在相应的环境下进行节点的初始化工作
|
// 在相应的环境下进行节点的初始化工作
|
||||||
//在spring体系下会获得spring扫描后的节点,接入元数据
|
// 在spring体系下会获得spring扫描后的节点,接入元数据
|
||||||
//在非spring体系下是一个空实现,等于不做此步骤
|
// 在非spring体系下是一个空实现,等于不做此步骤
|
||||||
ContextCmpInitHolder.loadContextCmpInit().initCmp();
|
ContextCmpInitHolder.loadContextCmpInit().initCmp();
|
||||||
|
|
||||||
//进行id生成器的初始化
|
// 进行id生成器的初始化
|
||||||
IdGeneratorHolder.init();
|
IdGeneratorHolder.init();
|
||||||
|
|
||||||
String ruleSource = liteflowConfig.getRuleSource();
|
String ruleSource = liteflowConfig.getRuleSource();
|
||||||
if (StrUtil.isBlank(ruleSource)) {
|
if (StrUtil.isBlank(ruleSource)) {
|
||||||
//查看有没有Parser的SPI实现
|
// 查看有没有Parser的SPI实现
|
||||||
//所有的Parser的SPI实现都是以custom形式放入的,且只支持xml形式
|
// 所有的Parser的SPI实现都是以custom形式放入的,且只支持xml形式
|
||||||
ServiceLoader<ParserClassNameSpi> loader = ServiceLoader.load(ParserClassNameSpi.class);
|
ServiceLoader<ParserClassNameSpi> loader = ServiceLoader.load(ParserClassNameSpi.class);
|
||||||
Iterator<ParserClassNameSpi> it = loader.iterator();
|
Iterator<ParserClassNameSpi> it = loader.iterator();
|
||||||
if (it.hasNext()) {
|
if (it.hasNext()) {
|
||||||
ParserClassNameSpi parserClassNameSpi = it.next();
|
ParserClassNameSpi parserClassNameSpi = it.next();
|
||||||
ruleSource = "el_xml:" + parserClassNameSpi.getSpiClassName();
|
ruleSource = "el_xml:" + parserClassNameSpi.getSpiClassName();
|
||||||
liteflowConfig.setRuleSource(ruleSource);
|
liteflowConfig.setRuleSource(ruleSource);
|
||||||
} else {
|
}
|
||||||
//ruleSource为空,而且没有spi形式的扩展,那么说明真的没有ruleSource
|
else {
|
||||||
//这种情况有可能是基于代码动态构建的
|
// ruleSource为空,而且没有spi形式的扩展,那么说明真的没有ruleSource
|
||||||
return;
|
// 这种情况有可能是基于代码动态构建的
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//如果有前缀的,则不需要再进行分割了,说明是一个整体
|
// 如果有前缀的,则不需要再进行分割了,说明是一个整体
|
||||||
//如果没有前缀,说明是本地文件,可能配置多个,所以需要分割
|
// 如果没有前缀,说明是本地文件,可能配置多个,所以需要分割
|
||||||
List<String> sourceRulePathList;
|
List<String> sourceRulePathList;
|
||||||
if (ReUtil.contains(PREFIX_FORMAT_CONFIG_REGEX, ruleSource)) {
|
if (ReUtil.contains(PREFIX_FORMAT_CONFIG_REGEX, ruleSource)) {
|
||||||
sourceRulePathList = ListUtil.toList(ruleSource);
|
sourceRulePathList = ListUtil.toList(ruleSource);
|
||||||
} else {
|
}
|
||||||
String afterHandleRuleSource = ruleSource.replace(StrUtil.SPACE, StrUtil.EMPTY);
|
else {
|
||||||
sourceRulePathList = ListUtil.toList(afterHandleRuleSource.split(",|;"));
|
String afterHandleRuleSource = ruleSource.replace(StrUtil.SPACE, StrUtil.EMPTY);
|
||||||
}
|
sourceRulePathList = ListUtil.toList(afterHandleRuleSource.split(",|;"));
|
||||||
|
}
|
||||||
|
|
||||||
FlowParser parser = null;
|
FlowParser parser = null;
|
||||||
Set<String> parserNameSet = new HashSet<>();
|
Set<String> parserNameSet = new HashSet<>();
|
||||||
List<String> rulePathList = new ArrayList<>();
|
List<String> rulePathList = new ArrayList<>();
|
||||||
for (String path : sourceRulePathList) {
|
for (String path : sourceRulePathList) {
|
||||||
try {
|
try {
|
||||||
// 查找对应的解析器
|
// 查找对应的解析器
|
||||||
parser = FlowParserProvider.lookup(path);
|
parser = FlowParserProvider.lookup(path);
|
||||||
parserNameSet.add(parser.getClass().getName());
|
parserNameSet.add(parser.getClass().getName());
|
||||||
// 替换掉前缀标识(如:xml:/json:),保留剩下的完整地址
|
// 替换掉前缀标识(如:xml:/json:),保留剩下的完整地址
|
||||||
path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, "");
|
path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, "");
|
||||||
rulePathList.add(path);
|
rulePathList.add(path);
|
||||||
|
|
||||||
//支持多类型的配置文件,分别解析
|
// 支持多类型的配置文件,分别解析
|
||||||
if (BooleanUtil.isTrue(liteflowConfig.isSupportMultipleType())) {
|
if (BooleanUtil.isTrue(liteflowConfig.isSupportMultipleType())) {
|
||||||
// 解析文件
|
// 解析文件
|
||||||
parser.parseMain(ListUtil.toList(path));
|
parser.parseMain(ListUtil.toList(path));
|
||||||
}
|
}
|
||||||
} catch (CyclicDependencyException e) {
|
}
|
||||||
LOG.error(e.getMessage());
|
catch (CyclicDependencyException e) {
|
||||||
throw e;
|
LOG.error(e.getMessage());
|
||||||
} catch (Exception e) {
|
throw e;
|
||||||
String errorMsg = StrUtil.format("init flow executor cause error for path {},reason:{}", path, e.getMessage());
|
}
|
||||||
LOG.error(e.getMessage(), e);
|
catch (Exception e) {
|
||||||
throw new FlowExecutorNotInitException(errorMsg);
|
String errorMsg = StrUtil.format("init flow executor cause error for path {},reason:{}", path,
|
||||||
}
|
e.getMessage());
|
||||||
}
|
LOG.error(e.getMessage(), e);
|
||||||
|
throw new FlowExecutorNotInitException(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//单类型的配置文件,需要一起解析
|
// 单类型的配置文件,需要一起解析
|
||||||
if (BooleanUtil.isFalse(liteflowConfig.isSupportMultipleType())) {
|
if (BooleanUtil.isFalse(liteflowConfig.isSupportMultipleType())) {
|
||||||
//检查Parser是否只有一个,因为多个不同的parser会造成子流程的混乱
|
// 检查Parser是否只有一个,因为多个不同的parser会造成子流程的混乱
|
||||||
if (parserNameSet.size() > 1) {
|
if (parserNameSet.size() > 1) {
|
||||||
String errorMsg = "cannot have multiple different parsers";
|
String errorMsg = "cannot have multiple different parsers";
|
||||||
LOG.error(errorMsg);
|
LOG.error(errorMsg);
|
||||||
throw new MultipleParsersException(errorMsg);
|
throw new MultipleParsersException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//进行多个配置文件的一起解析
|
// 进行多个配置文件的一起解析
|
||||||
try {
|
try {
|
||||||
if (parser != null) {
|
if (parser != null) {
|
||||||
// 解析文件
|
// 解析文件
|
||||||
parser.parseMain(rulePathList);
|
parser.parseMain(rulePathList);
|
||||||
} else {
|
}
|
||||||
throw new ConfigErrorException("parse error, please check liteflow config property");
|
else {
|
||||||
}
|
throw new ConfigErrorException("parse error, please check liteflow config property");
|
||||||
} catch (CyclicDependencyException e) {
|
}
|
||||||
LOG.error(e.getMessage(), e);
|
}
|
||||||
LOG.error(e.getMessage());
|
catch (CyclicDependencyException e) {
|
||||||
throw e;
|
LOG.error(e.getMessage(), e);
|
||||||
} catch (ChainDuplicateException e) {
|
LOG.error(e.getMessage());
|
||||||
LOG.error(e.getMessage(), e);
|
throw e;
|
||||||
throw e;
|
}
|
||||||
} catch (Exception e) {
|
catch (ChainDuplicateException e) {
|
||||||
String errorMsg = StrUtil.format("init flow executor cause error for path {},reason: {}", rulePathList, e.getMessage());
|
LOG.error(e.getMessage(), e);
|
||||||
LOG.error(e.getMessage(), e);
|
throw e;
|
||||||
throw new FlowExecutorNotInitException(errorMsg);
|
}
|
||||||
}
|
catch (Exception e) {
|
||||||
}
|
String errorMsg = StrUtil.format("init flow executor cause error for path {},reason: {}", rulePathList,
|
||||||
|
e.getMessage());
|
||||||
|
LOG.error(e.getMessage(), e);
|
||||||
|
throw new FlowExecutorNotInitException(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//如果是ruleSource方式的,最后判断下有没有解析出来,如果没有解析出来则报错
|
// 如果是ruleSource方式的,最后判断下有没有解析出来,如果没有解析出来则报错
|
||||||
if (StrUtil.isBlank(liteflowConfig.getRuleSourceExtData()) && MapUtil.isEmpty(liteflowConfig.getRuleSourceExtDataMap())) {
|
if (StrUtil.isBlank(liteflowConfig.getRuleSourceExtData())
|
||||||
if (FlowBus.getChainMap().isEmpty()) {
|
&& MapUtil.isEmpty(liteflowConfig.getRuleSourceExtDataMap())) {
|
||||||
String errMsg = StrUtil.format("no valid rule config found in rule path [{}]", liteflowConfig.getRuleSource());
|
if (FlowBus.getChainMap().isEmpty()) {
|
||||||
throw new ConfigErrorException(errMsg);
|
String errMsg = StrUtil.format("no valid rule config found in rule path [{}]",
|
||||||
}
|
liteflowConfig.getRuleSource());
|
||||||
}
|
throw new ConfigErrorException(errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//执行钩子
|
// 执行钩子
|
||||||
if (hook) {
|
if (hook) {
|
||||||
FlowInitHook.executeHook();
|
FlowInitHook.executeHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件监听
|
// 文件监听
|
||||||
if (liteflowConfig.getEnableMonitorFile()) {
|
if (liteflowConfig.getEnableMonitorFile()) {
|
||||||
try{
|
try {
|
||||||
addMonitorFilePaths(rulePathList);
|
addMonitorFilePaths(rulePathList);
|
||||||
MonitorFile.getInstance().create();
|
MonitorFile.getInstance().create();
|
||||||
}catch (Exception e){
|
}
|
||||||
String errMsg = StrUtil.format("file monitor init error for path:{}", rulePathList);
|
catch (Exception e) {
|
||||||
throw new MonitorFileInitErrorException(errMsg);
|
String errMsg = StrUtil.format("file monitor init error for path:{}", rulePathList);
|
||||||
}
|
throw new MonitorFileInitErrorException(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//此方法就是从原有的配置源主动拉取新的进行刷新
|
// 此方法就是从原有的配置源主动拉取新的进行刷新
|
||||||
//和FlowBus.refreshFlowMetaData的区别就是一个为主动拉取,一个为被动监听到新的内容进行刷新
|
// 和FlowBus.refreshFlowMetaData的区别就是一个为主动拉取,一个为被动监听到新的内容进行刷新
|
||||||
public void reloadRule() {
|
public void reloadRule() {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
init(false);
|
init(false);
|
||||||
LOG.info("reload rules takes {}ms", System.currentTimeMillis() - start);
|
LOG.info("reload rules takes {}ms", System.currentTimeMillis() - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
//隐式流程的调用方法
|
// 隐式流程的调用方法
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void invoke(String chainId, Object param, Integer slotIndex) throws Exception {
|
public void invoke(String chainId, Object param, Integer slotIndex) throws Exception {
|
||||||
LiteflowResponse response = this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_SYNC);
|
LiteflowResponse response = this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_SYNC);
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
throw response.getCause();
|
throw response.getCause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void invokeInAsync(String chainId, Object param, Integer slotIndex) throws Exception {
|
public void invokeInAsync(String chainId, Object param, Integer slotIndex) throws Exception {
|
||||||
LiteflowResponse response = this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_ASYNC);
|
LiteflowResponse response = this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_ASYNC);
|
||||||
if (!response.isSuccess()) {
|
if (!response.isSuccess()) {
|
||||||
throw response.getCause();
|
throw response.getCause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteflowResponse invoke2Resp(String chainId, Object param, Integer slotIndex) {
|
public LiteflowResponse invoke2Resp(String chainId, Object param, Integer slotIndex) {
|
||||||
return this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_SYNC);
|
return this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteflowResponse invoke2RespInAsync(String chainId, Object param, Integer slotIndex) {
|
public LiteflowResponse invoke2RespInAsync(String chainId, Object param, Integer slotIndex) {
|
||||||
return this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_ASYNC);
|
return this.invoke2Resp(chainId, param, slotIndex, InnerChainTypeEnum.IN_ASYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
//单独调用某一个node
|
// 单独调用某一个node
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void invoke(String nodeId, Integer slotIndex) throws Exception {
|
public void invoke(String nodeId, Integer slotIndex) throws Exception {
|
||||||
Node node = FlowBus.getNode(nodeId);
|
Node node = FlowBus.getNode(nodeId);
|
||||||
node.execute(slotIndex);
|
node.execute(slotIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
//调用一个流程并返回LiteflowResponse,上下文为默认的DefaultContext,初始参数为null
|
// 调用一个流程并返回LiteflowResponse,上下文为默认的DefaultContext,初始参数为null
|
||||||
public LiteflowResponse execute2Resp(String chainId) {
|
public LiteflowResponse execute2Resp(String chainId) {
|
||||||
return this.execute2Resp(chainId, null, DefaultContext.class);
|
return this.execute2Resp(chainId, null, DefaultContext.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
//调用一个流程并返回LiteflowResponse,上下文为默认的DefaultContext
|
// 调用一个流程并返回LiteflowResponse,上下文为默认的DefaultContext
|
||||||
public LiteflowResponse execute2Resp(String chainId, Object param) {
|
public LiteflowResponse execute2Resp(String chainId, Object param) {
|
||||||
return this.execute2Resp(chainId, param, DefaultContext.class);
|
return this.execute2Resp(chainId, param, DefaultContext.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
//调用一个流程并返回LiteflowResponse,允许多上下文的传入
|
// 调用一个流程并返回LiteflowResponse,允许多上下文的传入
|
||||||
public LiteflowResponse execute2Resp(String chainId, Object param, Class<?>... contextBeanClazzArray) {
|
public LiteflowResponse execute2Resp(String chainId, Object param, Class<?>... contextBeanClazzArray) {
|
||||||
return this.execute2Resp(chainId, param, contextBeanClazzArray, null);
|
return this.execute2Resp(chainId, param, contextBeanClazzArray, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteflowResponse execute2Resp(String chainId, Object param, Object... contextBeanArray) {
|
public LiteflowResponse execute2Resp(String chainId, Object param, Object... contextBeanArray) {
|
||||||
return this.execute2Resp(chainId, param, null, contextBeanArray);
|
return this.execute2Resp(chainId, param, null, contextBeanArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
//调用一个流程并返回Future<LiteflowResponse>,允许多上下文的传入
|
// 调用一个流程并返回Future<LiteflowResponse>,允许多上下文的传入
|
||||||
public Future<LiteflowResponse> execute2Future(String chainId, Object param, Class<?>... contextBeanClazzArray) {
|
public Future<LiteflowResponse> execute2Future(String chainId, Object param, Class<?>... contextBeanClazzArray) {
|
||||||
return ExecutorHelper.loadInstance().buildMainExecutor(liteflowConfig.getMainExecutorClass()).submit(()
|
return ExecutorHelper.loadInstance()
|
||||||
-> FlowExecutorHolder.loadInstance().execute2Resp(chainId, param, contextBeanClazzArray, null));
|
.buildMainExecutor(liteflowConfig.getMainExecutorClass())
|
||||||
}
|
.submit(() -> FlowExecutorHolder.loadInstance().execute2Resp(chainId, param, contextBeanClazzArray, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<LiteflowResponse> execute2Future(String chainId, Object param, Object... contextBeanArray) {
|
||||||
|
return ExecutorHelper.loadInstance()
|
||||||
|
.buildMainExecutor(liteflowConfig.getMainExecutorClass())
|
||||||
|
.submit(() -> FlowExecutorHolder.loadInstance().execute2Resp(chainId, param, null, contextBeanArray));
|
||||||
|
}
|
||||||
|
|
||||||
public Future<LiteflowResponse> execute2Future(String chainId, Object param, Object... contextBeanArray) {
|
// 调用一个流程,返回默认的上下文,适用于简单的调用
|
||||||
return ExecutorHelper.loadInstance().buildMainExecutor(liteflowConfig.getMainExecutorClass()).submit(()
|
@Deprecated
|
||||||
-> FlowExecutorHolder.loadInstance().execute2Resp(chainId, param, null, contextBeanArray));
|
public DefaultContext execute(String chainId, Object param) throws Exception {
|
||||||
}
|
LiteflowResponse response = this.execute2Resp(chainId, param, DefaultContext.class);
|
||||||
|
if (!response.isSuccess()) {
|
||||||
|
throw response.getCause();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return response.getFirstContextBean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//调用一个流程,返回默认的上下文,适用于简单的调用
|
private LiteflowResponse execute2Resp(String chainId, Object param, Class<?>[] contextBeanClazzArray,
|
||||||
@Deprecated
|
Object[] contextBeanArray) {
|
||||||
public DefaultContext execute(String chainId, Object param) throws Exception {
|
Slot slot = doExecute(chainId, param, contextBeanClazzArray, contextBeanArray, null, InnerChainTypeEnum.NONE);
|
||||||
LiteflowResponse response = this.execute2Resp(chainId, param, DefaultContext.class);
|
return LiteflowResponse.newMainResponse(slot);
|
||||||
if (!response.isSuccess()) {
|
}
|
||||||
throw response.getCause();
|
|
||||||
} else {
|
|
||||||
return response.getFirstContextBean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LiteflowResponse execute2Resp(String chainId,
|
private LiteflowResponse invoke2Resp(String chainId, Object param, Integer slotIndex,
|
||||||
Object param,
|
InnerChainTypeEnum innerChainType) {
|
||||||
Class<?>[] contextBeanClazzArray,
|
Slot slot = doExecute(chainId, param, null, null, slotIndex, innerChainType);
|
||||||
Object[] contextBeanArray) {
|
return LiteflowResponse.newInnerResponse(chainId, slot);
|
||||||
Slot slot = doExecute(chainId, param, contextBeanClazzArray, contextBeanArray, null, InnerChainTypeEnum.NONE);
|
}
|
||||||
return LiteflowResponse.newMainResponse(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LiteflowResponse invoke2Resp(String chainId,
|
private Slot doExecute(String chainId, Object param, Class<?>[] contextBeanClazzArray, Object[] contextBeanArray,
|
||||||
Object param,
|
Integer slotIndex, InnerChainTypeEnum innerChainType) {
|
||||||
Integer slotIndex, InnerChainTypeEnum innerChainType) {
|
if (FlowBus.needInit()) {
|
||||||
Slot slot = doExecute(chainId, param, null, null, slotIndex, innerChainType);
|
init(true);
|
||||||
return LiteflowResponse.newInnerResponse(chainId, slot);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Slot doExecute(String chainId,
|
// 如果不是隐式流程,那么需要分配Slot
|
||||||
Object param,
|
if (innerChainType.equals(InnerChainTypeEnum.NONE) && ObjectUtil.isNull(slotIndex)) {
|
||||||
Class<?>[] contextBeanClazzArray,
|
// 这里可以根据class分配,也可以根据bean去分配
|
||||||
Object[] contextBeanArray,
|
if (ArrayUtil.isNotEmpty(contextBeanClazzArray)) {
|
||||||
Integer slotIndex,
|
slotIndex = DataBus.offerSlotByClass(ListUtil.toList(contextBeanClazzArray));
|
||||||
InnerChainTypeEnum innerChainType) {
|
}
|
||||||
if (FlowBus.needInit()) {
|
else {
|
||||||
init(true);
|
slotIndex = DataBus.offerSlotByBean(ListUtil.toList(contextBeanArray));
|
||||||
}
|
}
|
||||||
|
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
||||||
|
LOG.info("slot[{}] offered", slotIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//如果不是隐式流程,那么需要分配Slot
|
if (slotIndex == -1) {
|
||||||
if (innerChainType.equals(InnerChainTypeEnum.NONE) && ObjectUtil.isNull(slotIndex)) {
|
throw new NoAvailableSlotException("there is no available slot");
|
||||||
//这里可以根据class分配,也可以根据bean去分配
|
}
|
||||||
if (ArrayUtil.isNotEmpty(contextBeanClazzArray)) {
|
|
||||||
slotIndex = DataBus.offerSlotByClass(ListUtil.toList(contextBeanClazzArray));
|
|
||||||
} else {
|
|
||||||
slotIndex = DataBus.offerSlotByBean(ListUtil.toList(contextBeanArray));
|
|
||||||
}
|
|
||||||
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
|
||||||
LOG.info("slot[{}] offered", slotIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slotIndex == -1) {
|
Slot slot = DataBus.getSlot(slotIndex);
|
||||||
throw new NoAvailableSlotException("there is no available slot");
|
if (ObjectUtil.isNull(slot)) {
|
||||||
}
|
throw new NoAvailableSlotException(StrUtil.format("the slot[{}] is not exist", slotIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是隐式流程,事先把subException给置空,然后把隐式流程的chainId放入slot元数据中
|
||||||
|
// 我知道这在多线程调用隐式流程中会有问题。但是考虑到这种场景的不会多,也有其他的转换方式。
|
||||||
|
// 所以暂且这么做,以后再优化
|
||||||
|
if (!innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
||||||
|
slot.removeSubException(chainId);
|
||||||
|
slot.addSubChain(chainId);
|
||||||
|
}
|
||||||
|
|
||||||
Slot slot = DataBus.getSlot(slotIndex);
|
if (StrUtil.isBlank(slot.getRequestId())) {
|
||||||
if (ObjectUtil.isNull(slot)) {
|
slot.generateRequestId();
|
||||||
throw new NoAvailableSlotException(StrUtil.format("the slot[{}] is not exist", slotIndex));
|
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
||||||
}
|
LOG.info("requestId[{}] has generated", slot.getRequestId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//如果是隐式流程,事先把subException给置空,然后把隐式流程的chainId放入slot元数据中
|
if (ObjectUtil.isNotNull(param)) {
|
||||||
//我知道这在多线程调用隐式流程中会有问题。但是考虑到这种场景的不会多,也有其他的转换方式。
|
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
||||||
//所以暂且这么做,以后再优化
|
slot.setRequestData(param);
|
||||||
if (!innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
}
|
||||||
slot.removeSubException(chainId);
|
else if (innerChainType.equals(InnerChainTypeEnum.IN_SYNC)) {
|
||||||
slot.addSubChain(chainId);
|
slot.setChainReqData(chainId, param);
|
||||||
}
|
}
|
||||||
|
else if (innerChainType.equals(InnerChainTypeEnum.IN_ASYNC)) {
|
||||||
|
slot.setChainReqData2Queue(chainId, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (StrUtil.isBlank(slot.getRequestId())) {
|
Chain chain = null;
|
||||||
slot.generateRequestId();
|
try {
|
||||||
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
chain = FlowBus.getChain(chainId);
|
||||||
LOG.info("requestId[{}] has generated", slot.getRequestId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ObjectUtil.isNotNull(param)) {
|
if (ObjectUtil.isNull(chain)) {
|
||||||
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
String errorMsg = StrUtil.format("[{}]:couldn't find chain with the id[{}]", slot.getRequestId(),
|
||||||
slot.setRequestData(param);
|
chainId);
|
||||||
} else if (innerChainType.equals(InnerChainTypeEnum.IN_SYNC)) {
|
throw new ChainNotFoundException(errorMsg);
|
||||||
slot.setChainReqData(chainId, param);
|
}
|
||||||
} else if (innerChainType.equals(InnerChainTypeEnum.IN_ASYNC)) {
|
// 执行chain
|
||||||
slot.setChainReqData2Queue(chainId, param);
|
chain.execute(slotIndex);
|
||||||
}
|
}
|
||||||
}
|
catch (ChainEndException e) {
|
||||||
|
if (ObjectUtil.isNotNull(chain)) {
|
||||||
|
String warnMsg = StrUtil.format("[{}]:chain[{}] execute end on slot[{}]", slot.getRequestId(),
|
||||||
|
chain.getChainName(), slotIndex);
|
||||||
|
LOG.warn(warnMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
if (ObjectUtil.isNotNull(chain)) {
|
||||||
|
String errMsg = StrUtil.format("[{}]:chain[{}] execute error on slot[{}]", slot.getRequestId(),
|
||||||
|
chain.getChainName(), slotIndex);
|
||||||
|
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
||||||
|
LOG.error(errMsg, e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.error(errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
||||||
|
LOG.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Chain chain = null;
|
// 如果是正常流程需要把异常设置到slot的exception属性里
|
||||||
try {
|
// 如果是隐式流程,则需要设置到隐式流程的exception属性里
|
||||||
chain = FlowBus.getChain(chainId);
|
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
||||||
|
slot.setException(e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slot.setSubException(chainId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
||||||
|
slot.printStep();
|
||||||
|
DataBus.releaseSlot(slotIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
if (ObjectUtil.isNull(chain)) {
|
public LiteflowConfig getLiteflowConfig() {
|
||||||
String errorMsg = StrUtil.format("[{}]:couldn't find chain with the id[{}]", slot.getRequestId(), chainId);
|
return liteflowConfig;
|
||||||
throw new ChainNotFoundException(errorMsg);
|
}
|
||||||
}
|
|
||||||
// 执行chain
|
|
||||||
chain.execute(slotIndex);
|
|
||||||
} catch (ChainEndException e) {
|
|
||||||
if (ObjectUtil.isNotNull(chain)) {
|
|
||||||
String warnMsg = StrUtil.format("[{}]:chain[{}] execute end on slot[{}]", slot.getRequestId(), chain.getChainName(), slotIndex);
|
|
||||||
LOG.warn(warnMsg);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (ObjectUtil.isNotNull(chain)) {
|
|
||||||
String errMsg = StrUtil.format("[{}]:chain[{}] execute error on slot[{}]", slot.getRequestId(), chain.getChainName(), slotIndex);
|
|
||||||
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
|
||||||
LOG.error(errMsg, e);
|
|
||||||
} else {
|
|
||||||
LOG.error(errMsg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
|
|
||||||
LOG.error(e.getMessage(), e);
|
|
||||||
} else {
|
|
||||||
LOG.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//如果是正常流程需要把异常设置到slot的exception属性里
|
public void setLiteflowConfig(LiteflowConfig liteflowConfig) {
|
||||||
//如果是隐式流程,则需要设置到隐式流程的exception属性里
|
this.liteflowConfig = liteflowConfig;
|
||||||
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
// 把liteFlowConfig设到LiteFlowGetter中去
|
||||||
slot.setException(e);
|
LiteflowConfigGetter.setLiteflowConfig(liteflowConfig);
|
||||||
} else {
|
}
|
||||||
slot.setSubException(chainId, e);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
|
||||||
slot.printStep();
|
|
||||||
DataBus.releaseSlot(slotIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiteflowConfig getLiteflowConfig() {
|
/**
|
||||||
return liteflowConfig;
|
* 添加监听文件路径
|
||||||
}
|
* @param pathList 文件路径
|
||||||
|
*/
|
||||||
|
private void addMonitorFilePaths(List<String> pathList) throws Exception {
|
||||||
|
// 添加规则文件监听
|
||||||
|
List<String> fileAbsolutePath = PathContentParserHolder.loadContextAware().getFileAbsolutePath(pathList);
|
||||||
|
MonitorFile.getInstance().addMonitorFilePaths(fileAbsolutePath);
|
||||||
|
}
|
||||||
|
|
||||||
public void setLiteflowConfig(LiteflowConfig liteflowConfig) {
|
|
||||||
this.liteflowConfig = liteflowConfig;
|
|
||||||
//把liteFlowConfig设到LiteFlowGetter中去
|
|
||||||
LiteflowConfigGetter.setLiteflowConfig(liteflowConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加监听文件路径
|
|
||||||
*
|
|
||||||
* @param pathList 文件路径
|
|
||||||
*/
|
|
||||||
private void addMonitorFilePaths(List<String> pathList) throws Exception {
|
|
||||||
// 添加规则文件监听
|
|
||||||
List<String> fileAbsolutePath = PathContentParserHolder.loadContextAware().getFileAbsolutePath(pathList);
|
|
||||||
MonitorFile.getInstance().addMonitorFilePaths(fileAbsolutePath);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -9,27 +9,28 @@ import com.yomahub.liteflow.property.LiteflowConfig;
|
||||||
*/
|
*/
|
||||||
public class FlowExecutorHolder {
|
public class FlowExecutorHolder {
|
||||||
|
|
||||||
private static FlowExecutor flowExecutor;
|
private static FlowExecutor flowExecutor;
|
||||||
|
|
||||||
public static FlowExecutor loadInstance(LiteflowConfig liteflowConfig){
|
public static FlowExecutor loadInstance(LiteflowConfig liteflowConfig) {
|
||||||
if (ObjectUtil.isNull(flowExecutor)){
|
if (ObjectUtil.isNull(flowExecutor)) {
|
||||||
flowExecutor = new FlowExecutor(liteflowConfig);
|
flowExecutor = new FlowExecutor(liteflowConfig);
|
||||||
}
|
}
|
||||||
return flowExecutor;
|
return flowExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FlowExecutor loadInstance(){
|
public static FlowExecutor loadInstance() {
|
||||||
if (ObjectUtil.isNull(flowExecutor)){
|
if (ObjectUtil.isNull(flowExecutor)) {
|
||||||
throw new FlowExecutorNotInitException("flow executor is not initialized yet");
|
throw new FlowExecutorNotInitException("flow executor is not initialized yet");
|
||||||
}
|
}
|
||||||
return flowExecutor;
|
return flowExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setHolder(FlowExecutor flowExecutor){
|
public static void setHolder(FlowExecutor flowExecutor) {
|
||||||
FlowExecutorHolder.flowExecutor = flowExecutor;
|
FlowExecutorHolder.flowExecutor = flowExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void clean() {
|
||||||
|
flowExecutor = null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void clean(){
|
|
||||||
flowExecutor = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,27 +7,27 @@ import java.util.List;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程初始化的钩子类,所有的钩子都放在这里
|
* 流程初始化的钩子类,所有的钩子都放在这里 目前钩子主要是放一些第三方中间件的规则监听 放的钩子要求都是无入参无返回的,所以这里是BooleanSupplier
|
||||||
* 目前钩子主要是放一些第三方中间件的规则监听
|
*
|
||||||
* 放的钩子要求都是无入参无返回的,所以这里是BooleanSupplier
|
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.4
|
* @since 2.9.4
|
||||||
*/
|
*/
|
||||||
public class FlowInitHook {
|
public class FlowInitHook {
|
||||||
|
|
||||||
private static final List<BooleanSupplier> supplierList = new ArrayList<>();
|
private static final List<BooleanSupplier> supplierList = new ArrayList<>();
|
||||||
|
|
||||||
public static void executeHook(){
|
public static void executeHook() {
|
||||||
if (CollUtil.isNotEmpty(supplierList)){
|
if (CollUtil.isNotEmpty(supplierList)) {
|
||||||
supplierList.forEach(BooleanSupplier::getAsBoolean);
|
supplierList.forEach(BooleanSupplier::getAsBoolean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addHook(BooleanSupplier hookSupplier){
|
public static void addHook(BooleanSupplier hookSupplier) {
|
||||||
supplierList.add(hookSupplier);
|
supplierList.add(hookSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void cleanHook() {
|
||||||
|
supplierList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public static void cleanHook(){
|
|
||||||
supplierList.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,17 +5,20 @@ import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 循环跳出节点逻辑抽象类
|
* 循环跳出节点逻辑抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public abstract class NodeBreakComponent extends NodeComponent{
|
public abstract class NodeBreakComponent extends NodeComponent {
|
||||||
@Override
|
|
||||||
public void process() throws Exception {
|
@Override
|
||||||
boolean breakFlag = processBreak();
|
public void process() throws Exception {
|
||||||
Slot slot = this.getSlot();
|
boolean breakFlag = processBreak();
|
||||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
Slot slot = this.getSlot();
|
||||||
slot.setBreakResult(originalClass.getName(), breakFlag);
|
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||||
}
|
slot.setBreakResult(originalClass.getName(), breakFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean processBreak() throws Exception;
|
||||||
|
|
||||||
public abstract boolean processBreak() throws Exception;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,10 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 普通组件抽象类
|
* 普通组件抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public abstract class NodeComponent{
|
public abstract class NodeComponent {
|
||||||
|
|
||||||
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@ -46,42 +47,41 @@ public abstract class NodeComponent{
|
||||||
|
|
||||||
private NodeTypeEnum type;
|
private NodeTypeEnum type;
|
||||||
|
|
||||||
//这是自己的实例,取代this
|
// 这是自己的实例,取代this
|
||||||
//为何要设置这个,用this不行么,因为如果有aop去切的话,this在spring的aop里是切不到的。self对象有可能是代理过的对象
|
// 为何要设置这个,用this不行么,因为如果有aop去切的话,this在spring的aop里是切不到的。self对象有可能是代理过的对象
|
||||||
private NodeComponent self;
|
private NodeComponent self;
|
||||||
|
|
||||||
//重试次数
|
// 重试次数
|
||||||
private int retryCount = 0;
|
private int retryCount = 0;
|
||||||
|
|
||||||
//在目标异常抛出时才重试
|
// 在目标异常抛出时才重试
|
||||||
private Class<? extends Exception>[] retryForExceptions = new Class[]{Exception.class};
|
private Class<? extends Exception>[] retryForExceptions = new Class[] { Exception.class };
|
||||||
|
|
||||||
/** 节点执行器的类全名 */
|
/** 节点执行器的类全名 */
|
||||||
private Class<? extends NodeExecutor> nodeExecutorClass = DefaultNodeExecutor.class;
|
private Class<? extends NodeExecutor> nodeExecutorClass = DefaultNodeExecutor.class;
|
||||||
|
|
||||||
/**当前对象为单例,注册进spring上下文,但是node实例不是单例,这里通过对node实例的引用来获得一些链路属性**/
|
/** 当前对象为单例,注册进spring上下文,但是node实例不是单例,这里通过对node实例的引用来获得一些链路属性 **/
|
||||||
|
|
||||||
private final TransmittableThreadLocal<Node> refNodeTL = new TransmittableThreadLocal<>();
|
private final TransmittableThreadLocal<Node> refNodeTL = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*******************以下的属性为线程附加属性********************
|
******************* 以下的属性为线程附加属性******************** 线程属性是指每一个request的值都是不一样的
|
||||||
* 线程属性是指每一个request的值都是不一样的
|
|
||||||
* 这里NodeComponent是单例,所以要用ThreadLocal来修饰
|
* 这里NodeComponent是单例,所以要用ThreadLocal来修饰
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//当前slot的index
|
// 当前slot的index
|
||||||
private final TransmittableThreadLocal<Integer> slotIndexTL = new TransmittableThreadLocal<>();
|
private final TransmittableThreadLocal<Integer> slotIndexTL = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
//是否结束整个流程,这个只对串行流程有效,并行流程无效
|
// 是否结束整个流程,这个只对串行流程有效,并行流程无效
|
||||||
private final TransmittableThreadLocal<Boolean> isEndTL = new TransmittableThreadLocal<>();
|
private final TransmittableThreadLocal<Boolean> isEndTL = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
public NodeComponent() {
|
public NodeComponent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute() throws Exception{
|
public void execute() throws Exception {
|
||||||
Slot slot = this.getSlot();
|
Slot slot = this.getSlot();
|
||||||
|
|
||||||
//在元数据里加入step信息
|
// 在元数据里加入step信息
|
||||||
CmpStep cmpStep = new CmpStep(nodeId, name, CmpStepTypeEnum.SINGLE);
|
CmpStep cmpStep = new CmpStep(nodeId, name, CmpStepTypeEnum.SINGLE);
|
||||||
cmpStep.setTag(this.getTag());
|
cmpStep.setTag(this.getTag());
|
||||||
slot.addStep(cmpStep);
|
slot.addStep(cmpStep);
|
||||||
|
@ -89,42 +89,46 @@ public abstract class NodeComponent{
|
||||||
StopWatch stopWatch = new StopWatch();
|
StopWatch stopWatch = new StopWatch();
|
||||||
stopWatch.start();
|
stopWatch.start();
|
||||||
|
|
||||||
|
try {
|
||||||
try{
|
// 前置处理
|
||||||
//前置处理
|
|
||||||
self.beforeProcess();
|
self.beforeProcess();
|
||||||
|
|
||||||
//主要的处理逻辑
|
// 主要的处理逻辑
|
||||||
self.process();
|
self.process();
|
||||||
|
|
||||||
//成功后回调方法
|
// 成功后回调方法
|
||||||
self.onSuccess();
|
self.onSuccess();
|
||||||
|
|
||||||
//步骤状态设为true
|
// 步骤状态设为true
|
||||||
cmpStep.setSuccess(true);
|
cmpStep.setSuccess(true);
|
||||||
} catch (Exception e){
|
}
|
||||||
//步骤状态设为false,并加入异常
|
catch (Exception e) {
|
||||||
|
// 步骤状态设为false,并加入异常
|
||||||
cmpStep.setSuccess(false);
|
cmpStep.setSuccess(false);
|
||||||
cmpStep.setException(e);
|
cmpStep.setException(e);
|
||||||
|
|
||||||
//执行失败后回调方法
|
// 执行失败后回调方法
|
||||||
//这里要注意,失败方法本身抛出错误,只打出堆栈,往外抛出的还是主要的异常
|
// 这里要注意,失败方法本身抛出错误,只打出堆栈,往外抛出的还是主要的异常
|
||||||
try{
|
try {
|
||||||
self.onError();
|
self.onError();
|
||||||
}catch (Exception ex){
|
}
|
||||||
String errMsg = StrUtil.format("[{}]:component[{}] onError method happens exception",slot.getRequestId(),this.getDisplayName());
|
catch (Exception ex) {
|
||||||
|
String errMsg = StrUtil.format("[{}]:component[{}] onError method happens exception",
|
||||||
|
slot.getRequestId(), this.getDisplayName());
|
||||||
LOG.error(errMsg);
|
LOG.error(errMsg);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
}
|
||||||
//后置处理
|
finally {
|
||||||
|
// 后置处理
|
||||||
self.afterProcess();
|
self.afterProcess();
|
||||||
|
|
||||||
stopWatch.stop();
|
stopWatch.stop();
|
||||||
final long timeSpent = stopWatch.getTotalTimeMillis();
|
final long timeSpent = stopWatch.getTotalTimeMillis();
|
||||||
LOG.debug("[{}]:component[{}] finished in {} milliseconds",slot.getRequestId(),this.getDisplayName(),timeSpent);
|
LOG.debug("[{}]:component[{}] finished in {} milliseconds", slot.getRequestId(), this.getDisplayName(),
|
||||||
|
timeSpent);
|
||||||
|
|
||||||
//往CmpStep中放入时间消耗信息
|
// 往CmpStep中放入时间消耗信息
|
||||||
cmpStep.setTimeSpent(timeSpent);
|
cmpStep.setTimeSpent(timeSpent);
|
||||||
|
|
||||||
// 性能统计
|
// 性能统计
|
||||||
|
@ -135,52 +139,53 @@ public abstract class NodeComponent{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beforeProcess(){
|
public void beforeProcess() {
|
||||||
//全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类
|
// 全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类
|
||||||
//非spring环境下,全局切面为空实现
|
// 非spring环境下,全局切面为空实现
|
||||||
CmpAroundAspectHolder.loadCmpAroundAspect().beforeProcess(nodeId, this.getSlot());
|
CmpAroundAspectHolder.loadCmpAroundAspect().beforeProcess(nodeId, this.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void process() throws Exception;
|
public abstract void process() throws Exception;
|
||||||
|
|
||||||
public void onSuccess() throws Exception{
|
public void onSuccess() throws Exception {
|
||||||
//如果需要在成功后回调某一个方法,请覆盖这个方法
|
// 如果需要在成功后回调某一个方法,请覆盖这个方法
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onError() throws Exception{
|
public void onError() throws Exception {
|
||||||
//如果需要在抛错后回调某一段逻辑,请覆盖这个方法
|
// 如果需要在抛错后回调某一段逻辑,请覆盖这个方法
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterProcess(){
|
public void afterProcess() {
|
||||||
CmpAroundAspectHolder.loadCmpAroundAspect().afterProcess(nodeId, this.getSlot());
|
CmpAroundAspectHolder.loadCmpAroundAspect().afterProcess(nodeId, this.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
//是否进入该节点
|
// 是否进入该节点
|
||||||
public boolean isAccess(){
|
public boolean isAccess() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//出错是否继续执行(这个只适用于并行流程,串行流程不起作用)
|
// 出错是否继续执行(这个只适用于并行流程,串行流程不起作用)
|
||||||
public boolean isContinueOnError() {
|
public boolean isContinueOnError() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//是否结束整个流程(不往下继续执行)
|
// 是否结束整个流程(不往下继续执行)
|
||||||
public boolean isEnd() {
|
public boolean isEnd() {
|
||||||
Boolean isEnd = isEndTL.get();
|
Boolean isEnd = isEndTL.get();
|
||||||
if(ObjectUtil.isNull(isEnd)){
|
if (ObjectUtil.isNull(isEnd)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return isEndTL.get();
|
return isEndTL.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置是否结束整个流程
|
// 设置是否结束整个流程
|
||||||
public void setIsEnd(boolean isEnd){
|
public void setIsEnd(boolean isEnd) {
|
||||||
this.isEndTL.set(isEnd);
|
this.isEndTL.set(isEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeIsEnd(){
|
public void removeIsEnd() {
|
||||||
this.isEndTL.remove();
|
this.isEndTL.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,19 +198,19 @@ public abstract class NodeComponent{
|
||||||
return this.slotIndexTL.get();
|
return this.slotIndexTL.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeSlotIndex(){
|
public void removeSlotIndex() {
|
||||||
this.slotIndexTL.remove();
|
this.slotIndexTL.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Slot getSlot(){
|
public Slot getSlot() {
|
||||||
return DataBus.getSlot(this.slotIndexTL.get());
|
return DataBus.getSlot(this.slotIndexTL.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getFirstContextBean(){
|
public <T> T getFirstContextBean() {
|
||||||
return this.getSlot().getFirstContextBean();
|
return this.getSlot().getFirstContextBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getContextBean(Class<T> contextBeanClazz){
|
public <T> T getContextBean(Class<T> contextBeanClazz) {
|
||||||
return this.getSlot().getContextBean(contextBeanClazz);
|
return this.getSlot().getContextBean(contextBeanClazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,11 +246,11 @@ public abstract class NodeComponent{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void sendPrivateDeliveryData(String nodeId, T t){
|
public <T> void sendPrivateDeliveryData(String nodeId, T t) {
|
||||||
this.getSlot().setPrivateDeliveryData(nodeId, t);
|
this.getSlot().setPrivateDeliveryData(nodeId, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getPrivateDeliveryData(){
|
public <T> T getPrivateDeliveryData() {
|
||||||
return this.getSlot().getPrivateDeliveryData(this.getNodeId());
|
return this.getSlot().getPrivateDeliveryData(this.getNodeId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +278,7 @@ public abstract class NodeComponent{
|
||||||
this.nodeExecutorClass = nodeExecutorClass;
|
this.nodeExecutorClass = nodeExecutorClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTag(){
|
public String getTag() {
|
||||||
return this.refNodeTL.get().getTag();
|
return this.refNodeTL.get().getTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,15 +290,15 @@ public abstract class NodeComponent{
|
||||||
this.monitorBus = monitorBus;
|
this.monitorBus = monitorBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getRequestData(){
|
public <T> T getRequestData() {
|
||||||
return getSlot().getRequestData();
|
return getSlot().getRequestData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getSubChainReqData(){
|
public <T> T getSubChainReqData() {
|
||||||
return getSlot().getChainReqData(this.getCurrChainId());
|
return getSlot().getChainReqData(this.getCurrChainId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getSubChainReqDataInAsync(){
|
public <T> T getSubChainReqDataInAsync() {
|
||||||
return getSlot().getChainReqDataFromQueue(this.getCurrChainId());
|
return getSlot().getChainReqDataFromQueue(this.getCurrChainId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,54 +307,55 @@ public abstract class NodeComponent{
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public String getChainName(){
|
public String getChainName() {
|
||||||
return getSlot().getChainName();
|
return getSlot().getChainName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getChainId(){
|
public String getChainId() {
|
||||||
return getSlot().getChainId();
|
return getSlot().getChainId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayName(){
|
public String getDisplayName() {
|
||||||
if(StrUtil.isEmpty(this.name)){
|
if (StrUtil.isEmpty(this.name)) {
|
||||||
return this.nodeId;
|
return this.nodeId;
|
||||||
}else {
|
}
|
||||||
|
else {
|
||||||
return StrUtil.format("{}({})", this.nodeId, this.name);
|
return StrUtil.format("{}({})", this.nodeId, this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrChainId(){
|
public String getCurrChainId() {
|
||||||
return getRefNode().getCurrChainId();
|
return getRefNode().getCurrChainId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getRefNode(){
|
public Node getRefNode() {
|
||||||
return this.refNodeTL.get();
|
return this.refNodeTL.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRefNode(Node refNode){
|
public void setRefNode(Node refNode) {
|
||||||
this.refNodeTL.set(refNode);
|
this.refNodeTL.set(refNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeRefNode(){
|
public void removeRefNode() {
|
||||||
this.refNodeTL.remove();
|
this.refNodeTL.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getCmpData(Class<T> clazz){
|
public <T> T getCmpData(Class<T> clazz) {
|
||||||
String cmpData = getRefNode().getCmpData();
|
String cmpData = getRefNode().getCmpData();
|
||||||
if (StrUtil.isBlank(cmpData)){
|
if (StrUtil.isBlank(cmpData)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (clazz.equals(String.class) || clazz.equals(Object.class)){
|
if (clazz.equals(String.class) || clazz.equals(Object.class)) {
|
||||||
return (T) cmpData;
|
return (T) cmpData;
|
||||||
}
|
}
|
||||||
return JsonUtil.parseObject(cmpData, clazz);
|
return JsonUtil.parseObject(cmpData, clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getLoopIndex(){
|
public Integer getLoopIndex() {
|
||||||
return this.refNodeTL.get().getLoopIndex();
|
return this.refNodeTL.get().getLoopIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getCurrLoopObj(){
|
public <T> T getCurrLoopObj() {
|
||||||
return this.refNodeTL.get().getCurrLoopObject();
|
return this.refNodeTL.get().getCurrLoopObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,4 +376,5 @@ public abstract class NodeComponent{
|
||||||
public LiteflowResponse invoke2RespInAsync(String chainId, Object param) {
|
public LiteflowResponse invoke2RespInAsync(String chainId, Object param) {
|
||||||
return FlowExecutorHolder.loadInstance().invoke2RespInAsync(chainId, param, this.getSlotIndex());
|
return FlowExecutorHolder.loadInstance().invoke2RespInAsync(chainId, param, this.getSlotIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,20 @@ import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FOR计数节点抽象类
|
* FOR计数节点抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public abstract class NodeForComponent extends NodeComponent{
|
public abstract class NodeForComponent extends NodeComponent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws Exception {
|
public void process() throws Exception {
|
||||||
int forCount = processFor();
|
int forCount = processFor();
|
||||||
Slot slot = this.getSlot();
|
Slot slot = this.getSlot();
|
||||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||||
slot.setForResult(originalClass.getName(), forCount);
|
slot.setForResult(originalClass.getName(), forCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract int processFor() throws Exception;
|
||||||
|
|
||||||
public abstract int processFor() throws Exception;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,19 @@ import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IF节点抽象类
|
* IF节点抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.8.5
|
* @since 2.8.5
|
||||||
*/
|
*/
|
||||||
public abstract class NodeIfComponent extends NodeComponent{
|
public abstract class NodeIfComponent extends NodeComponent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws Exception {
|
public void process() throws Exception {
|
||||||
boolean result = this.processIf();
|
boolean result = this.processIf();
|
||||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||||
this.getSlot().setIfResult(originalClass.getName(), result);
|
this.getSlot().setIfResult(originalClass.getName(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract boolean processIf() throws Exception;
|
||||||
|
|
||||||
public abstract boolean processIf() throws Exception;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,20 @@ import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ITERATOR迭代器循环组件抽象类
|
* ITERATOR迭代器循环组件抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.7
|
* @since 2.9.7
|
||||||
*/
|
*/
|
||||||
public abstract class NodeIteratorComponent extends NodeComponent{
|
public abstract class NodeIteratorComponent extends NodeComponent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws Exception {
|
public void process() throws Exception {
|
||||||
Iterator<?> it = processIterator();
|
Iterator<?> it = processIterator();
|
||||||
Slot slot = this.getSlot();
|
Slot slot = this.getSlot();
|
||||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||||
slot.setIteratorResult(originalClass.getName(), it);
|
slot.setIteratorResult(originalClass.getName(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract Iterator<?> processIterator() throws Exception;
|
||||||
|
|
||||||
public abstract Iterator<?> processIterator() throws Exception;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 条件路由节点抽象类
|
* 条件路由节点抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public abstract class NodeSwitchComponent extends NodeComponent {
|
public abstract class NodeSwitchComponent extends NodeComponent {
|
||||||
|
@ -22,7 +23,7 @@ public abstract class NodeSwitchComponent extends NodeComponent {
|
||||||
this.getSlot().setSwitchResult(originalClass.getName(), nodeId);
|
this.getSlot().setSwitchResult(originalClass.getName(), nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//用以返回路由节点的beanId
|
// 用以返回路由节点的beanId
|
||||||
public abstract String processSwitch() throws Exception;
|
public abstract String processSwitch() throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,17 +5,20 @@ import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WHILE条件节点抽象类
|
* WHILE条件节点抽象类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public abstract class NodeWhileComponent extends NodeComponent{
|
public abstract class NodeWhileComponent extends NodeComponent {
|
||||||
@Override
|
|
||||||
public void process() throws Exception {
|
@Override
|
||||||
boolean whileFlag = processWhile();
|
public void process() throws Exception {
|
||||||
Slot slot = this.getSlot();
|
boolean whileFlag = processWhile();
|
||||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
Slot slot = this.getSlot();
|
||||||
slot.setWhileResult(originalClass.getName(), whileFlag);
|
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||||
}
|
slot.setWhileResult(originalClass.getName(), whileFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean processWhile() throws Exception;
|
||||||
|
|
||||||
public abstract boolean processWhile() throws Exception;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,23 +7,28 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本BREAK节点
|
* 脚本BREAK节点
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class ScriptBreakComponent extends NodeBreakComponent implements ScriptComponent{
|
public class ScriptBreakComponent extends NodeBreakComponent implements ScriptComponent {
|
||||||
@Override
|
|
||||||
public boolean processBreak() throws Exception {
|
@Override
|
||||||
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
public boolean processBreak() throws Exception {
|
||||||
wrap.setCurrChainId(this.getCurrChainId());
|
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
||||||
wrap.setNodeId(this.getNodeId());
|
wrap.setCurrChainId(this.getCurrChainId());
|
||||||
wrap.setSlotIndex(this.getSlotIndex());
|
wrap.setNodeId(this.getNodeId());
|
||||||
wrap.setTag(this.getTag());
|
wrap.setSlotIndex(this.getSlotIndex());
|
||||||
wrap.setCmpData(this.getCmpData(Map.class));
|
wrap.setTag(this.getTag());
|
||||||
return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
wrap.setCmpData(this.getCmpData(Map.class));
|
||||||
}
|
return (boolean) ScriptExecutorFactory.loadInstance()
|
||||||
|
.getScriptExecutor(this.getRefNode().getLanguage())
|
||||||
|
.execute(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadScript(String script, String language) {
|
||||||
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadScript(String script, String language) {
|
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,29 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本组件类
|
* 脚本组件类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
public class ScriptCommonComponent extends NodeComponent implements ScriptComponent{
|
public class ScriptCommonComponent extends NodeComponent implements ScriptComponent {
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws Exception {
|
public void process() throws Exception {
|
||||||
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
||||||
wrap.setCurrChainId(this.getCurrChainId());
|
wrap.setCurrChainId(this.getCurrChainId());
|
||||||
wrap.setNodeId(this.getNodeId());
|
wrap.setNodeId(this.getNodeId());
|
||||||
wrap.setSlotIndex(this.getSlotIndex());
|
wrap.setSlotIndex(this.getSlotIndex());
|
||||||
wrap.setTag(this.getTag());
|
wrap.setTag(this.getTag());
|
||||||
wrap.setCmpData(this.getCmpData(Map.class));
|
wrap.setCmpData(this.getCmpData(Map.class));
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadScript(String script, String language) {
|
||||||
|
log.info("load script for component[{}]", getDisplayName());
|
||||||
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadScript(String script, String language) {
|
|
||||||
log.info("load script for component[{}]", getDisplayName());
|
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,26 +7,30 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本接口
|
* 脚本接口
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public interface ScriptComponent {
|
public interface ScriptComponent {
|
||||||
/**
|
|
||||||
* 用于维护脚本类型和脚本 cmp 的映射关系
|
|
||||||
*/
|
|
||||||
Map<NodeTypeEnum, Class<?>> ScriptComponentClassMap = new HashMap<NodeTypeEnum, Class<?>>() {{
|
|
||||||
put(NodeTypeEnum.SCRIPT, ScriptCommonComponent.class);
|
|
||||||
put(NodeTypeEnum.SWITCH_SCRIPT, ScriptSwitchComponent.class);
|
|
||||||
put(NodeTypeEnum.IF_SCRIPT, ScriptIfComponent.class);
|
|
||||||
put(NodeTypeEnum.FOR_SCRIPT, ScriptForComponent.class);
|
|
||||||
put(NodeTypeEnum.WHILE_SCRIPT, ScriptWhileComponent.class);
|
|
||||||
put(NodeTypeEnum.BREAK_SCRIPT, ScriptBreakComponent.class);
|
|
||||||
}};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于维护脚本类型和脚本 cmp 的映射关系
|
||||||
|
*/
|
||||||
|
Map<NodeTypeEnum, Class<?>> ScriptComponentClassMap = new HashMap<NodeTypeEnum, Class<?>>() {
|
||||||
|
{
|
||||||
|
put(NodeTypeEnum.SCRIPT, ScriptCommonComponent.class);
|
||||||
|
put(NodeTypeEnum.SWITCH_SCRIPT, ScriptSwitchComponent.class);
|
||||||
|
put(NodeTypeEnum.IF_SCRIPT, ScriptIfComponent.class);
|
||||||
|
put(NodeTypeEnum.FOR_SCRIPT, ScriptForComponent.class);
|
||||||
|
put(NodeTypeEnum.WHILE_SCRIPT, ScriptWhileComponent.class);
|
||||||
|
put(NodeTypeEnum.BREAK_SCRIPT, ScriptBreakComponent.class);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载脚本
|
||||||
|
* @param script
|
||||||
|
*/
|
||||||
|
void loadScript(String script, String language);
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载脚本
|
|
||||||
* @param script
|
|
||||||
*/
|
|
||||||
void loadScript(String script, String language);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,23 +7,28 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本FOR节点
|
* 脚本FOR节点
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class ScriptForComponent extends NodeForComponent implements ScriptComponent{
|
public class ScriptForComponent extends NodeForComponent implements ScriptComponent {
|
||||||
@Override
|
|
||||||
public int processFor() throws Exception {
|
@Override
|
||||||
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
public int processFor() throws Exception {
|
||||||
wrap.setCurrChainId(this.getCurrChainId());
|
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
||||||
wrap.setNodeId(this.getNodeId());
|
wrap.setCurrChainId(this.getCurrChainId());
|
||||||
wrap.setSlotIndex(this.getSlotIndex());
|
wrap.setNodeId(this.getNodeId());
|
||||||
wrap.setTag(this.getTag());
|
wrap.setSlotIndex(this.getSlotIndex());
|
||||||
wrap.setCmpData(this.getCmpData(Map.class));
|
wrap.setTag(this.getTag());
|
||||||
return (int) ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
wrap.setCmpData(this.getCmpData(Map.class));
|
||||||
}
|
return (int) ScriptExecutorFactory.loadInstance()
|
||||||
|
.getScriptExecutor(this.getRefNode().getLanguage())
|
||||||
|
.execute(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadScript(String script, String language) {
|
||||||
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadScript(String script, String language) {
|
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,23 +7,28 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本IF节点
|
* 脚本IF节点
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.8.5
|
* @since 2.8.5
|
||||||
*/
|
*/
|
||||||
public class ScriptIfComponent extends NodeIfComponent implements ScriptComponent{
|
public class ScriptIfComponent extends NodeIfComponent implements ScriptComponent {
|
||||||
@Override
|
|
||||||
public boolean processIf() throws Exception {
|
@Override
|
||||||
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
public boolean processIf() throws Exception {
|
||||||
wrap.setCurrChainId(this.getCurrChainId());
|
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
||||||
wrap.setNodeId(this.getNodeId());
|
wrap.setCurrChainId(this.getCurrChainId());
|
||||||
wrap.setSlotIndex(this.getSlotIndex());
|
wrap.setNodeId(this.getNodeId());
|
||||||
wrap.setTag(this.getTag());
|
wrap.setSlotIndex(this.getSlotIndex());
|
||||||
wrap.setCmpData(this.getCmpData(Map.class));
|
wrap.setTag(this.getTag());
|
||||||
return (boolean)ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
wrap.setCmpData(this.getCmpData(Map.class));
|
||||||
}
|
return (boolean) ScriptExecutorFactory.loadInstance()
|
||||||
|
.getScriptExecutor(this.getRefNode().getLanguage())
|
||||||
|
.execute(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadScript(String script, String language) {
|
||||||
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadScript(String script, String language) {
|
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,28 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本条件节点
|
* 脚本条件节点
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
public class ScriptSwitchComponent extends NodeSwitchComponent implements ScriptComponent{
|
public class ScriptSwitchComponent extends NodeSwitchComponent implements ScriptComponent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String processSwitch() throws Exception {
|
public String processSwitch() throws Exception {
|
||||||
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
||||||
wrap.setCurrChainId(this.getCurrChainId());
|
wrap.setCurrChainId(this.getCurrChainId());
|
||||||
wrap.setNodeId(this.getNodeId());
|
wrap.setNodeId(this.getNodeId());
|
||||||
wrap.setSlotIndex(this.getSlotIndex());
|
wrap.setSlotIndex(this.getSlotIndex());
|
||||||
wrap.setTag(this.getTag());
|
wrap.setTag(this.getTag());
|
||||||
wrap.setCmpData(this.getCmpData(Map.class));
|
wrap.setCmpData(this.getCmpData(Map.class));
|
||||||
return (String)ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
return (String) ScriptExecutorFactory.loadInstance()
|
||||||
}
|
.getScriptExecutor(this.getRefNode().getLanguage())
|
||||||
|
.execute(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadScript(String script, String language) {
|
||||||
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadScript(String script, String language) {
|
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,28 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本WHILE节点
|
* 脚本WHILE节点
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*/
|
*/
|
||||||
public class ScriptWhileComponent extends NodeWhileComponent implements ScriptComponent{
|
public class ScriptWhileComponent extends NodeWhileComponent implements ScriptComponent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processWhile() throws Exception {
|
public boolean processWhile() throws Exception {
|
||||||
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
ScriptExecuteWrap wrap = new ScriptExecuteWrap();
|
||||||
wrap.setCurrChainId(this.getCurrChainId());
|
wrap.setCurrChainId(this.getCurrChainId());
|
||||||
wrap.setNodeId(this.getNodeId());
|
wrap.setNodeId(this.getNodeId());
|
||||||
wrap.setSlotIndex(this.getSlotIndex());
|
wrap.setSlotIndex(this.getSlotIndex());
|
||||||
wrap.setTag(this.getTag());
|
wrap.setTag(this.getTag());
|
||||||
wrap.setCmpData(this.getCmpData(Map.class));
|
wrap.setCmpData(this.getCmpData(Map.class));
|
||||||
return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap);
|
return (boolean) ScriptExecutorFactory.loadInstance()
|
||||||
}
|
.getScriptExecutor(this.getRefNode().getLanguage())
|
||||||
|
.execute(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadScript(String script, String language) {
|
||||||
|
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadScript(String script, String language) {
|
|
||||||
ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,181 +34,190 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 声明式组件的代理核心生成类
|
* 声明式组件的代理核心生成类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.6.14
|
* @since 2.6.14
|
||||||
*/
|
*/
|
||||||
public class ComponentProxy {
|
public class ComponentProxy {
|
||||||
|
|
||||||
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
private final String nodeId;
|
private final String nodeId;
|
||||||
|
|
||||||
private final Object bean;
|
private final Object bean;
|
||||||
|
|
||||||
private final Class<?> clazz;
|
private final Class<?> clazz;
|
||||||
|
|
||||||
public ComponentProxy(String nodeId, Object bean, Class<?> clazz) {
|
public ComponentProxy(String nodeId, Object bean, Class<?> clazz) {
|
||||||
this.nodeId = nodeId;
|
this.nodeId = nodeId;
|
||||||
this.bean = bean;
|
this.bean = bean;
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NodeComponent> getProxyList() throws Exception{
|
public List<NodeComponent> getProxyList() throws Exception {
|
||||||
//这里要判断bean是否是spring代理过的bean,如果是代理过的bean需要取到原class对象
|
// 这里要判断bean是否是spring代理过的bean,如果是代理过的bean需要取到原class对象
|
||||||
Class<?> beanClazz;
|
Class<?> beanClazz;
|
||||||
if (LiteFlowProxyUtil.isCglibProxyClass(bean.getClass())){
|
if (LiteFlowProxyUtil.isCglibProxyClass(bean.getClass())) {
|
||||||
beanClazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
|
beanClazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
|
||||||
}else{
|
}
|
||||||
beanClazz = bean.getClass();
|
else {
|
||||||
}
|
beanClazz = bean.getClass();
|
||||||
//得到当前bean里所覆盖的LiteflowMethod(一定是被@LiteFlowMethod修饰的),自己定义的不算
|
}
|
||||||
Map<String, List<Method>> methodListMap = Arrays.stream(beanClazz.getMethods()).filter(
|
// 得到当前bean里所覆盖的LiteflowMethod(一定是被@LiteFlowMethod修饰的),自己定义的不算
|
||||||
m -> m.getAnnotation(LiteflowMethod.class) != null
|
Map<String, List<Method>> methodListMap = Arrays.stream(beanClazz.getMethods())
|
||||||
).collect(Collectors.groupingBy(
|
.filter(m -> m.getAnnotation(LiteflowMethod.class) != null)
|
||||||
m -> m.getAnnotation(LiteflowMethod.class).nodeId()
|
.collect(Collectors.groupingBy(m -> m.getAnnotation(LiteflowMethod.class).nodeId()));
|
||||||
));
|
|
||||||
|
|
||||||
return methodListMap.entrySet().stream().map(entry -> {
|
return methodListMap.entrySet().stream().map(entry -> {
|
||||||
// 获取当前节点的原有注解,如:LiteFlowRetry 之类的规则注解
|
// 获取当前节点的原有注解,如:LiteFlowRetry 之类的规则注解
|
||||||
Annotation[] beanClassAnnotation = beanClazz.getAnnotations();
|
Annotation[] beanClassAnnotation = beanClazz.getAnnotations();
|
||||||
// 如果entry的key为空字符串,则是为了兼容老版本的写法,即:没有指定nodeId的情况
|
// 如果entry的key为空字符串,则是为了兼容老版本的写法,即:没有指定nodeId的情况
|
||||||
// 判断是否是方法级创造节点
|
// 判断是否是方法级创造节点
|
||||||
boolean isMethodCreate = !StrUtil.isEmpty(entry.getKey());
|
boolean isMethodCreate = !StrUtil.isEmpty(entry.getKey());
|
||||||
// 获取当前bean 真实的nodeId
|
// 获取当前bean 真实的nodeId
|
||||||
String activeNodeId = isMethodCreate ? entry.getKey() : nodeId;
|
String activeNodeId = isMethodCreate ? entry.getKey() : nodeId;
|
||||||
// 获取当前节点所有的@LiteflowRetry @LiteflowMethod注解对
|
// 获取当前节点所有的@LiteflowRetry @LiteflowMethod注解对
|
||||||
List<Tuple> tupleList = entry.getValue().stream().map(m ->
|
List<Tuple> tupleList = entry.getValue()
|
||||||
new Tuple(m.getAnnotation(LiteflowRetry.class), m.getAnnotation(LiteflowMethod.class))
|
.stream()
|
||||||
).collect(Collectors.toList());
|
.map(m -> new Tuple(m.getAnnotation(LiteflowRetry.class), m.getAnnotation(LiteflowMethod.class)))
|
||||||
// 获取当前节点的所有LiteFlowMethod注解
|
.collect(Collectors.toList());
|
||||||
List<LiteflowMethod> methodList = tupleList.stream().map(tuple -> ((LiteflowMethod)tuple.get(1)))
|
// 获取当前节点的所有LiteFlowMethod注解
|
||||||
.filter(Objects::nonNull)
|
List<LiteflowMethod> methodList = tupleList.stream()
|
||||||
.collect(Collectors.toList());
|
.map(tuple -> ((LiteflowMethod) tuple.get(1)))
|
||||||
// nodeType去重
|
.filter(Objects::nonNull)
|
||||||
List<? extends Class<? extends NodeComponent>> classes = methodList.stream()
|
.collect(Collectors.toList());
|
||||||
.map(LiteflowMethod::nodeType)
|
// nodeType去重
|
||||||
.map(NodeTypeEnum::getMappingClazz)
|
List<? extends Class<? extends NodeComponent>> classes = methodList.stream()
|
||||||
.distinct()
|
.map(LiteflowMethod::nodeType)
|
||||||
.collect(Collectors.toList());
|
.map(NodeTypeEnum::getMappingClazz)
|
||||||
// 相同nodeId里只能定义同一种的类型的NodeComponent
|
.distinct()
|
||||||
boolean legal = classes.size() == 1;
|
.collect(Collectors.toList());
|
||||||
if (!legal){
|
// 相同nodeId里只能定义同一种的类型的NodeComponent
|
||||||
throw new LiteFlowException("The cmpClass of the same nodeId must be the same,you declared nodeId:" + activeNodeId + ",cmpClass:" + classes);
|
boolean legal = classes.size() == 1;
|
||||||
}
|
if (!legal) {
|
||||||
// 当前节点实际LiteflowRetry注解
|
throw new LiteFlowException("The cmpClass of the same nodeId must be the same,you declared nodeId:"
|
||||||
AtomicReference<LiteflowRetry> liteflowRetryAtomicReference = new AtomicReference<>(null);
|
+ activeNodeId + ",cmpClass:" + classes);
|
||||||
// 相同nodeId只能有一个LiteflowRetry定义方法,且必须再Process方法上
|
}
|
||||||
boolean illegal = tupleList.stream().anyMatch(
|
// 当前节点实际LiteflowRetry注解
|
||||||
tuple -> {
|
AtomicReference<LiteflowRetry> liteflowRetryAtomicReference = new AtomicReference<>(null);
|
||||||
LiteflowRetry liteflowRetry = tuple.get(0);
|
// 相同nodeId只能有一个LiteflowRetry定义方法,且必须再Process方法上
|
||||||
LiteflowMethod liteflowMethod = tuple.get(1);
|
boolean illegal = tupleList.stream().anyMatch(tuple -> {
|
||||||
boolean existRetry = liteflowRetry != null;
|
LiteflowRetry liteflowRetry = tuple.get(0);
|
||||||
boolean isProcess = liteflowMethod.value().isMainMethod();
|
LiteflowMethod liteflowMethod = tuple.get(1);
|
||||||
// 如果是再Process方法上的liteflowRetry注解,则默认为真实节点。
|
boolean existRetry = liteflowRetry != null;
|
||||||
if (isProcess && existRetry) {
|
boolean isProcess = liteflowMethod.value().isMainMethod();
|
||||||
liteflowRetryAtomicReference.set(liteflowRetry);
|
// 如果是再Process方法上的liteflowRetry注解,则默认为真实节点。
|
||||||
}
|
if (isProcess && existRetry) {
|
||||||
// 如果存在existRetry注解,但是不是在Process方法上,则为非法
|
liteflowRetryAtomicReference.set(liteflowRetry);
|
||||||
return existRetry && !isProcess;
|
}
|
||||||
}
|
// 如果存在existRetry注解,但是不是在Process方法上,则为非法
|
||||||
);
|
return existRetry && !isProcess;
|
||||||
if (illegal){
|
});
|
||||||
throw new LiteFlowException("the retry annotation (@LiteflowRetry) must be declared on the PROCESS method");
|
if (illegal) {
|
||||||
}
|
throw new LiteFlowException(
|
||||||
// 生成nodeCmp的类型,默认为全局定义的clazz
|
"the retry annotation (@LiteflowRetry) must be declared on the PROCESS method");
|
||||||
Class<?> cmpClazz;
|
}
|
||||||
cmpClazz = clazz;
|
// 生成nodeCmp的类型,默认为全局定义的clazz
|
||||||
// 判断是否是方法声明的组件
|
Class<?> cmpClazz;
|
||||||
if (isMethodCreate){
|
cmpClazz = clazz;
|
||||||
cmpClazz = methodList.iterator().next().nodeType().getMappingClazz();
|
// 判断是否是方法声明的组件
|
||||||
LiteflowRetry liteflowRetry;
|
if (isMethodCreate) {
|
||||||
if ((liteflowRetry = liteflowRetryAtomicReference.get()) != null){
|
cmpClazz = methodList.iterator().next().nodeType().getMappingClazz();
|
||||||
// 增加LiteFlowRetry注解到注解数组里
|
LiteflowRetry liteflowRetry;
|
||||||
List<Annotation> annotations = Arrays.stream(beanClassAnnotation)
|
if ((liteflowRetry = liteflowRetryAtomicReference.get()) != null) {
|
||||||
.filter(a -> !a.annotationType().equals(LiteflowRetry.class))
|
// 增加LiteFlowRetry注解到注解数组里
|
||||||
.collect(Collectors.toList());
|
List<Annotation> annotations = Arrays.stream(beanClassAnnotation)
|
||||||
annotations.add(liteflowRetry);
|
.filter(a -> !a.annotationType().equals(LiteflowRetry.class))
|
||||||
beanClassAnnotation = new Annotation[annotations.size()];
|
.collect(Collectors.toList());
|
||||||
annotations.toArray(beanClassAnnotation);
|
annotations.add(liteflowRetry);
|
||||||
}
|
beanClassAnnotation = new Annotation[annotations.size()];
|
||||||
}
|
annotations.toArray(beanClassAnnotation);
|
||||||
try {
|
}
|
||||||
//创建对象
|
}
|
||||||
//这里package进行了重设,放到了被代理对象的所在目录
|
try {
|
||||||
//生成的对象也加了上被代理对象拥有的注解
|
// 创建对象
|
||||||
//被拦截的对象也根据被代理对象根据@LiteFlowMethod所标注的进行了动态判断
|
// 这里package进行了重设,放到了被代理对象的所在目录
|
||||||
Object instance = new ByteBuddy().subclass(cmpClazz)
|
// 生成的对象也加了上被代理对象拥有的注解
|
||||||
.name(StrUtil.format("{}.ByteBuddy${}${}",
|
// 被拦截的对象也根据被代理对象根据@LiteFlowMethod所标注的进行了动态判断
|
||||||
ClassUtil.getPackage(beanClazz),
|
Object instance = new ByteBuddy().subclass(cmpClazz)
|
||||||
activeNodeId,
|
.name(StrUtil.format("{}.ByteBuddy${}${}", ClassUtil.getPackage(beanClazz), activeNodeId,
|
||||||
SerialsUtil.generateShortUUID()))
|
SerialsUtil.generateShortUUID()))
|
||||||
.method(ElementMatchers.namedOneOf(methodList.stream().map(m -> m.value().getMethodName()).toArray(String[]::new)))
|
.method(ElementMatchers
|
||||||
.intercept(InvocationHandlerAdapter.of(new AopInvocationHandler(bean)))
|
.namedOneOf(methodList.stream().map(m -> m.value().getMethodName()).toArray(String[]::new)))
|
||||||
.annotateType(beanClassAnnotation)
|
.intercept(InvocationHandlerAdapter.of(new AopInvocationHandler(bean)))
|
||||||
.make()
|
.annotateType(beanClassAnnotation)
|
||||||
.load(ComponentProxy.class.getClassLoader())
|
.make()
|
||||||
.getLoaded()
|
.load(ComponentProxy.class.getClassLoader())
|
||||||
.newInstance();
|
.getLoaded()
|
||||||
NodeComponent nodeComponent = (NodeComponent) instance;
|
.newInstance();
|
||||||
// 重设nodeId
|
NodeComponent nodeComponent = (NodeComponent) instance;
|
||||||
nodeComponent.setNodeId(activeNodeId);
|
// 重设nodeId
|
||||||
return nodeComponent;
|
nodeComponent.setNodeId(activeNodeId);
|
||||||
} catch (Exception e) {
|
return nodeComponent;
|
||||||
throw new LiteFlowException(e);
|
}
|
||||||
}
|
catch (Exception e) {
|
||||||
}).collect(Collectors.toList());
|
throw new LiteFlowException(e);
|
||||||
}
|
}
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
public class AopInvocationHandler implements InvocationHandler {
|
public class AopInvocationHandler implements InvocationHandler {
|
||||||
|
|
||||||
private final Object bean;
|
private final Object bean;
|
||||||
|
|
||||||
private final Class<?> clazz;
|
private final Class<?> clazz;
|
||||||
|
|
||||||
public AopInvocationHandler(Object bean) {
|
public AopInvocationHandler(Object bean) {
|
||||||
this.bean = bean;
|
this.bean = bean;
|
||||||
this.clazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
|
this.clazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
//这里做了2件事情
|
// 这里做了2件事情
|
||||||
//先是从普通的bean里过滤出含有@LiteFlowMethod这个标注的方法
|
// 先是从普通的bean里过滤出含有@LiteFlowMethod这个标注的方法
|
||||||
//然后进行转换成LiteFlowMethodBean对象List,形成<methodName,Method>键值对的对象
|
// 然后进行转换成LiteFlowMethodBean对象List,形成<methodName,Method>键值对的对象
|
||||||
List<LiteFlowMethodBean> liteFlowMethodBeanList = Arrays.stream(ReflectUtil.getMethods(clazz)).filter(m -> {
|
List<LiteFlowMethodBean> liteFlowMethodBeanList = Arrays.stream(ReflectUtil.getMethods(clazz)).filter(m -> {
|
||||||
LiteflowMethod liteFlowMethod = m.getAnnotation(LiteflowMethod.class);
|
LiteflowMethod liteFlowMethod = m.getAnnotation(LiteflowMethod.class);
|
||||||
return ObjectUtil.isNotNull(liteFlowMethod);
|
return ObjectUtil.isNotNull(liteFlowMethod);
|
||||||
}).filter(m -> {
|
}).filter(m -> {
|
||||||
// 过滤不属于当前NodeComponent的方法
|
// 过滤不属于当前NodeComponent的方法
|
||||||
LiteflowMethod liteFlowMethod = m.getAnnotation(LiteflowMethod.class);
|
LiteflowMethod liteFlowMethod = m.getAnnotation(LiteflowMethod.class);
|
||||||
return StrUtil.isEmpty(liteFlowMethod.nodeId())|| Objects.equals(liteFlowMethod.nodeId(),((NodeComponent) proxy).getNodeId());
|
return StrUtil.isEmpty(liteFlowMethod.nodeId())
|
||||||
}).map(m -> {
|
|| Objects.equals(liteFlowMethod.nodeId(), ((NodeComponent) proxy).getNodeId());
|
||||||
LiteflowMethod liteFlowMethod = m.getAnnotation(LiteflowMethod.class);
|
}).map(m -> {
|
||||||
return new LiteFlowMethodBean(liteFlowMethod.value().getMethodName(), m);
|
LiteflowMethod liteFlowMethod = m.getAnnotation(LiteflowMethod.class);
|
||||||
}).collect(Collectors.toList());
|
return new LiteFlowMethodBean(liteFlowMethod.value().getMethodName(), m);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
//获取当前调用方法,是否在被代理的对象方法里面(根据@LiteFlowMethod这个标注去判断)
|
// 获取当前调用方法,是否在被代理的对象方法里面(根据@LiteFlowMethod这个标注去判断)
|
||||||
//如果在里面,则返回那个LiteFlowMethodBean,不在则返回null
|
// 如果在里面,则返回那个LiteFlowMethodBean,不在则返回null
|
||||||
LiteFlowMethodBean liteFlowMethodBean = liteFlowMethodBeanList.stream().filter(
|
LiteFlowMethodBean liteFlowMethodBean = liteFlowMethodBeanList.stream()
|
||||||
liteFlowMethodBean1 -> liteFlowMethodBean1.getMethodName().equals(method.getName())
|
.filter(liteFlowMethodBean1 -> liteFlowMethodBean1.getMethodName().equals(method.getName()))
|
||||||
).findFirst().orElse(null);
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
//如果被代理的对象里有此标注标的方法,则调用此被代理的对象里的方法,如果没有,则调用父类里的方法
|
// 如果被代理的对象里有此标注标的方法,则调用此被代理的对象里的方法,如果没有,则调用父类里的方法
|
||||||
//进行检查,检查被代理的bean里是否有且仅有NodeComponent这个类型的参数
|
// 进行检查,检查被代理的bean里是否有且仅有NodeComponent这个类型的参数
|
||||||
boolean checkFlag = liteFlowMethodBean.getMethod().getParameterTypes().length == 1
|
boolean checkFlag = liteFlowMethodBean.getMethod().getParameterTypes().length == 1
|
||||||
&& Arrays.asList(liteFlowMethodBean.getMethod().getParameterTypes()).contains(NodeComponent.class);
|
&& Arrays.asList(liteFlowMethodBean.getMethod().getParameterTypes()).contains(NodeComponent.class);
|
||||||
if (!checkFlag) {
|
if (!checkFlag) {
|
||||||
String errMsg = StrUtil.format("Method[{}.{}] must have NodeComponent parameter(and only one parameter)", bean.getClass().getName(), liteFlowMethodBean.getMethod().getName());
|
String errMsg = StrUtil.format(
|
||||||
LOG.error(errMsg);
|
"Method[{}.{}] must have NodeComponent parameter(and only one parameter)",
|
||||||
throw new ComponentMethodDefineErrorException(errMsg);
|
bean.getClass().getName(), liteFlowMethodBean.getMethod().getName());
|
||||||
}
|
LOG.error(errMsg);
|
||||||
|
throw new ComponentMethodDefineErrorException(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return liteFlowMethodBean.getMethod().invoke(bean, proxy);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
InvocationTargetException targetEx = (InvocationTargetException) e;
|
||||||
|
throw targetEx.getTargetException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
try{
|
|
||||||
return liteFlowMethodBean.getMethod().invoke(bean, proxy);
|
|
||||||
}catch (Exception e){
|
|
||||||
InvocationTargetException targetEx = (InvocationTargetException)e;
|
|
||||||
throw targetEx.getTargetException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,28 +7,29 @@ import java.lang.reflect.Method;
|
||||||
*/
|
*/
|
||||||
public class LiteFlowMethodBean {
|
public class LiteFlowMethodBean {
|
||||||
|
|
||||||
private String methodName;
|
private String methodName;
|
||||||
|
|
||||||
private Method method;
|
private Method method;
|
||||||
|
|
||||||
public LiteFlowMethodBean(String methodName, Method method) {
|
public LiteFlowMethodBean(String methodName, Method method) {
|
||||||
this.methodName = methodName;
|
this.methodName = methodName;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMethodName() {
|
public String getMethodName() {
|
||||||
return methodName;
|
return methodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMethodName(String methodName) {
|
public void setMethodName(String methodName) {
|
||||||
this.methodName = methodName;
|
this.methodName = methodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method getMethod() {
|
public Method getMethod() {
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMethod(Method method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMethod(Method method) {
|
|
||||||
this.method = method;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,11 @@ package com.yomahub.liteflow.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件步骤类型
|
* 组件步骤类型
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public enum CmpStepTypeEnum {
|
public enum CmpStepTypeEnum {
|
||||||
START,
|
|
||||||
END,
|
START, END, SINGLE;
|
||||||
SINGLE;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,52 +4,51 @@ package com.yomahub.liteflow.enums;
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public enum ConditionTypeEnum {
|
public enum ConditionTypeEnum {
|
||||||
TYPE_THEN("then","then"),
|
|
||||||
TYPE_WHEN("when","when"),
|
|
||||||
TYPE_SWITCH("switch", "switch"),
|
|
||||||
|
|
||||||
TYPE_IF("if", "if"),
|
TYPE_THEN("then", "then"), TYPE_WHEN("when", "when"), TYPE_SWITCH("switch", "switch"),
|
||||||
TYPE_PRE("pre","pre"),
|
|
||||||
TYPE_FINALLY("finally","finally"),
|
|
||||||
|
|
||||||
TYPE_FOR("for", "for"),
|
TYPE_IF("if", "if"), TYPE_PRE("pre", "pre"), TYPE_FINALLY("finally", "finally"),
|
||||||
|
|
||||||
TYPE_WHILE("while", "while"),
|
TYPE_FOR("for", "for"),
|
||||||
|
|
||||||
TYPE_ITERATOR("iterator", "iterator"),
|
TYPE_WHILE("while", "while"),
|
||||||
|
|
||||||
TYPE_CATCH("catch", "catch")
|
TYPE_ITERATOR("iterator", "iterator"),
|
||||||
;
|
|
||||||
private String type;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
ConditionTypeEnum(String type, String name) {
|
TYPE_CATCH("catch", "catch");
|
||||||
this.type = type;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
private String type;
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
private String name;
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
ConditionTypeEnum(String type, String name) {
|
||||||
return name;
|
this.type = type;
|
||||||
}
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public String getType() {
|
||||||
this.name = name;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConditionTypeEnum getEnumByCode(String code) {
|
||||||
|
for (ConditionTypeEnum e : ConditionTypeEnum.values()) {
|
||||||
|
if (e.getType().equals(code)) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static ConditionTypeEnum getEnumByCode(String code) {
|
|
||||||
for (ConditionTypeEnum e : ConditionTypeEnum.values()) {
|
|
||||||
if (e.getType().equals(code)) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,11 @@ package com.yomahub.liteflow.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可执行节点枚举
|
* 可执行节点枚举
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public enum ExecuteTypeEnum {
|
public enum ExecuteTypeEnum {
|
||||||
CHAIN,CONDITION,NODE
|
|
||||||
|
CHAIN, CONDITION, NODE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,35 +5,33 @@ package com.yomahub.liteflow.enums;
|
||||||
* @since 2.5.0
|
* @since 2.5.0
|
||||||
*/
|
*/
|
||||||
public enum FlowParserTypeEnum {
|
public enum FlowParserTypeEnum {
|
||||||
TYPE_XML("xml", "xml"),
|
|
||||||
TYPE_YML("yml", "yml"),
|
|
||||||
TYPE_JSON("json", "json"),
|
|
||||||
TYPE_EL_XML("el_xml", "el_xml"),
|
|
||||||
TYPE_EL_JSON("el_json", "el_json"),
|
|
||||||
TYPE_EL_YML("el_yml", "el_yml")
|
|
||||||
;
|
|
||||||
private String type;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
FlowParserTypeEnum(String type, String name) {
|
TYPE_XML("xml", "xml"), TYPE_YML("yml", "yml"), TYPE_JSON("json", "json"), TYPE_EL_XML("el_xml", "el_xml"),
|
||||||
this.type = type;
|
TYPE_EL_JSON("el_json", "el_json"), TYPE_EL_YML("el_yml", "el_yml");
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
private String type;
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
private String name;
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
FlowParserTypeEnum(String type, String name) {
|
||||||
return name;
|
this.type = type;
|
||||||
}
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public String getType() {
|
||||||
this.name = name;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,17 @@ package com.yomahub.liteflow.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 隐式流程类型
|
* 隐式流程类型
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.8.5
|
* @since 2.8.5
|
||||||
*/
|
*/
|
||||||
public enum InnerChainTypeEnum {
|
public enum InnerChainTypeEnum {
|
||||||
//不是隐式chain
|
|
||||||
NONE,
|
// 不是隐式chain
|
||||||
//在串行环境中执行
|
NONE,
|
||||||
IN_SYNC,
|
// 在串行环境中执行
|
||||||
//在并行环境中执行
|
IN_SYNC,
|
||||||
IN_ASYNC
|
// 在并行环境中执行
|
||||||
|
IN_ASYNC
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +1,49 @@
|
||||||
package com.yomahub.liteflow.enums;
|
package com.yomahub.liteflow.enums;
|
||||||
|
|
||||||
public enum LiteFlowMethodEnum {
|
public enum LiteFlowMethodEnum {
|
||||||
PROCESS("process", true),
|
|
||||||
PROCESS_SWITCH("processSwitch", true),
|
|
||||||
PROCESS_IF("processIf", true),
|
|
||||||
PROCESS_FOR("processFor", true),
|
|
||||||
PROCESS_WHILE("processWhile", true),
|
|
||||||
PROCESS_BREAK("processBreak", true),
|
|
||||||
|
|
||||||
PROCESS_ITERATOR("processIterator", true),
|
PROCESS("process", true), PROCESS_SWITCH("processSwitch", true), PROCESS_IF("processIf", true),
|
||||||
|
PROCESS_FOR("processFor", true), PROCESS_WHILE("processWhile", true), PROCESS_BREAK("processBreak", true),
|
||||||
|
|
||||||
IS_ACCESS("isAccess", false),
|
PROCESS_ITERATOR("processIterator", true),
|
||||||
|
|
||||||
IS_END("isEnd", false),
|
IS_ACCESS("isAccess", false),
|
||||||
IS_CONTINUE_ON_ERROR("isContinueOnError", false),
|
|
||||||
|
|
||||||
GET_NODE_EXECUTOR_CLASS("getNodeExecutorClass", false),
|
IS_END("isEnd", false), IS_CONTINUE_ON_ERROR("isContinueOnError", false),
|
||||||
|
|
||||||
ON_SUCCESS("onSuccess", false),
|
GET_NODE_EXECUTOR_CLASS("getNodeExecutorClass", false),
|
||||||
|
|
||||||
ON_ERROR("onError", false),
|
ON_SUCCESS("onSuccess", false),
|
||||||
|
|
||||||
BEFORE_PROCESS("beforeProcess", false),
|
ON_ERROR("onError", false),
|
||||||
|
|
||||||
AFTER_PROCESS("afterProcess", false);
|
BEFORE_PROCESS("beforeProcess", false),
|
||||||
|
|
||||||
private String methodName;
|
AFTER_PROCESS("afterProcess", false);
|
||||||
|
|
||||||
private boolean isMainMethod;
|
private String methodName;
|
||||||
|
|
||||||
LiteFlowMethodEnum(String methodName, boolean isMainMethod){
|
private boolean isMainMethod;
|
||||||
this.methodName = methodName;
|
|
||||||
this.isMainMethod = isMainMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethodName() {
|
LiteFlowMethodEnum(String methodName, boolean isMainMethod) {
|
||||||
return methodName;
|
this.methodName = methodName;
|
||||||
}
|
this.isMainMethod = isMainMethod;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMethodName(String methodName) {
|
public String getMethodName() {
|
||||||
this.methodName = methodName;
|
return methodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMainMethod() {
|
public void setMethodName(String methodName) {
|
||||||
return isMainMethod;
|
this.methodName = methodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMainMethod() {
|
||||||
|
return isMainMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainMethod(boolean mainMethod) {
|
||||||
|
isMainMethod = mainMethod;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMainMethod(boolean mainMethod) {
|
|
||||||
isMainMethod = mainMethod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ public enum NodeTypeEnum {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(NodeTypeEnum.class);
|
private static final Logger LOG = LoggerFactory.getLogger(NodeTypeEnum.class);
|
||||||
|
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private boolean isScript;
|
private boolean isScript;
|
||||||
|
@ -127,34 +128,35 @@ public enum NodeTypeEnum {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeTypeEnum guessType(Class<?> clazz) {
|
public static NodeTypeEnum guessType(Class<?> clazz) {
|
||||||
if(LiteFlowProxyUtil.isCglibProxyClass(clazz)){
|
if (LiteFlowProxyUtil.isCglibProxyClass(clazz)) {
|
||||||
clazz = LiteFlowProxyUtil.getUserClass(clazz);
|
clazz = LiteFlowProxyUtil.getUserClass(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeTypeEnum nodeType = guessTypeBySuperClazz(clazz);
|
NodeTypeEnum nodeType = guessTypeBySuperClazz(clazz);
|
||||||
if (nodeType == null) {
|
if (nodeType == null) {
|
||||||
//尝试从类声明处进行推断
|
// 尝试从类声明处进行推断
|
||||||
LiteflowCmpDefine liteflowCmpDefine = clazz.getAnnotation(LiteflowCmpDefine.class);
|
LiteflowCmpDefine liteflowCmpDefine = clazz.getAnnotation(LiteflowCmpDefine.class);
|
||||||
if (liteflowCmpDefine != null) {
|
if (liteflowCmpDefine != null) {
|
||||||
//类声明方式中@LiteflowMethod是无需设置nodeId的
|
// 类声明方式中@LiteflowMethod是无需设置nodeId的
|
||||||
//但是如果设置了,那么核心逻辑其实是取类上定义的id的
|
// 但是如果设置了,那么核心逻辑其实是取类上定义的id的
|
||||||
//这种可以运行,但是理解起来不大好理解,所以给出提示,建议不要这么做
|
// 这种可以运行,但是理解起来不大好理解,所以给出提示,建议不要这么做
|
||||||
boolean mixDefined = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
boolean mixDefined = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
||||||
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
||||||
if (liteflowMethod != null) {
|
if (liteflowMethod != null) {
|
||||||
return StrUtil.isNotBlank(liteflowMethod.nodeId());
|
return StrUtil.isNotBlank(liteflowMethod.nodeId());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mixDefined) {
|
if (mixDefined) {
|
||||||
LOG.warn("[[[WARNING!!!]]]The @liteflowMethod in the class[{}] defined by @liteflowCmpDefine should not configure the nodeId again!",
|
LOG.warn(
|
||||||
|
"[[[WARNING!!!]]]The @liteflowMethod in the class[{}] defined by @liteflowCmpDefine should not configure the nodeId again!",
|
||||||
clazz.getName());
|
clazz.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在返回之前,还要对方法级别的@LiteflowMethod进行检查,如果存在方法上的类型与类上的不一致时,给予警告信息
|
||||||
//在返回之前,还要对方法级别的@LiteflowMethod进行检查,如果存在方法上的类型与类上的不一致时,给予警告信息
|
|
||||||
AtomicReference<Method> differenceTypeMethod = new AtomicReference<>();
|
AtomicReference<Method> differenceTypeMethod = new AtomicReference<>();
|
||||||
boolean hasDifferenceNodeType = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
boolean hasDifferenceNodeType = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
||||||
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
||||||
|
@ -162,27 +164,33 @@ public enum NodeTypeEnum {
|
||||||
if (!liteflowMethod.nodeType().equals(liteflowCmpDefine.value())) {
|
if (!liteflowMethod.nodeType().equals(liteflowCmpDefine.value())) {
|
||||||
differenceTypeMethod.set(method);
|
differenceTypeMethod.set(method);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//表示存在不一样的类型
|
// 表示存在不一样的类型
|
||||||
if (hasDifferenceNodeType) {
|
if (hasDifferenceNodeType) {
|
||||||
LOG.warn("[[[WARNING!!!]]]The nodeType in @liteflowCmpDefine declared on the class[{}] does not match the nodeType in @liteflowMethod declared on the method[{}]!",
|
LOG.warn(
|
||||||
|
"[[[WARNING!!!]]]The nodeType in @liteflowCmpDefine declared on the class[{}] does not match the nodeType in @liteflowMethod declared on the method[{}]!",
|
||||||
clazz.getName(), differenceTypeMethod.get().getName());
|
clazz.getName(), differenceTypeMethod.get().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return liteflowCmpDefine.value();
|
return liteflowCmpDefine.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
//再尝试声明式组件这部分的推断
|
// 再尝试声明式组件这部分的推断
|
||||||
LiteflowMethod liteflowMethod = Arrays.stream(clazz.getDeclaredMethods()).map(
|
LiteflowMethod liteflowMethod = Arrays.stream(clazz.getDeclaredMethods())
|
||||||
method -> AnnotationUtil.getAnnotation(method, LiteflowMethod.class)
|
.map(method -> AnnotationUtil.getAnnotation(method, LiteflowMethod.class))
|
||||||
).filter(Objects::nonNull).filter(lfMethod -> lfMethod.value().isMainMethod()).findFirst().orElse(null);
|
.filter(Objects::nonNull)
|
||||||
|
.filter(lfMethod -> lfMethod.value().isMainMethod())
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
if (liteflowMethod != null) {
|
if (liteflowMethod != null) {
|
||||||
nodeType = liteflowMethod.nodeType();
|
nodeType = liteflowMethod.nodeType();
|
||||||
|
@ -190,4 +198,5 @@ public enum NodeTypeEnum {
|
||||||
}
|
}
|
||||||
return nodeType;
|
return nodeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,43 +2,41 @@ package com.yomahub.liteflow.enums;
|
||||||
|
|
||||||
public enum ScriptTypeEnum {
|
public enum ScriptTypeEnum {
|
||||||
|
|
||||||
GROOVY("groovy", "groovy"),
|
GROOVY("groovy", "groovy"), QLEXPRESS("qlexpress", "qlexpress"), JS("javascript", "js"), PYTHON("python", "python"),
|
||||||
QLEXPRESS("qlexpress", "qlexpress"),
|
LUA("luaj", "lua");
|
||||||
JS("javascript", "js"),
|
|
||||||
PYTHON("python", "python"),
|
|
||||||
LUA("luaj", "lua")
|
|
||||||
;
|
|
||||||
private String engineName;
|
|
||||||
|
|
||||||
private String displayName;
|
private String engineName;
|
||||||
|
|
||||||
ScriptTypeEnum(String engineName, String displayName) {
|
private String displayName;
|
||||||
this.engineName = engineName;
|
|
||||||
this.displayName = displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEngineName() {
|
ScriptTypeEnum(String engineName, String displayName) {
|
||||||
return engineName;
|
this.engineName = engineName;
|
||||||
}
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
public void setEngineName(String engineName) {
|
public String getEngineName() {
|
||||||
this.engineName = engineName;
|
return engineName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayName() {
|
public void setEngineName(String engineName) {
|
||||||
return displayName;
|
this.engineName = engineName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisplayName(String displayName) {
|
public String getDisplayName() {
|
||||||
this.displayName = displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScriptTypeEnum getEnumByDisplayName(String displayName) {
|
||||||
|
for (ScriptTypeEnum e : ScriptTypeEnum.values()) {
|
||||||
|
if (e.getDisplayName().equals(displayName)) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static ScriptTypeEnum getEnumByDisplayName(String displayName) {
|
|
||||||
for (ScriptTypeEnum e : ScriptTypeEnum.values()) {
|
|
||||||
if (e.getDisplayName().equals(displayName)) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型错误异常
|
* 类型错误异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class CatchErrorException extends RuntimeException {
|
public class CatchErrorException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public CatchErrorException(String message) {
|
public CatchErrorException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,24 @@ package com.yomahub.liteflow.exception;
|
||||||
*/
|
*/
|
||||||
public class ChainDuplicateException extends RuntimeException {
|
public class ChainDuplicateException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public ChainDuplicateException(String message) {
|
public ChainDuplicateException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 链端异常
|
* 链端异常
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public class ChainEndException extends RuntimeException {
|
public class ChainEndException extends RuntimeException {
|
||||||
|
@ -24,4 +25,5 @@ public class ChainEndException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 链端不存在
|
* 链端不存在
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public class ChainNotFoundException extends RuntimeException {
|
public class ChainNotFoundException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class ChainNotFoundException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程规则主要执行器类
|
* 流程规则主要执行器类
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.5.3
|
* @since 2.5.3
|
||||||
*/
|
*/
|
||||||
|
@ -25,4 +26,5 @@ public class ComponentCannotRegisterException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件方法定义错误异常
|
* 组件方法定义错误异常
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public class ComponentMethodDefineErrorException extends RuntimeException {
|
public class ComponentMethodDefineErrorException extends RuntimeException {
|
||||||
|
@ -24,4 +25,5 @@ public class ComponentMethodDefineErrorException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件不可访问异常
|
* 组件不可访问异常
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
*/
|
*/
|
||||||
public class ComponentNotAccessException extends RuntimeException {
|
public class ComponentNotAccessException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class ComponentNotAccessException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件代理错误异常
|
* 组件代理错误异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class ComponentProxyErrorException extends RuntimeException {
|
public class ComponentProxyErrorException extends RuntimeException {
|
||||||
|
@ -24,4 +25,5 @@ public class ComponentProxyErrorException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置错误异常
|
* 配置错误异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class ConfigErrorException extends RuntimeException {
|
public class ConfigErrorException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class ConfigErrorException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 循环依赖异常
|
* 循环依赖异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class CyclicDependencyException extends RuntimeException {
|
public class CyclicDependencyException extends RuntimeException {
|
||||||
|
@ -24,4 +25,5 @@ public class CyclicDependencyException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,35 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 未找到数据异常
|
* 未找到数据异常
|
||||||
|
*
|
||||||
* @author tangkc
|
* @author tangkc
|
||||||
*/
|
*/
|
||||||
public class DataNotFoundException extends RuntimeException {
|
public class DataNotFoundException extends RuntimeException {
|
||||||
public static final String MSG = "DataNotFoundException";
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
public static final String MSG = "DataNotFoundException";
|
||||||
|
|
||||||
/**
|
private static final long serialVersionUID = 1L;
|
||||||
* 异常信息
|
|
||||||
*/
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
public DataNotFoundException() {
|
/**
|
||||||
this.message = MSG;
|
* 异常信息
|
||||||
}
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
public DataNotFoundException(String message) {
|
public DataNotFoundException() {
|
||||||
this.message = message;
|
this.message = MSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public DataNotFoundException(String message) {
|
||||||
public String getMessage() {
|
this.message = message;
|
||||||
return message;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL 解析异常
|
* EL 解析异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class ELParseException extends RuntimeException {
|
public class ELParseException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public ELParseException(String message) {
|
public ELParseException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
package com.yomahub.liteflow.exception;
|
package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 空条件值异常
|
* 空条件值异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class EmptyConditionValueException extends RuntimeException {
|
public class EmptyConditionValueException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 异常信息 */
|
private static final long serialVersionUID = 1L;
|
||||||
private String message;
|
|
||||||
|
|
||||||
public EmptyConditionValueException(String message) {
|
/** 异常信息 */
|
||||||
this.message = message;
|
private String message;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public EmptyConditionValueException(String message) {
|
||||||
public String getMessage() {
|
this.message = message;
|
||||||
return message;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误支持路径异常
|
* 错误支持路径异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class ErrorSupportPathException extends RuntimeException {
|
public class ErrorSupportPathException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class ErrorSupportPathException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,4 +29,5 @@ public class ExecutableItemNotFoundException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程执行者未初始化
|
* 流程执行者未初始化
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class FlowExecutorNotInitException extends RuntimeException {
|
public class FlowExecutorNotInitException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class FlowExecutorNotInitException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程系统异常
|
* 流程系统异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class FlowSystemException extends RuntimeException {
|
public class FlowSystemException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class FlowSystemException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果目标不能是 Pre 或 Finally 异常
|
* 如果目标不能是 Pre 或 Finally 异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class IfTargetCannotBePreOrFinallyException extends RuntimeException {
|
public class IfTargetCannotBePreOrFinallyException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public IfTargetCannotBePreOrFinallyException(String message) {
|
public IfTargetCannotBePreOrFinallyException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型错误异常
|
* 类型错误异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class IfTypeErrorException extends RuntimeException {
|
public class IfTypeErrorException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public IfTypeErrorException(String message) {
|
public IfTypeErrorException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Json 进程异常
|
* Json 进程异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class JsonProcessException extends RuntimeException {
|
public class JsonProcessException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class JsonProcessException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
package com.yomahub.liteflow.exception;
|
package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LiteFlow架内部逻辑发生错误抛出的异常
|
* LiteFlow架内部逻辑发生错误抛出的异常 (自定义此异常方便开发者在做全局异常处理时分辨异常类型)
|
||||||
* (自定义此异常方便开发者在做全局异常处理时分辨异常类型)
|
*
|
||||||
* @author zendwang
|
* @author zendwang
|
||||||
* @since 2.8.3
|
* @since 2.8.3
|
||||||
*/
|
*/
|
||||||
|
@ -16,7 +16,6 @@ public class LiteFlowException extends RuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建一个异常
|
* 构建一个异常
|
||||||
*
|
|
||||||
* @param message 异常描述信息
|
* @param message 异常描述信息
|
||||||
*/
|
*/
|
||||||
public LiteFlowException(String message) {
|
public LiteFlowException(String message) {
|
||||||
|
@ -35,7 +34,6 @@ public class LiteFlowException extends RuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建一个异常
|
* 构建一个异常
|
||||||
*
|
|
||||||
* @param cause 异常对象
|
* @param cause 异常对象
|
||||||
*/
|
*/
|
||||||
public LiteFlowException(Throwable cause) {
|
public LiteFlowException(Throwable cause) {
|
||||||
|
@ -44,7 +42,6 @@ public class LiteFlowException extends RuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建一个异常
|
* 构建一个异常
|
||||||
*
|
|
||||||
* @param message 异常信息
|
* @param message 异常信息
|
||||||
* @param cause 异常对象
|
* @param cause 异常对象
|
||||||
*/
|
*/
|
||||||
|
@ -69,4 +66,5 @@ public class LiteFlowException extends RuntimeException {
|
||||||
public String getCode() {
|
public String getCode() {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件监听异常
|
* 文件监听异常
|
||||||
|
*
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.10.0
|
* @since 2.10.0
|
||||||
*/
|
*/
|
||||||
|
@ -25,4 +26,5 @@ public class MonitorFileInitErrorException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重复解析器异常
|
* 重复解析器异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class MultipleParsersException extends RuntimeException {
|
public class MultipleParsersException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class MultipleParsersException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无可用插槽异常
|
* 无可用插槽异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NoAvailableSlotException extends RuntimeException {
|
public class NoAvailableSlotException extends RuntimeException {
|
||||||
|
@ -23,4 +24,5 @@ public class NoAvailableSlotException extends RuntimeException {
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 没有节点异常
|
* 没有节点异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NoForNodeException extends RuntimeException {
|
public class NoForNodeException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NoForNodeException(String message) {
|
public NoForNodeException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点不为真异常
|
* 节点不为真异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NoIfTrueNodeException extends RuntimeException {
|
public class NoIfTrueNodeException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NoIfTrueNodeException(String message) {
|
public NoIfTrueNodeException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 没有节点异常
|
* 没有节点异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NoIteratorNodeException extends RuntimeException {
|
public class NoIteratorNodeException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NoIteratorNodeException(String message) {
|
public NoIteratorNodeException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,24 @@ package com.yomahub.liteflow.exception;
|
||||||
*/
|
*/
|
||||||
public class NoSuchContextBeanException extends RuntimeException {
|
public class NoSuchContextBeanException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NoSuchContextBeanException(String message) {
|
public NoSuchContextBeanException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无切换目标节点异常
|
* 无切换目标节点异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NoSwitchTargetNodeException extends RuntimeException {
|
public class NoSwitchTargetNodeException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NoSwitchTargetNodeException(String message) {
|
public NoSwitchTargetNodeException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 没有 While 节点异常
|
* 没有 While 节点异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NoWhileNodeException extends RuntimeException {
|
public class NoWhileNodeException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NoWhileNodeException(String message) {
|
public NoWhileNodeException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
package com.yomahub.liteflow.exception;
|
package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点构建异常
|
* 节点构建异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NodeBuildException extends RuntimeException {
|
public class NodeBuildException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/** 异常信息 */
|
private static final long serialVersionUID = 1L;
|
||||||
private String message;
|
|
||||||
|
|
||||||
public NodeBuildException(String message) {
|
/** 异常信息 */
|
||||||
this.message = message;
|
private String message;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public NodeBuildException(String message) {
|
||||||
public String getMessage() {
|
this.message = message;
|
||||||
return message;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 找不到节点类异常
|
* 找不到节点类异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NodeClassNotFoundException extends RuntimeException {
|
public class NodeClassNotFoundException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NodeClassNotFoundException(String message) {
|
public NodeClassNotFoundException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,29 @@ package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点类型无法猜测异常
|
* 节点类型无法猜测异常
|
||||||
|
*
|
||||||
* @author Yun
|
* @author Yun
|
||||||
*/
|
*/
|
||||||
public class NodeTypeCanNotGuessException extends RuntimeException {
|
public class NodeTypeCanNotGuessException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异常信息
|
* 异常信息
|
||||||
*/
|
*/
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
public NodeTypeCanNotGuessException(String message) {
|
public NodeTypeCanNotGuessException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue