com.yomahub.liteflow.spi.spring.SpringDeclComponentParser Maven / Gradle / Ivy
The newest version!
package com.yomahub.liteflow.spi.spring;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.annotation.*;
import com.yomahub.liteflow.annotation.util.AnnoUtil;
import com.yomahub.liteflow.core.proxy.DeclWarpBean;
import com.yomahub.liteflow.core.proxy.MethodWrapBean;
import com.yomahub.liteflow.core.proxy.ParameterWrapBean;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.exception.CmpDefinitionException;
import com.yomahub.liteflow.spi.DeclComponentParser;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Spring环境声明式组件解析器实现
* @author Bryan.Zhang
* @since 2.11.4
*/
public class SpringDeclComponentParser implements DeclComponentParser {
@Override
public List parseDeclBean(Class> clazz) {
return parseDeclBean(clazz, null, null);
}
@Override
public List parseDeclBean(Class> clazz, final String nodeId, final String nodeName) {
Map> definitionMap = Arrays.stream(clazz.getMethods()).filter(
method -> AnnotationUtil.getAnnotation(method, LiteflowMethod.class) != null
).map(method -> {
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
LiteflowRetry liteflowRetry = AnnotationUtil.getAnnotation(method, LiteflowRetry.class);
String currNodeId = null;
String currNodeName = null;
if (nodeId == null){
if (StrUtil.isBlank(liteflowMethod.nodeId())){
LiteflowComponent liteflowComponent = AnnoUtil.getAnnotation(clazz, LiteflowComponent.class);
Component component = AnnoUtil.getAnnotation(clazz, Component.class);
if(liteflowComponent != null){
currNodeId = liteflowComponent.value();
currNodeName = liteflowComponent.name();
}else if(component != null){
currNodeId = component.value();
}else{
currNodeName = StrUtil.EMPTY;
currNodeId = StrUtil.EMPTY;
}
}else{
currNodeId = liteflowMethod.nodeId();
currNodeName = liteflowMethod.nodeName();
}
}else{
currNodeId = nodeId;
currNodeName = nodeName;
}
NodeTypeEnum nodeType;
LiteflowCmpDefine liteflowCmpDefine = AnnotationUtil.getAnnotation(method.getDeclaringClass(), LiteflowCmpDefine.class);
if (liteflowCmpDefine != null){
nodeType = liteflowCmpDefine.value();
}else{
nodeType = liteflowMethod.nodeType();
}
Parameter[] parameters = method.getParameters();
List parameterList = IntStream.range(0, parameters.length).boxed().map(index -> {
Parameter parameter = parameters[index];
return new ParameterWrapBean(parameter.getType(), AnnotationUtil.getAnnotation(parameter, LiteflowFact.class), index);
}).collect(Collectors.toList());
return new DeclInfo(currNodeId, currNodeName, nodeType, method.getDeclaringClass(), new MethodWrapBean(method, liteflowMethod, liteflowRetry, parameterList));
}).filter(declInfo -> StrUtil.isNotBlank(declInfo.getNodeId())).collect(Collectors.groupingBy(DeclInfo::getNodeId));
return definitionMap.entrySet().stream().map(entry -> {
String key = entry.getKey();
List declInfos = entry.getValue();
DeclWarpBean declWarpBean = new DeclWarpBean();
declWarpBean.setNodeId(key);
DeclInfo processMethodDeclInfo = declInfos.stream().filter(declInfo -> declInfo.getMethodWrapBean().getLiteflowMethod().value().isMainMethod()).findFirst().orElse(null);
if (processMethodDeclInfo == null){
throw new CmpDefinitionException(StrUtil.format("Component [{}] does not define the process method", key));
}
declWarpBean.setNodeName(processMethodDeclInfo.getNodeName());
declWarpBean.setRawClazz(processMethodDeclInfo.getRawClazz());
declWarpBean.setNodeType(processMethodDeclInfo.getNodeType());
RootBeanDefinition rawClassDefinition = new RootBeanDefinition(clazz);
rawClassDefinition.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON);
declWarpBean.setRawBean(rawClassDefinition);
declWarpBean.setMethodWrapBeanList(declInfos.stream().map(DeclInfo::getMethodWrapBean).collect(Collectors.toList()));
return declWarpBean;
}).collect(Collectors.toList());
}
@Override
public int priority() {
return 1;
}
public static class DeclInfo{
private String nodeId;
private String nodeName;
private NodeTypeEnum nodeType;
private Class> rawClazz;
private MethodWrapBean methodWrapBean;
public DeclInfo(String nodeId, String nodeName, NodeTypeEnum nodeType, Class> rawClazz, MethodWrapBean methodWrapBean) {
this.nodeId = nodeId;
this.nodeName = nodeName;
this.nodeType = nodeType;
this.rawClazz = rawClazz;
this.methodWrapBean = methodWrapBean;
}
public String getNodeId() {
return nodeId;
}
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public Class> getRawClazz() {
return rawClazz;
}
public void setRawClazz(Class> rawClazz) {
this.rawClazz = rawClazz;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public MethodWrapBean getMethodWrapBean() {
return methodWrapBean;
}
public void setMethodWrapBean(MethodWrapBean methodWrapBean) {
this.methodWrapBean = methodWrapBean;
}
public NodeTypeEnum getNodeType() {
return nodeType;
}
public void setNodeType(NodeTypeEnum nodeType) {
this.nodeType = nodeType;
}
}
}