加入格式化代码插件,并提交格式化后的代码

This commit is contained in:
everywhere.z 2023-03-20 11:50:40 +08:00
parent 1f13db48fc
commit ec50e3a0af
1756 changed files with 24781 additions and 22473 deletions

1
.springjavaformatconfig Normal file
View File

@ -0,0 +1 @@
java-baseline=8

View File

@ -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 "";
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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};
} }

View File

@ -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;
}
}
} }

View File

@ -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);
} }

View File

@ -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, ",", "[", "]"));
}
}
} }

View File

@ -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再加上 "^" 的长度 1indexOf 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再加上 "," 的长度 1indexOf 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再加上 "^" 的长度 1indexOf 从 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再加上 "^" 的长度 1indexOf 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再加上 "," 的长度 1indexOf 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再加上 "^" 的长度 1indexOf 从 0 开始,所以还需要加 1
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true);
}
}
}
} catch (Exception ex) {
// ignore
}
return msg;
}
//#endregion
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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);
}
}
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -24,4 +24,5 @@ public class FinallyOperator extends BaseOperator<FinallyCondition> {
} }
return finallyCondition; return finallyCondition;
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -24,4 +24,5 @@ public class IgnoreErrorOperator extends BaseOperator<WhenCondition> {
return condition; return condition;
} }
} }

View File

@ -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;
}
} }

View File

@ -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);
} }
} }
} }
} }

View File

@ -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;
}
} }

View File

@ -30,4 +30,5 @@ public class SwitchOperator extends BaseOperator<SwitchCondition> {
return switchCondition; return switchCondition;
} }
} }

View File

@ -26,4 +26,5 @@ public class TagOperator extends BaseOperator<Node> {
return node; return node;
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
} }

View File

@ -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);
}
}
}
} }

View File

@ -90,4 +90,5 @@ public class ChainPropBean {
this.conditionType = conditionType; this.conditionType = conditionType;
return this; return this;
} }
} }

View File

@ -102,4 +102,5 @@ public class NodePropBean {
this.language = language; this.language = language;
return this; return this;
} }
} }

View File

@ -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";
} }

View File

@ -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";
} }

View File

@ -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 "";
} }

View File

@ -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;
}
} }

View File

@ -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);
}
} }

View File

@ -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;
}
} }

View File

@ -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();
}
} }

View File

@ -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;
} }

View File

@ -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());
} }
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);
}
} }

View File

@ -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);
}
} }

View File

@ -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);
} }

View File

@ -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);
}
} }

View File

@ -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);
}
} }

View File

@ -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);
}
} }

View File

@ -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);
}
} }

View File

@ -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();
}
}
}
} }

View File

@ -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;
}
} }

View File

@ -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;
} }

View File

@ -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;
}
} }

View File

@ -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
} }

View File

@ -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;
}
} }

View File

@ -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
} }

View File

@ -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;
}
} }

View File

@ -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;
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
} }
} }

View File

@ -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