提交 d2f8e327 编写于 作者: misaka's avatar misaka

Merge branch 'dev' of http://demo.ibizlab.cn/ibizr7sfstdtempl/ibiz4jr7 into dev

<#ibiztemplate>
TARGET=PSDATAENTITY
</#ibiztemplate>
<#assign isDynaSys =false>
<#if sys.getAllPSSystemModules()??>
<#list sys.getAllPSSystemModules() as module>
<#if module.getDynaInstMode()?? && (module.getDynaInstMode()?c=='1' || module.getDynaInstMode()?c=='2' )>
<#assign isDynaSys =true>
<#break>
</#if>
</#list>
</#if>
<#comment>引入驼峰配置</#comment>
<#ibizinclude>/SLN/globalfunc.cfg</#ibizinclude>
<#assign hasResetField=false>
......@@ -132,6 +141,12 @@ public class ${item.getCodeName()} extends EntityMP implements Serializable {
<#assign defieldano=defieldano+"dupCheck = DupCheck.ALL" >
</#if>
</#if>
<#if isDynaSys && defield.isMultiFormDEField?? && defield.isMultiFormDEField()?? && defield.isMultiFormDEField()==true>
<#if defieldano?? && defieldano!='' >
<#assign defieldano = defieldano+", ">
</#if>
<#assign defieldano = defieldano+"dynaInstTagField = true">
</#if>
/**
* ${defield.getLogicName()}
*/
......@@ -460,6 +475,13 @@ public class ${item.getCodeName()} extends EntityMongo implements Serializable {
</#if>
</#if>
</#if>
<#if isDynaSys && defield.isMultiFormDEField?? && defield.isMultiFormDEField()?? && defield.isMultiFormDEField()==true>
<#if defieldano?? && defieldano!='' >
<#assign defieldano = defieldano+", ">
</#if>
<#assign defieldano = defieldano+"dynaInstTagField = true">
</#if>
/**
* ${defield.getLogicName()}
*/
......@@ -633,6 +655,12 @@ public class ${item.getCodeName()} extends EntityClient implements Serializable
</#if>
</#if>
</#if>
<#if isDynaSys && defield.isMultiFormDEField?? && defield.isMultiFormDEField()?? && defield.isMultiFormDEField()==true>
<#if defieldano?? && defieldano!='' >
<#assign defieldano = defieldano+", ">
</#if>
<#assign defieldano = defieldano+"dynaInstTagField = true">
</#if>
/**
* ${defield.getLogicName()}
*/
......@@ -843,6 +871,12 @@ public class ${item.getCodeName()} extends EntityBase implements Serializable {
</#if>
</#if>
</#if>
<#if isDynaSys && defield.isMultiFormDEField?? && defield.isMultiFormDEField()?? && defield.isMultiFormDEField()==true>
<#if defieldano?? && defieldano!='' >
<#assign defieldano = defieldano+", ">
</#if>
<#assign defieldano = defieldano+"dynaInstTagField = true">
</#if>
/**
* ${defield.getLogicName()}
*/
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign isDynaSys =false>
<#if sys.getAllPSSystemModules()??>
<#list sys.getAllPSSystemModules() as module>
<#if module.getDynaInstMode()?? && (module.getDynaInstMode()?c=='1' || module.getDynaInstMode()?c=='2' )>
<#assign isDynaSys =true>
<#break>
</#if>
</#list>
</#if>
package ${pub.getPKGCodeName()}.util.annotation;
import ${pub.getPKGCodeName()}.util.enums.DEFieldDefaultValueType;
......@@ -79,5 +88,11 @@ public @interface DEField
* 范围属性
*/
String dupCheckField() default "";
<#if isDynaSys>
/**
* 动态实例标记属性
*/
boolean dynaInstTagField() default false;
</#if>
}
......@@ -14,13 +14,11 @@ TARGET=PSSYSTEM
<#if !isDynaSys>
package ${pub.getPKGCodeName()}.util.aspect;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import ${pub.getPKGCodeName()}.util.domain.DELogic;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import ${pub.getPKGCodeName()}.util.errors.BadRequestAlertException;
import ${pub.getPKGCodeName()}.util.helper.DEFieldCacheMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
......@@ -36,6 +34,8 @@ import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
......@@ -49,7 +49,6 @@ import org.springframework.util.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
......@@ -123,7 +122,7 @@ public class DELogicAspect {
* @param action
*/
private void executeBeforeLogic(EntityBase entity, String action) {
File bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.BEFORE);
Resource bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.BEFORE);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action);
}
......@@ -136,7 +135,7 @@ public class DELogicAspect {
* @param action
*/
private void executeAfterLogic(EntityBase entity, String action) {
File bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.AFTER);
Resource bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.AFTER);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action);
}
......@@ -149,7 +148,7 @@ public class DELogicAspect {
* @param action
*/
private void executeLogic(EntityBase entity, String action) {
File bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.EXEC);
Resource bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.EXEC);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action);
}
......@@ -161,32 +160,37 @@ public class DELogicAspect {
* @param bpmnFile
* @param entity
*/
private void executeLogic(File bpmnFile, Object entity, String action) {
log.debug("开始执行实体处理逻辑[{}:{}:{}:本地模式]", entity.getClass().getSimpleName(), action, bpmnFile.getName());
String bpmnId = DigestUtils.md5DigestAsHex(bpmnFile.getPath().getBytes());
DELogic logic = getDELogic(bpmnFile);
if (logic == null) {
return;
}
if (deLogicMap.containsKey(bpmnId) && logic.getMd5().equals(deLogicMap.get(bpmnId).getMd5())) {
logic = deLogicMap.get(bpmnId);
} else {
reloadLogic(logic);
deLogicMap.put(bpmnId, logic);
}
KieContainer container = logic.getContainer();
KieSession kieSession = container.getKieBase().newKieSession();
Process mainProcess = logic.getProcess();
//主流程参数
fillGlobalParam(kieSession, mainProcess, entity);
//子流程参数
if (!ObjectUtils.isEmpty(logic.getRefLogic())) {
for (DELogic subLogic : logic.getRefLogic()) {
fillGlobalParam(kieSession, subLogic.getProcess(), entity);
private void executeLogic(Resource bpmnFile, Object entity, String action) {
try {
log.debug("开始执行实体处理逻辑[{}:{}:{}:本地模式]", entity.getClass().getSimpleName(), action, bpmnFile.getFilename());
String bpmnId = DigestUtils.md5DigestAsHex(bpmnFile.getURL().getPath().getBytes());
DELogic logic = getDELogic(bpmnFile);
if (logic == null) {
return;
}
if (deLogicMap.containsKey(bpmnId) && logic.getMd5().equals(deLogicMap.get(bpmnId).getMd5())) {
logic = deLogicMap.get(bpmnId);
} else {
reloadLogic(logic);
deLogicMap.put(bpmnId, logic);
}
KieContainer container = logic.getContainer();
KieSession kieSession = container.getKieBase().newKieSession();
Process mainProcess = logic.getProcess();
//主流程参数
fillGlobalParam(kieSession, mainProcess, entity);
//子流程参数
if (!ObjectUtils.isEmpty(logic.getRefLogic())) {
for (DELogic subLogic : logic.getRefLogic()) {
fillGlobalParam(kieSession, subLogic.getProcess(), entity);
}
}
kieSession.startProcess(mainProcess.getId());
log.debug("实体处理逻辑[{}:{}:{}:本地模式]执行结束", entity.getClass().getSimpleName(), action, bpmnFile.getFilename());
} catch (IOException e) {
log.error("实体处理逻辑[{}:{}:{}:本地模式]发生异常", entity.getClass().getSimpleName(), action, bpmnFile.getFilename());
throw new BadRequestAlertException("执行实体处理逻辑发生异常" + e.getMessage(), "DELogicAspect", "executeLogic");
}
kieSession.startProcess(mainProcess.getId());
log.debug("实体处理逻辑[{}:{}:{}:本地模式]执行结束", entity.getClass().getSimpleName(), action, bpmnFile.getName());
}
/**
......@@ -194,11 +198,11 @@ public class DELogicAspect {
*
* @param logic
*/
private void reloadLogic(DELogic logic) {
private void reloadLogic(DELogic logic) throws IOException {
KieServices kieServices = KieServices.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
for (File bpmn : logic.getRefRuleFiles()) {
kieFileSystem.write(ResourceFactory.newFileResource(bpmn));
for (Resource bpmn : logic.getRefRuleFiles()) {
kieFileSystem.write(ResourceFactory.newUrlResource(bpmn.getURL()));
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
Results results = kieBuilder.getResults();
......@@ -253,28 +257,29 @@ public class DELogicAspect {
* @param bpmnFile
* @return
*/
@SneakyThrows
private DELogic getDELogic(File bpmnFile) {
private DELogic getDELogic(Resource bpmnFile) {
DELogic logic = null;
XMLStreamReader reader = null;
InputStream bpmn = null;
try {
if (bpmnFile.exists()) {
XMLInputFactory factory = XMLInputFactory.newInstance();
bpmn = new FileInputStream(bpmnFile);
bpmn = bpmnFile.getInputStream();
reader = factory.createXMLStreamReader(bpmn);
BpmnModel model = bpmnXMLConverter.convertToBpmnModel(reader);
Process mainProcess = model.getMainProcess();
if (mainProcess == null) {
return null;
}
log.debug("正在加载 BPMN:{}", bpmnFile.getURL().getPath());
List<DELogic> refLogics = new ArrayList<>();
List<File> refFiles = new ArrayList<>();
List<Resource> refFiles = new ArrayList<>();
//自己 bpmn drl
refFiles.add(bpmnFile);
File drlFile = getDrl(bpmnFile);
Resource drlFile = getDrl(bpmnFile);
if (drlFile != null && drlFile.exists()) {
refFiles.add(drlFile);
log.debug("正在加载 DRL:{}", drlFile.getURL().getPath());
}
// bpmn drl
if (!ObjectUtils.isEmpty(model.getMainProcess()) && !ObjectUtils.isEmpty(model.getMainProcess().getFlowElementMap())) {
......@@ -282,11 +287,7 @@ public class DELogicAspect {
if (item instanceof CallActivity) {
CallActivity subBpmn = (CallActivity) item;
String bpmnFileName = subBpmn.getName();
log.debug("正在加载 BPMN:{}", bpmnFileName);
File subBpmnFile = getSubBpmn(bpmnFileName);
if (ObjectUtils.isEmpty(subBpmnFile)) {
log.debug("BPMN:{},缺少文件:{} ", bpmnFileName, subBpmnFile);
}
Resource subBpmnFile = getSubBpmn(bpmnFileName);
DELogic refLogic = getDELogic(subBpmnFile);
if (refLogic != null) {
refLogics.add(refLogic);
......@@ -306,7 +307,7 @@ public class DELogicAspect {
logic.setMd5(getMd5(refFiles));
}
} catch (Exception e) {
log.error("执行处理逻辑失败"+e);
log.error("执行处理逻辑失败" + e);
} finally {
try {
if (reader != null) {
......@@ -316,7 +317,7 @@ public class DELogicAspect {
bpmn.close();
}
} catch (Exception e) {
log.error("执行处理逻辑失败"+e);
log.error("执行处理逻辑失败" + e);
}
}
return logic;
......@@ -341,10 +342,10 @@ public class DELogicAspect {
}
}
}
if(!ObjectUtils.isEmpty(service.getSuperclass()) && !service.getSuperclass().getName().equals(Object.class.getName())) {
if (!ObjectUtils.isEmpty(service.getSuperclass()) && !service.getSuperclass().getName().equals(Object.class.getName())) {
return getEntity(service.getSuperclass());
}
log.error("获取实体信息失败,未能在[{}]中找到参数为实体类对象的行为,如create.update等",service.getSimpleName());
log.error("获取实体信息失败,未能在[{}]中找到参数为实体类对象的行为,如create.update等", service.getSimpleName());
return null;
}
......@@ -354,19 +355,19 @@ public class DELogicAspect {
* @param subFiles
* @return
*/
private String getMd5(List<File> subFiles) {
private String getMd5(List<Resource> subFiles) {
try {
StringBuffer buffer = new StringBuffer();
for (File file : subFiles) {
for (Resource file : subFiles) {
InputStream bpmnFile = null;
try {
bpmnFile = new FileInputStream(file);
bpmnFile = file.getInputStream();
if (!ObjectUtils.isEmpty(bpmnFile)) {
String strBpmn = IOUtils.toString(bpmnFile, "UTF-8");
buffer.append(strBpmn);
}
} catch (Exception e) {
log.error("处理逻辑版本检查失败"+e);
log.error("处理逻辑版本检查失败" + e);
} finally {
if (bpmnFile != null) {
bpmnFile.close();
......@@ -379,12 +380,12 @@ public class DELogicAspect {
return null;
}
} catch (Exception e) {
log.error("处理逻辑版本检查失败"+e);
log.error("处理逻辑版本检查失败" + e);
return null;
}
}
/**
/**
* 本地逻辑
*
* @param entity
......@@ -392,10 +393,8 @@ public class DELogicAspect {
* @param logicExecMode
* @return
*/
private File getLocalModel(String entity, String action, LogicExecMode logicExecMode) {
String logicName = String.format("%s.bpmn", logicExecMode.text);
String filePath = File.separator + "rules" + File.separator + entity + File.separator + action.toLowerCase() + File.separator + logicName;
return getBpmnFile(filePath);
private Resource getLocalModel(String entity, String action, LogicExecMode logicExecMode) {
return new ClassPathResource("rules" + File.separator + entity + File.separator + action.toLowerCase() + File.separator + logicExecMode.text + ".bpmn");
}
/**
......@@ -404,9 +403,8 @@ public class DELogicAspect {
* @param logicName
* @return
*/
private File getSubBpmn(String logicName) {
String filePath = String.format("/rules/%s", logicName);
return getBpmnFile(filePath);
private Resource getSubBpmn(String logicName) {
return new ClassPathResource(String.format("rules/%s", logicName));
}
/**
......@@ -415,41 +413,10 @@ public class DELogicAspect {
* @param bpmn
* @return
*/
private File getDrl(File bpmn) {
if (bpmn.getPath().endsWith("RuleFlow.bpmn")) {
return getBpmnFile(bpmn.getPath().replace("RuleFlow.bpmn", "Rule.drl"));
} else {
return getBpmnFile(bpmn.getPath().replace(".bpmn", ".drl"));
}
}
/**
* 获取 bpmn
*
* @param filePath
* @return
*/
private File getBpmnFile(String filePath) {
InputStream in = null;
File bpmn = null;
try {
in = this.getClass().getResourceAsStream(filePath.replace("\\", "/"));
if (in != null) {
bpmn = new File(filePath);
FileUtils.copyToFile(in, bpmn);
}
} catch (IOException e) {
log.error("执行处理逻辑失败,无法获取逻辑文件"+e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bpmn;
private Resource getDrl(Resource bpmn) {
String filePath = ((ClassPathResource) bpmn).getPath();
filePath = filePath.endsWith("RuleFlow.bpmn") ? filePath.replace("RuleFlow.bpmn", "Rule.drl") : filePath.replace(".bpmn", ".drl");
return new ClassPathResource(filePath);
}
/**
......@@ -460,8 +427,8 @@ public class DELogicAspect {
* @param action
* @return
*/
private boolean isValid(File bpmn, Object entity, Object action) {
String logicId = String.format("%s%s%s", entity.getClass().getSimpleName(), action, bpmn.getName()).toLowerCase();
private boolean isValid(Resource bpmn, Object entity, Object action) {
String logicId = String.format("%s%s%s", entity.getClass().getSimpleName(), action, bpmn.getFilename()).toLowerCase();
if (validLogic.containsKey(logicId)) {
return true;
} else {
......@@ -500,14 +467,15 @@ public class DELogicAspect {
<#comment>加载远程逻辑(动态系统)</#comment>
package ${pub.getPKGCodeName()}.util.aspect;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import ${pub.getPKGCodeName()}.util.annotation.DEField;
import ${pub.getPKGCodeName()}.util.domain.DELogic;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import ${pub.getPKGCodeName()}.util.errors.BadRequestAlertException;
import ${pub.getPKGCodeName()}.util.helper.DEFieldCacheMap;
import org.apache.commons.io.FileUtils;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
......@@ -526,6 +494,9 @@ import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
......@@ -539,9 +510,10 @@ import org.springframework.util.StringUtils;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
......@@ -569,7 +541,7 @@ public class DELogicAspect {
@Value("${r'$'}{ibiz.systemid:${sys.getCodeName()}}")
private String systemId;
@Value("${r'$'}{ibiz.dynainstid:${sys.getCodeName()?lower_case}}")
private String dynamicId;
private String defaultDynaInstId;
<#assign hasDynamicModule =false>
<#assign hasLocalModule = false>
......@@ -628,10 +600,10 @@ public class DELogicAspect {
EntityBase entity = null;
if ("remove".equalsIgnoreCase(action) || "get".equalsIgnoreCase(action)) {
entity = getEntity(service.getClass());
if(!ObjectUtils.isEmpty(entity)) {
if (!ObjectUtils.isEmpty(entity)) {
String id = DEFieldCacheMap.getDEKeyField(entity.getClass());
if(StringUtils.isEmpty(id)) {
log.debug("无法获取实体主键属性[{}]",entity.getClass().getSimpleName());
if (StringUtils.isEmpty(id)) {
log.debug("无法获取实体主键属性[{}]", entity.getClass().getSimpleName());
return point.proceed();
}
entity.set(id, arg);
......@@ -639,11 +611,19 @@ public class DELogicAspect {
} else if (arg instanceof EntityBase) {
entity = (EntityBase) arg;
}
String dynaInstId = null;
if (isDyna) {
dynaInstId = getDynaInstId(entity);
dynaInstId = ObjectUtils.isEmpty(dynaInstId) ? defaultDynaInstId : dynaInstId;
}
if (entity != null) {
executeBeforeLogic(entity, action, isDyna);
executeBeforeLogic(entity, action, isDyna, dynaInstId);
Object result = point.proceed();
executeLogic(entity, action, isDyna);
executeAfterLogic(entity, action, isDyna);
if("get".equalsIgnoreCase(action) && result instanceof EntityBase){
entity = (EntityBase) result;
}
executeLogic(entity, action, isDyna, dynaInstId);
executeAfterLogic(entity, action, isDyna, dynaInstId);
return result;
}
return point.proceed();
......@@ -655,18 +635,18 @@ public class DELogicAspect {
* @param entity
* @param action
*/
private void executeBeforeLogic(EntityBase entity, String action, boolean isDyna) {
File bpmnFile;
private void executeBeforeLogic(EntityBase entity, String action, boolean isDyna, String instanceId) {
Resource bpmnFile;
if (isDyna) {
bpmnFile = getRemoteModel(getDEModule(entity), entity.getClass().getSimpleName(), action, LogicExecMode.BEFORE);
bpmnFile = getRemoteModel(getDEModule(entity), entity.getClass().getSimpleName(), action, LogicExecMode.BEFORE, instanceId);
if (bpmnFile != null && bpmnFile.exists()) {
executeLogic(bpmnFile, entity, action, LogicMode.REMOTE);
executeLogic(bpmnFile, entity, action, instanceId);
return;
}
}
bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.BEFORE);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action, LogicMode.LOCAL);
executeLogic(bpmnFile, entity, action, instanceId);
}
}
......@@ -676,18 +656,18 @@ public class DELogicAspect {
* @param entity
* @param action
*/
private void executeAfterLogic(EntityBase entity, String action, boolean isDyna) {
File bpmnFile;
private void executeAfterLogic(EntityBase entity, String action, boolean isDyna, String instanceId) {
Resource bpmnFile;
if (isDyna) {
bpmnFile = getRemoteModel(getDEModule(entity), entity.getClass().getSimpleName(), action, LogicExecMode.AFTER);
bpmnFile = getRemoteModel(getDEModule(entity), entity.getClass().getSimpleName(), action, LogicExecMode.AFTER, instanceId);
if (bpmnFile != null && bpmnFile.exists()) {
executeLogic(bpmnFile, entity, action, LogicMode.REMOTE);
executeLogic(bpmnFile, entity, action, instanceId);
return;
}
}
bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.AFTER);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action, LogicMode.LOCAL);
executeLogic(bpmnFile, entity, action, instanceId);
}
}
......@@ -697,18 +677,18 @@ public class DELogicAspect {
* @param entity
* @param action
*/
private void executeLogic(EntityBase entity, String action, boolean isDyna) {
File bpmnFile;
private void executeLogic(EntityBase entity, String action, boolean isDyna, String instanceId) {
Resource bpmnFile;
if (isDyna) {
bpmnFile = getRemoteModel(getDEModule(entity), entity.getClass().getSimpleName(), action, LogicExecMode.EXEC);
bpmnFile = getRemoteModel(getDEModule(entity), entity.getClass().getSimpleName(), action, LogicExecMode.EXEC, instanceId);
if (bpmnFile != null && bpmnFile.exists()) {
executeLogic(bpmnFile, entity, action, LogicMode.REMOTE);
executeLogic(bpmnFile, entity, action, instanceId);
return;
}
}
bpmnFile = getLocalModel(entity.getClass().getSimpleName(), action, LogicExecMode.EXEC);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action, LogicMode.LOCAL);
executeLogic(bpmnFile, entity, action, instanceId);
}
}
......@@ -718,32 +698,38 @@ public class DELogicAspect {
* @param bpmnFile
* @param entity
*/
private void executeLogic(File bpmnFile, Object entity, String action, LogicMode logicMode) {
log.debug("开始执行实体处理逻辑[{}:{}:{}:{}]", entity.getClass().getSimpleName(), action, bpmnFile.getName(), logicMode.text);
String bpmnId = DigestUtils.md5DigestAsHex(bpmnFile.getPath().getBytes());
DELogic logic = getDELogic(bpmnFile, entity, logicMode);
if (logic == null) {
return;
}
if (deLogicMap.containsKey(bpmnId) && logic.getMd5().equals(deLogicMap.get(bpmnId).getMd5())) {
logic = deLogicMap.get(bpmnId);
} else {
reloadLogic(logic);
deLogicMap.put(bpmnId, logic);
}
KieContainer container = logic.getContainer();
KieSession kieSession = container.getKieBase().newKieSession();
Process mainProcess = logic.getProcess();
//主流程参数
fillGlobalParam(kieSession, mainProcess, entity);
//子流程参数
if (!ObjectUtils.isEmpty(logic.getRefLogic())) {
for (DELogic subLogic : logic.getRefLogic()) {
fillGlobalParam(kieSession, subLogic.getProcess(), entity);
private void executeLogic(Resource bpmnFile, Object entity, String action, String instanceId) {
String logicMode = bpmnFile instanceof FileSystemResource ? String.format("远程模式:%s", instanceId) : "本地模式";
try {
log.debug("开始执行实体处理逻辑[{}:{}:{}:{}]", entity.getClass().getSimpleName(), action, bpmnFile.getFilename(), logicMode);
String bpmnId = DigestUtils.md5DigestAsHex(bpmnFile.getURL().getPath().getBytes());
DELogic logic = getDELogic(bpmnFile, entity, instanceId);
if (logic == null) {
return;
}
if (deLogicMap.containsKey(bpmnId) && logic.getMd5().equals(deLogicMap.get(bpmnId).getMd5())) {
logic = deLogicMap.get(bpmnId);
} else {
reloadLogic(logic);
deLogicMap.put(bpmnId, logic);
}
KieContainer container = logic.getContainer();
KieSession kieSession = container.getKieBase().newKieSession();
Process mainProcess = logic.getProcess();
//主流程参数
fillGlobalParam(kieSession, mainProcess, entity);
//子流程参数
if (!ObjectUtils.isEmpty(logic.getRefLogic())) {
for (DELogic subLogic : logic.getRefLogic()) {
fillGlobalParam(kieSession, subLogic.getProcess(), entity);
}
}
kieSession.startProcess(mainProcess.getId());
log.debug("实体处理逻辑[{}:{}:{}:{}]执行结束", entity.getClass().getSimpleName(), action, bpmnFile.getFilename(), logicMode);
} catch (IOException e) {
log.error("执行实体处理逻辑[{}:{}:{}:{}]发生异常" + e.getMessage(), entity.getClass().getSimpleName(), action, bpmnFile.getFilename(), logicMode);
throw new BadRequestAlertException("执行实体处理逻辑发生异常"+ e.getMessage(), "DELogicAspect", "executeLogic");
}
kieSession.startProcess(mainProcess.getId());
log.debug("实体处理逻辑[{}:{}:{}:{}]执行结束", entity.getClass().getSimpleName(), action, bpmnFile.getName(), logicMode.text);
}
/**
......@@ -751,11 +737,11 @@ public class DELogicAspect {
*
* @param logic
*/
private void reloadLogic(DELogic logic) {
private void reloadLogic(DELogic logic) throws IOException {
KieServices kieServices = KieServices.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
for (File bpmn : logic.getRefRuleFiles()) {
kieFileSystem.write(ResourceFactory.newFileResource(bpmn));
for (Resource bpmn : logic.getRefRuleFiles()) {
kieFileSystem.write(ResourceFactory.newUrlResource(bpmn.getURL()));
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
Results results = kieBuilder.getResults();
......@@ -811,28 +797,29 @@ public class DELogicAspect {
* @param entity
* @return
*/
@SneakyThrows
private DELogic getDELogic(File bpmnFile, Object entity, LogicMode logicMode) {
private DELogic getDELogic(Resource bpmnFile, Object entity, String instanceId) {
DELogic logic = null;
XMLStreamReader reader = null;
InputStream bpmn = null;
try {
if (bpmnFile.exists()) {
XMLInputFactory factory = XMLInputFactory.newInstance();
bpmn = new FileInputStream(bpmnFile);
bpmn = bpmnFile.getInputStream();
reader = factory.createXMLStreamReader(bpmn);
BpmnModel model = bpmnXMLConverter.convertToBpmnModel(reader);
Process mainProcess = model.getMainProcess();
if (mainProcess == null) {
return null;
}
log.debug("正在加载 BPMN:{}", bpmnFile.getURL().getPath());
List<DELogic> refLogics = new ArrayList<>();
List<File> refFiles = new ArrayList<>();
List<Resource> refFiles = new ArrayList<>();
//自己 bpmn drl
refFiles.add(bpmnFile);
File drlFile = getDrl(bpmnFile);
Resource drlFile = getDrl(bpmnFile);
if (drlFile != null && drlFile.exists()) {
refFiles.add(drlFile);
log.debug("正在加载 DRL:{}", drlFile.getURL().getPath());
}
// bpmn drl
if (!ObjectUtils.isEmpty(model.getMainProcess()) && !ObjectUtils.isEmpty(model.getMainProcess().getFlowElementMap())) {
......@@ -840,12 +827,8 @@ public class DELogicAspect {
if (item instanceof CallActivity) {
CallActivity subBpmn = (CallActivity) item;
String bpmnFileName = subBpmn.getName();
log.debug("正在加载 BPMN:{}", bpmnFileName);
File subBpmnFile = getSubBpmn(getDEModule(entity), entity.getClass().getSimpleName(), bpmnFileName, logicMode);
if (ObjectUtils.isEmpty(subBpmnFile)) {
log.debug("BPMN:{},缺少文件:{} ", bpmnFileName, subBpmnFile);
}
DELogic refLogic = getDELogic(subBpmnFile, entity, logicMode);
Resource subBpmnFile = getSubBpmn(getDEModule(entity), entity.getClass().getSimpleName(), bpmnFileName, bpmnFile, instanceId);
DELogic refLogic = getDELogic(subBpmnFile, entity, instanceId);
if (refLogic != null) {
refLogics.add(refLogic);
if (!ObjectUtils.isEmpty(refLogic.getRefRuleFiles())) {
......@@ -864,7 +847,7 @@ public class DELogicAspect {
logic.setMd5(getMd5(refFiles));
}
} catch (Exception e) {
log.error("执行处理逻辑失败"+e);
log.error("执行处理逻辑失败" + e);
} finally {
try {
if (reader != null) {
......@@ -874,7 +857,7 @@ public class DELogicAspect {
bpmn.close();
}
} catch (Exception e) {
log.error("执行处理逻辑失败"+e);
log.error("执行处理逻辑失败" + e);
}
}
return logic;
......@@ -899,10 +882,10 @@ public class DELogicAspect {
}
}
}
if(!ObjectUtils.isEmpty(service.getSuperclass()) && !service.getSuperclass().getName().equals(Object.class.getName())) {
if (!ObjectUtils.isEmpty(service.getSuperclass()) && !service.getSuperclass().getName().equals(Object.class.getName())) {
return getEntity(service.getSuperclass());
}
log.error("获取实体信息失败,未能在[{}]中找到参数为实体类对象的行为,如create.update等",service.getSimpleName());
log.error("获取实体信息失败,未能在[{}]中找到参数为实体类对象的行为,如create.update等", service.getSimpleName());
return null;
}
......@@ -912,19 +895,19 @@ public class DELogicAspect {
* @param subFiles
* @return
*/
private String getMd5(List<File> subFiles) {
private String getMd5(List<Resource> subFiles) {
try {
StringBuffer buffer = new StringBuffer();
for (File file : subFiles) {
for (Resource file : subFiles) {
InputStream bpmnFile = null;
try {
bpmnFile = new FileInputStream(file);
bpmnFile = file.getInputStream();
if (!ObjectUtils.isEmpty(bpmnFile)) {
String strBpmn = IOUtils.toString(bpmnFile, "UTF-8");
buffer.append(strBpmn);
}
} catch (Exception e) {
log.error("处理逻辑版本检查失败"+e);
log.error("处理逻辑版本检查失败" + e);
} finally {
if (bpmnFile != null) {
bpmnFile.close();
......@@ -937,7 +920,7 @@ public class DELogicAspect {
return null;
}
} catch (Exception e) {
log.error("处理逻辑版本检查失败"+e);
log.error("处理逻辑版本检查失败" + e);
return null;
}
}
......@@ -950,10 +933,8 @@ public class DELogicAspect {
* @param logicExecMode
* @return
*/
private File getLocalModel(String entity, String action, LogicExecMode logicExecMode) {
String logicName = String.format("%s.bpmn", logicExecMode.text);
String filePath = File.separator + "rules" + File.separator + entity + File.separator + action.toLowerCase() + File.separator + logicName;
return getBpmnFile(filePath);
private Resource getLocalModel(String entity, String action, LogicExecMode logicExecMode) {
return new ClassPathResource("rules" + File.separator + entity + File.separator + action.toLowerCase() + File.separator + logicExecMode.text + ".bpmn");
}
/**
......@@ -965,9 +946,9 @@ public class DELogicAspect {
* @param logicExecMode
* @return
*/
private File getRemoteModel(String module, String entity, String action, LogicExecMode logicExecMode) {
String logicName = String.format("psdeaction.json.%s.bpmn", logicExecMode.text);
return getBpmnFile(dynamicPath + File.separator + (systemId + File.separator + dynamicId + File.separator + "psmodules" + File.separator + module + File.separator + "psdataentities" + File.separator + entity + File.separator + "psdeactions" + File.separator + action + File.separator + logicName).toLowerCase());
private Resource getRemoteModel(String module, String entity, String action, LogicExecMode logicExecMode, String instanceId) {
return new FileSystemResource(dynamicPath + File.separator + (systemId + File.separator + instanceId + File.separator + "psmodules" + File.separator + module +
File.separator + "psdataentities" + File.separator + entity + File.separator + "psdeactions" + File.separator + action + ".json." + logicExecMode.text + ".bpmn").toLowerCase());
}
/**
......@@ -978,14 +959,13 @@ public class DELogicAspect {
* @param logicName
* @return
*/
private File getSubBpmn(String module, String entity, String logicName, LogicMode logicMode) {
if (LogicMode.REMOTE.equals(logicMode)) {
return getBpmnFile(dynamicPath + File.separator + (systemId + File.separator + dynamicId + File.separator + "psmodules" + File.separator + module + File.separator + "psdataentities" + File.separator + entity + File.separator + "psdelogics" + File.separator + logicName + File.separator + "psdelogic.json.bpmn").toLowerCase());
private Resource getSubBpmn(String module, String entity, String logicName, Resource parentBpmn, String instanceId) {
if (parentBpmn instanceof FileSystemResource) {
return new FileSystemResource(dynamicPath + File.separator + (systemId + File.separator + instanceId + File.separator + "psmodules" + File.separator + module
+ File.separator + "psdataentities" + File.separator + entity + File.separator + "psdelogics" + File.separator + logicName).toLowerCase());
} else {
String filePath = String.format("/rules/%s", logicName);
return getBpmnFile(filePath);
return new ClassPathResource(String.format("rules/%s", logicName));
}
}
/**
......@@ -994,41 +974,11 @@ public class DELogicAspect {
* @param bpmn
* @return
*/
private File getDrl(File bpmn) {
if (bpmn.getPath().endsWith("RuleFlow.bpmn")) {
return getBpmnFile(bpmn.getPath().replace("RuleFlow.bpmn", "Rule.drl"));
} else {
return getBpmnFile(bpmn.getPath().replace(".bpmn", ".drl"));
}
}
/**
* 获取 bpmn
*
* @param filePath
* @return
*/
private File getBpmnFile(String filePath) {
InputStream in = null;
File bpmn = null;
try {
in = this.getClass().getResourceAsStream(filePath.replace("\\", "/"));
if (in != null) {
bpmn = new File(filePath);
FileUtils.copyToFile(in, bpmn);
}
} catch (IOException e) {
log.error("执行处理逻辑失败,无法获取逻辑文件"+e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bpmn;
@SneakyThrows
private Resource getDrl(Resource bpmn) {
String filePath = bpmn instanceof FileSystemResource ? bpmn.getURL().getPath() : ((ClassPathResource) bpmn).getPath();
filePath = filePath.endsWith("RuleFlow.bpmn") ? filePath.replace("RuleFlow.bpmn", "Rule.drl") : filePath.replace(".bpmn", ".drl");
return bpmn instanceof FileSystemResource ? new FileSystemResource(filePath) : new ClassPathResource(filePath);
}
/**
......@@ -1051,6 +1001,79 @@ public class DELogicAspect {
return strModule;
}
/**
* 获取动态实例标识
*
* @param entity
* @return
*/
private String getDynaInstId(EntityBase entity) {
String instId = null;
Object instTag = null;
Map<String, DEField> deFields = DEFieldCacheMap.getDEFields(entity.getClass());
for (Map.Entry<String, DEField> deField : deFields.entrySet()) {
if (deField.getValue().dynaInstTagField()) {
instTag = entity.get(deField.getKey());
}
}
if (ObjectUtils.isEmpty(instTag)) {
return null;
}
JSONObject defaultDynaInst = getDefaultDynaInst();
if (!ObjectUtils.isEmpty(defaultDynaInst)) {
JSONArray instances = defaultDynaInst.getJSONArray("getPSDynaInsts");
if (!ObjectUtils.isEmpty(instances)) {
for (Object item : instances) {
JSONObject dynaInst = (JSONObject) item;
if (dynaInst != null) {
if (!ObjectUtils.isEmpty(dynaInst.get("instTag"))) {
return String.valueOf(dynaInst.get("instTag"));
}
}
}
}
}
return instId;
}
/**
* 获取系统标识
*
* @return 返回一组SystemJSON数据
*/
private JSONObject getDefaultDynaInst() {
JSONObject dynaInst = null;
InputStream in = null;
byte[] bytes = null;
try {
Resource file = new FileSystemResource(dynamicPath + File.separator + systemId + File.separator + defaultDynaInstId + File.separator + "PSSYSTEM.json");
if (!file.exists()) {
throw new BadRequestAlertException(String.format("无法获取动态实例[%s]", file.getURL().getPath()), "DELogicAspect", "getDefaultDynaInst");
}
in = file.getInputStream();
bytes = new byte[in.available()];
in.read(bytes);
} catch (Exception e) {
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
}
}
if (bytes != null) {
String strSystem = new String(bytes, StandardCharsets.UTF_8);
if (!StringUtils.isEmpty(strSystem)) {
dynaInst = JSONObject.parseObject(strSystem);
}
}
if (ObjectUtils.isEmpty(dynaInst)) {
throw new BadRequestAlertException("无法获取动态实例", "DELogicAspect", "getDefaultDynaInst");
}
return dynaInst;
}
/**
* 执行动态行为
*
......@@ -1088,8 +1111,8 @@ public class DELogicAspect {
* @param action
* @return
*/
private boolean isValid(File bpmn, Object entity, Object action) {
String logicId = String.format("%s%s%s", entity.getClass().getSimpleName(), action, bpmn.getName()).toLowerCase();
private boolean isValid(Resource bpmn, Object entity, Object action) {
String logicId = String.format("%s%s%s", entity.getClass().getSimpleName(), action, bpmn.getFilename()).toLowerCase();
if (validLogic.containsKey(logicId)) {
return true;
} else {
......@@ -1141,25 +1164,6 @@ public class DELogicAspect {
<#comment>输出枚举类</#comment>
<#macro enum>
public enum LogicMode {
/**
* 本地
*/
LOCAL("0", "本地模式"),
/**
* 远程
*/
REMOTE("1", "远程模式");
LogicMode(String value, String text) {
this.value = value;
this.text = text;
}
private String value;
private String text;
}
public enum LogicExecMode {
/**
* 前附加逻辑
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign isDynaSys =false>
<#if sys.getAllPSSystemModules()??>
<#list sys.getAllPSSystemModules() as module>
<#if module.getDynaInstMode()?? && (module.getDynaInstMode()?c=='1' || module.getDynaInstMode()?c=='2' )>
<#assign isDynaSys =true>
<#break>
</#if>
</#list>
</#if>
package ${pub.getPKGCodeName()}.util.domain;
import lombok.Data;
import org.flowable.bpmn.model.Process;
import org.springframework.core.io.Resource;
import org.kie.api.runtime.KieContainer;
import java.io.File;
import java.io.Serializable;
......@@ -17,6 +27,6 @@ public class DELogic implements Serializable {
Process process;
KieContainer container;
List<DELogic> refLogic;
List<File> refRuleFiles;
List<Resource> refRuleFiles;
String md5;
}
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册