Merge branch 'apps_dev' of https://e.coding.net/yilidev/yilipalkaifa/apps into apps_dev

This commit is contained in:
lihongyu 2022-09-20 14:30:36 +08:00
commit a074976fec
21 changed files with 1084 additions and 0 deletions

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<app xmlns="http://www.actionsoft.com.cn/app">
<name>模型转换</name>
<version>1.0</version>
<buildNo>1</buildNo>
<developer id="776cca9a287c8b4d63b9cad216aa3859" tablePrefix="ACT" url="http://www.actionsoft.com.cn">北京炎黄盈动科技发展有限责任公司</developer>
<categoryVisible>false</categoryVisible>
<description><![CDATA[支持多种模型之间转换]]></description>
<details><![CDATA[]]></details>
<installListener/>
<pluginListener>com.actionsoft.apps.coe.pal.modelconvert.plugin.Plugins</pluginListener>
<startListener/>
<stopListener/>
<upgradeListener/>
<uninstallListener/>
<reloadable>true</reloadable>
<requires/>
<properties/>
<allowStartup>true</allowStartup>
<allowUpgradeByStore>true</allowUpgradeByStore>
<depend versions="6.5" env="">com.actionsoft.apps.coe.pal</depend>
<modelAdministrator/>
<installDate>2022-09-16 14:05:05</installDate>
<icon code="&amp;#xe64f;" color="#009688"/>
<productId/>
</app>

View File

@ -0,0 +1,13 @@
package com.actionsoft.apps.coe.pal.modelconvert;
import com.actionsoft.bpms.server.bind.annotation.Controller;
import com.actionsoft.bpms.server.bind.annotation.Mapping;
@Controller
public class ModelConvertController {
@Mapping("com.actionsoft.apps.coe.pal.test_handle")
public String test(){
return "";
}
}

View File

@ -0,0 +1,58 @@
package com.actionsoft.apps.coe.pal.modelconvert.aslp;
import com.actionsoft.apps.coe.pal.aslp.AslpUtil;
import com.actionsoft.apps.coe.pal.modelconvert.constant.ConvertType;
import com.actionsoft.apps.coe.pal.modelconvert.strategy.ModelConvertContext;
import com.actionsoft.apps.coe.pal.modelconvert.strategy.ModelConvertStrategy;
import com.actionsoft.apps.coe.pal.modelconvert.util.ConvertUtil;
import com.actionsoft.apps.resource.interop.aslp.ASLP;
import com.actionsoft.apps.resource.interop.aslp.Meta;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.UtilString;
import java.util.Map;
public class TransferModelConvert implements ASLP {
@Override
@Meta(parameter = {
"name:'repositoryId',required:true,allowEmpty:false,desc:'被转换的模型ID'",
"name:'sourceMethod',required:true,allowEmpty:false,desc:'被转换类型'",
"name:'targetMethod',required:true,allowEmpty:false,desc:'目标转换类型'",
"name:'sid',required:true,allowEmpty:false,desc:'会话ID'"
})
public ResponseObject call(Map<String, Object> map) {
ResponseObject checkParams = AslpUtil.isParamsEmpty(map);
if (checkParams.isErr()) {
return checkParams;
}
String repositoryId = (String) map.get("repositoryId");
if (UtilString.isEmpty(repositoryId)){
return ResponseObject.newErrResponse("被转换的模型ID不能为空");
}
String sourceMethod = (String) map.get("sourceMethod");
if (UtilString.isEmpty(sourceMethod)){
return ResponseObject.newErrResponse("被转换类型不能为空");
}
String targetMethod = (String) map.get("targetMethod");
if (UtilString.isEmpty(targetMethod)){
return ResponseObject.newErrResponse("目标转换类型不能为空");
}
String sid = (String) map.get("sid");
if (UtilString.isEmpty(sid)){
return ResponseObject.newErrResponse("会话ID不能为空");
}
UserContext uc = UserContext.fromSessionId(sid);
if (uc == null) {
return ResponseObject.newErrResponse("sid参数无效");
}
ConvertType convertType = ConvertUtil.matchConvertType(sourceMethod, targetMethod);
if (convertType == null){
return ResponseObject.newErrResponse("暂不支持"+sourceMethod+"转换"+targetMethod);
}
ModelConvertStrategy convertStrategy = ModelConvertContext.getInstance().modelConvertStrategy(convertType);
String result = convertStrategy.modelConvert(uc,map);
ResponseObject ro = ResponseObject.newOkResponse(result);
return ro;
}
}

View File

@ -0,0 +1,59 @@
package com.actionsoft.apps.coe.pal.modelconvert.aslp;
import com.actionsoft.apps.coe.pal.aslp.AslpUtil;
import com.actionsoft.apps.coe.pal.modelconvert.constant.ConvertType;
import com.actionsoft.apps.coe.pal.modelconvert.strategy.ModelConvertContext;
import com.actionsoft.apps.coe.pal.modelconvert.strategy.ModelConvertStrategy;
import com.actionsoft.apps.coe.pal.modelconvert.util.ConvertUtil;
import com.actionsoft.apps.resource.interop.aslp.ASLP;
import com.actionsoft.apps.resource.interop.aslp.Meta;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.UtilString;
import java.util.List;
import java.util.Map;
public class TransferModelConvertBatch implements ASLP {
@Override
@Meta(parameter = {
"name:'repositoryIdList',required:true,allowEmpty:false,desc:'被转换的模型ID的集合'",
"name:'sourceMethod',required:true,allowEmpty:false,desc:'被转换类型'",
"name:'targetMethod',required:true,allowEmpty:false,desc:'目标转换类型'",
"name:'sid',required:true,allowEmpty:false,desc:'会话ID'"
})
public ResponseObject call(Map<String, Object> map) {
ResponseObject checkParams = AslpUtil.isParamsEmpty(map);
if (checkParams.isErr()) {
return checkParams;
}
List<String> repositoryIdList = (List<String>) map.get("repositoryIdList");
if (AslpUtil.isEmpty(repositoryIdList)){
return ResponseObject.newErrResponse("被转换的模型ID的集合不允许为空");
}
String sourceMethod = (String) map.get("sourceMethod");
if (UtilString.isEmpty(sourceMethod)){
return ResponseObject.newErrResponse("被转换类型不能为空");
}
String targetMethod = (String) map.get("targetMethod");
if (UtilString.isEmpty(targetMethod)){
return ResponseObject.newErrResponse("目标转换类型不能为空");
}
String sid = (String) map.get("sid");
if (UtilString.isEmpty(sid)){
return ResponseObject.newErrResponse("会话ID不能为空");
}
UserContext uc = UserContext.fromSessionId(sid);
if (uc == null) {
return ResponseObject.newErrResponse("sid参数无效");
}
ConvertType convertType = ConvertUtil.matchConvertType(sourceMethod, targetMethod);
if (convertType == null){
return ResponseObject.newErrResponse("暂不支持"+sourceMethod+"转换"+targetMethod);
}
ModelConvertStrategy convertStrategy = ModelConvertContext.getInstance().modelConvertStrategy(convertType);
String result = convertStrategy.modelConvertBatch(uc,map);
ResponseObject ro = ResponseObject.newOkResponse(result);
return ro;
}
}

View File

@ -0,0 +1,45 @@
package com.actionsoft.apps.coe.pal.modelconvert.cache;
import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class RepositoryModelCache {
private RepositoryModelCache(){}
private static RepositoryModelCache repositoryModelCache = new RepositoryModelCache();
// key 历史记录表ID
private static Map<String, List<PALRepositoryModel>> map = new HashMap<>();
public static RepositoryModelCache getInstance(){
return repositoryModelCache;
}
public static void load(String key,PALRepositoryModel repositoryModel){
List<PALRepositoryModel> repositoryModelList = new ArrayList<>();
repositoryModelList.add(repositoryModel);
map.put(key,repositoryModelList);
}
public static void load(String key,List<PALRepositoryModel> repositoryModelList){
map.put(key,repositoryModelList);
}
public static List<PALRepositoryModel> getRepositoryModelList(String key){
return map.get(key);
}
public static void updateRepositoryList(String key,String repositoryId){
List<PALRepositoryModel> repositoryModelList = map.get(key);
repositoryModelList = repositoryModelList.stream().filter(item -> !item.getId().equals(repositoryId)).collect(Collectors.toList());
map.put(key,repositoryModelList);
}
public static void clear(){
map.clear();
}
}

View File

@ -0,0 +1,32 @@
package com.actionsoft.apps.coe.pal.modelconvert.constant;
public enum ConvertType {
EPC_FLOWCHART("process.epc","process.flowchart","EPC转FlowChart"),
EPC_BPMN("process.epc","process.bpmn","EPC转BPMN"),
FLOWCHART_BPMN("process.flowchart","process.bpmn","FlowChart转BPMN");
private ConvertType(String sourceMethod,String targetMethod,String desc){
this.sourceMethod = sourceMethod;
this.targetMethod = targetMethod;
this.desc = desc;
}
private final String sourceMethod;
private final String targetMethod;
private final String desc;
public String getSourceMethod() {
return sourceMethod;
}
public String getTargetMethod() {
return targetMethod;
}
public String getDesc() {
return desc;
}
}

View File

@ -0,0 +1,13 @@
package com.actionsoft.apps.coe.pal.modelconvert.constant;
public class LinkerDefConstant {
// 构造连线时的几个固定参数
public static final double ANGLE_RIGHT = 0;
public static final double ANGLE_DOWN = 1.5707963267948968;
public static final double ANGLE_LEFT = 3.141592653589793;
public static final double ANGLE_UP = 4.71238898038469;
public static final String linker = "{\"fontStyle\":{\"fontFamily\":\"Arial\",\"size\":13,\"color\":\"50,50,50\",\"underline\":false,\"textAlign\":\"center\",\"bold\":false,\"italic\":false},\"points\":[],\"dataAttributes\":[{\"shapeDesc\":\"\",\"name\":\"AWSProperties\",\"id\":\"AWSPropertiesID\",\"type\":\"string\",\"category\":\"default\",\"value\":\"\"}],\"props\":{\"zindex\":0},\"linkerType\":\"broken\",\"lineStyle\":{\"lineStyle\":\"solid\",\"lineColor\":\"50,50,50\",\"beginArrowStyle\":\"none\",\"endArrowStyle\":\"solidArrow\",\"lineWidth\":1},\"name\":\"linker\",\"orderIndex\":0,\"from\":{\"x\":0,\"y\":0,\"angle\":0,\"id\":\"\"},\"id\":\"\",\"text\":\"\",\"to\":{\"x\":0,\"y\":0,\"angle\":0,\"id\":\"\"},\"locked\":false,\"group\":\"\"}";
}

View File

@ -0,0 +1,115 @@
package com.actionsoft.apps.coe.pal.modelconvert.dao;
import com.actionsoft.apps.coe.pal.modelconvert.model.HistoryRecord;
import com.actionsoft.bpms.commons.database.BatchPreparedStatementSetter;
import com.actionsoft.bpms.commons.database.RowMapper;
import com.actionsoft.bpms.commons.mvc.dao.DaoObject;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.bpms.util.UUIDGener;
import com.actionsoft.bpms.util.UtilString;
import com.actionsoft.exception.AWSDataAccessException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HistoryRecordDao extends DaoObject<HistoryRecord> {
@Override
public int insert(HistoryRecord historyRecord) throws AWSDataAccessException {
Map<String, Object> paraMap = new HashMap<String, Object>();
if (UtilString.isEmpty(historyRecord.getId())) {
historyRecord.setId(UUIDGener.getUUID());
}
paraMap.put(HistoryRecord.FIELD_UUID,historyRecord.getId());
paraMap.put(HistoryRecord.FIELD_WSID,historyRecord.getWsId());
paraMap.put(HistoryRecord.FIELD_SOURCE_METHOD,historyRecord.getSourceMethod());
paraMap.put(HistoryRecord.FIELD_TARGET_METHOD,historyRecord.getTargetMethod());
paraMap.put(HistoryRecord.FIELD_OPERATOR,historyRecord.getOperator());
paraMap.put(HistoryRecord.FIELD_OPERATOR_TIME,historyRecord.getOperationTime());
int result = DBSql.update(DBSql.getInsertStatement(entityName(), paraMap), paraMap);
return result;
}
@Override
public int update(HistoryRecord historyRecord) throws AWSDataAccessException {
String sql = "UPDATE " + entityName() + " SET " + HistoryRecord.FIELD_WSID + "=:wsId, " + HistoryRecord.FIELD_SOURCE_METHOD + "=:sourceMethod"
+ HistoryRecord.FIELD_TARGET_METHOD + "=:targetMethod, " + HistoryRecord.FIELD_OPERATOR + "=:operator, "
+ HistoryRecord.FIELD_OPERATOR_TIME + "=:operatorTime WHERE " + HistoryRecord.FIELD_UUID + "=:id";
Map<String, Object> paraMap = new HashMap<String, Object>();
paraMap.put("id",historyRecord.getId());
paraMap.put("wsId",historyRecord.getWsId());
paraMap.put("sourceMethod",historyRecord.getSourceMethod());
paraMap.put("targetMethod",historyRecord.getTargetMethod());
paraMap.put("operator",historyRecord.getOperator());
paraMap.put("operatorTime",historyRecord.getOperationTime());
int r = DBSql.update(sql, paraMap);
return r;
}
@Override
public String entityName() {
return HistoryRecord.DATABASE_ENTITY;
}
@Override
public RowMapper<HistoryRecord> rowMapper() {
return new RowMapper<HistoryRecord>() {
@Override
public HistoryRecord mapRow(ResultSet resultSet, int i) throws SQLException {
HistoryRecord historyRecord = new HistoryRecord();
historyRecord.setId(resultSet.getString(HistoryRecord.FIELD_UUID));
historyRecord.setWsId(resultSet.getString(HistoryRecord.FIELD_WSID));
historyRecord.setSourceMethod(resultSet.getString(HistoryRecord.FIELD_SOURCE_METHOD));
historyRecord.setTargetMethod(resultSet.getString(HistoryRecord.FIELD_TARGET_METHOD));
historyRecord.setOperator(resultSet.getString(HistoryRecord.FIELD_OPERATOR));
historyRecord.setOperationTime(resultSet.getTimestamp(HistoryRecord.FIELD_OPERATOR_TIME));
return historyRecord;
}
};
}
/**
* 批量入库
* @param historyRecordList
* @throws SQLException
*/
public void batchInsert(List<HistoryRecord> historyRecordList) throws SQLException {
Connection conn = DBSql.open();
conn.setAutoCommit(false);
String sql = "INSERT INTO " + entityName() + "(" + HistoryRecord.FIELD_UUID + "," + HistoryRecord.FIELD_WSID + "," + HistoryRecord.FIELD_SOURCE_METHOD
+ "," + HistoryRecord.FIELD_TARGET_METHOD + "," + HistoryRecord.FIELD_OPERATOR + "," + HistoryRecord.FIELD_OPERATOR_TIME + ") VALUES (?, ?, ?, ?, ?, ?)";
try {
int[] result = DBSql.batch(conn, sql, new BatchPreparedStatementSetter() {
@Override
public int getBatchSize() {
return historyRecordList.size();
}
@Override
public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
HistoryRecord historyRecord = historyRecordList.get(i);
preparedStatement.setString(1, historyRecord.getId());
preparedStatement.setString(2, historyRecord.getWsId());
preparedStatement.setString(3, historyRecord.getSourceMethod());
preparedStatement.setString(4, historyRecord.getTargetMethod());
preparedStatement.setString(5, historyRecord.getOperator());
preparedStatement.setTimestamp(6, historyRecord.getOperationTime());
}
});
conn.commit();
} catch (AWSDataAccessException e) {
conn.rollback();
e.printStackTrace();
} catch (SQLException throwables) {
conn.rollback();
throwables.printStackTrace();
} finally {
DBSql.close(conn);
}
}
}

View File

@ -0,0 +1,43 @@
package com.actionsoft.apps.coe.pal.modelconvert.model;
public class EventNode {
private String id;
private double x;
private double y;
private double width;
private double height;
public EventNode(String id,double x, double y, double width, double height) {
this.id = id;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public String getId() {
return id;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public Position getCenterShapePosi(){
double x = this.x + this.width / 2;
double y = this.y + this.height / 2;
return new Position(x,y);
}
}

View File

@ -0,0 +1,71 @@
package com.actionsoft.apps.coe.pal.modelconvert.model;
import com.actionsoft.bpms.commons.mvc.model.ModelBean;
import java.sql.Timestamp;
public class HistoryRecord extends ModelBean {
public static final String DATABASE_ENTITY = "APP_ACT_COE_PAL_MODEL_CONVERT_HISTORY_RECORD";
public static final String FIELD_UUID = "ID";
public static final String FIELD_WSID = "WSID";
public static final String FIELD_SOURCE_METHOD = "SOURCEMETHOD";
public static final String FIELD_TARGET_METHOD = "TARGETMETHOD";
public static final String FIELD_OPERATOR = "OPERATOR";
public static final String FIELD_OPERATOR_TIME = "OPERATORTIME";
private String id;
private String wsId;
private String sourceMethod;
private String targetMethod;
private String operator;
private Timestamp operationTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getWsId() {
return wsId;
}
public void setWsId(String wsId) {
this.wsId = wsId;
}
public String getSourceMethod() {
return sourceMethod;
}
public void setSourceMethod(String sourceMethod) {
this.sourceMethod = sourceMethod;
}
public String getTargetMethod() {
return targetMethod;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public Timestamp getOperationTime() {
return operationTime;
}
public void setOperationTime(Timestamp operationTime) {
this.operationTime = operationTime;
}
}

View File

@ -0,0 +1,34 @@
package com.actionsoft.apps.coe.pal.modelconvert.model;
import com.actionsoft.bpms.commons.mvc.model.ModelBean;
public class HistoryRecordDetail extends ModelBean {
private String id;
private String historyId;
private String repositoryId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getHistoryId() {
return historyId;
}
public void setHistoryId(String historyId) {
this.historyId = historyId;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
}

View File

@ -0,0 +1,39 @@
package com.actionsoft.apps.coe.pal.modelconvert.model;
import java.util.List;
public class LinkerAdapter {
private String id;
private String type;
private Position position; // from/to目标点坐标
private List<Position> points; // 存放折点
private Position linkPoint; // 与事件图形相连的坐标点
public LinkerAdapter(String id, String type, Position position, List<Position> points, Position linkPoint) {
this.id = id;
this.type = type;
this.position = position;
this.points = points;
this.linkPoint = linkPoint;
}
public String getId() {
return id;
}
public String getType() {
return type;
}
public Position getPosition() {
return position;
}
public List<Position> getPoints() {
return points;
}
public Position getLinkPoint() {
return linkPoint;
}
}

View File

@ -0,0 +1,19 @@
package com.actionsoft.apps.coe.pal.modelconvert.model;
public class Position {
private double x;
private double y;
public Position(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}

View File

@ -0,0 +1,41 @@
package com.actionsoft.apps.coe.pal.modelconvert.plugin;
import com.actionsoft.apps.coe.pal.modelconvert.aslp.TransferModelConvert;
import com.actionsoft.apps.coe.pal.modelconvert.aslp.TransferModelConvertBatch;
import com.actionsoft.apps.coe.pal.modelconvert.web.ModelConvertWeb;
import com.actionsoft.apps.listener.PluginListener;
import com.actionsoft.apps.resource.AppContext;
import com.actionsoft.apps.resource.plugin.profile.ASLPPluginProfile;
import com.actionsoft.apps.resource.plugin.profile.AWSPluginProfile;
import com.actionsoft.apps.resource.plugin.profile.AppExtensionProfile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Plugins implements PluginListener {
public Plugins() {
}
@Override
public List<AWSPluginProfile> register(AppContext appContext) {
List<AWSPluginProfile> list = new ArrayList<AWSPluginProfile>();
// PAL应用扩展点
Map<String, Object> params = new HashMap<String, Object>();
params.put("title", "模型转换");
params.put("icon", "");
params.put("desc", "模型转换");
params.put("mainClass", ModelConvertWeb.class.getName());
params.put("deletedClass", "");
list.add(new AppExtensionProfile("PAL流程资产库->流程发布", "aslp://com.actionsoft.apps.coe.pal/registerExtendsApp", params));
// 提供模型转换接口
list.add(new ASLPPluginProfile("modelConvert", TransferModelConvert.class.getName(),"单个文件模型转换接口",null));
list.add(new ASLPPluginProfile("modelConvertBatch", TransferModelConvertBatch.class.getName(),"批量文件模型转换接口",null));
// 提供模型转换进度查询接口
return list;
}
}

View File

@ -0,0 +1,25 @@
package com.actionsoft.apps.coe.pal.modelconvert.strategy;
import com.actionsoft.apps.coe.pal.modelconvert.constant.ConvertType;
import java.util.HashMap;
import java.util.Map;
public class ModelConvertContext {
private ModelConvertContext(){}
private static ModelConvertContext modelConvertContext = new ModelConvertContext();
private static Map<ConvertType,ModelConvertStrategy> map = new HashMap<>(3);
static {
map.put(ConvertType.EPC_FLOWCHART,null);
}
public static ModelConvertContext getInstance(){
return modelConvertContext;
}
public ModelConvertStrategy modelConvertStrategy(ConvertType convertType){
return map.get(convertType);
}
}

View File

@ -0,0 +1,12 @@
package com.actionsoft.apps.coe.pal.modelconvert.strategy;
import com.actionsoft.bpms.server.UserContext;
import java.util.Map;
public interface ModelConvertStrategy {
String modelConvert(UserContext uc,Map<String, Object> param);
String modelConvertBatch(UserContext uc,Map<String,Object> param);
}

View File

@ -0,0 +1,320 @@
package com.actionsoft.apps.coe.pal.modelconvert.strategy.impl;
import com.actionsoft.apps.coe.pal.modelconvert.cache.RepositoryModelCache;
import com.actionsoft.apps.coe.pal.modelconvert.constant.LinkerDefConstant;
import com.actionsoft.apps.coe.pal.modelconvert.model.EventNode;
import com.actionsoft.apps.coe.pal.modelconvert.model.LinkerAdapter;
import com.actionsoft.apps.coe.pal.modelconvert.model.Position;
import com.actionsoft.apps.coe.pal.modelconvert.strategy.ModelConvertStrategy;
import com.actionsoft.apps.coe.pal.modelconvert.util.ConvertUtil;
import com.actionsoft.apps.coe.pal.pal.repository.dao.CoeProcessLevelDaoFacotory;
import com.actionsoft.apps.coe.pal.pal.repository.dao.PALRepository;
import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager;
import com.actionsoft.apps.coe.pal.pal.repository.designer.model.BaseModel;
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.CoeDesignerUtil;
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.ShapeUtil;
import com.actionsoft.apps.coe.pal.pal.repository.model.impl.PALRepositoryModelImpl;
import com.actionsoft.apps.coe.pal.pal.repository.util.CoeProcessLevelUtil;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.UUIDGener;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.sql.Timestamp;
import java.util.*;
/**
* EPC转FlowChart
*/
public class EpcToFlowChart implements ModelConvertStrategy {
/**
* 单条数据转换
* @param param
* @return
*/
@Override
public String modelConvert(UserContext uc,Map<String, Object> param) {
String repositoryId = (String) param.get("repositoryId");
String sourceMethod = (String)param.get("sourceMethod");
String targetMethod = (String)param.get("targetMethod");
PALRepository repository = CoeProcessLevelDaoFacotory.createCoeProcessLevel();
PALRepositoryModelImpl epcRepositoryModel = (PALRepositoryModelImpl)repository.getInstance(repositoryId);
// 1.放入缓存
String historyId = UUIDGener.getUUID();
RepositoryModelCache.load(historyId,epcRepositoryModel);
// 2.新模型文件入库
String newRepositoryId = UUIDGener.getUUID();
String plRid = UUIDGener.getUUID();
String parentId = epcRepositoryModel.getParentId();
String wsId = epcRepositoryModel.getWsId();
String methodCategory = targetMethod.substring(0,targetMethod.indexOf("."));
int orderIndex = repository.getChildrenMaxOrderIndexByPidAndWsId(parentId, wsId) + 1;
Timestamp nowTime = new Timestamp(System.currentTimeMillis());
PALRepositoryModelImpl repositoryModel = CoeProcessLevelUtil.createPALRepositoryModel(newRepositoryId, plRid, wsId, epcRepositoryModel.getName(), "", orderIndex, parentId,
methodCategory, true, 1, newRepositoryId, false, targetMethod, "0", epcRepositoryModel.getLevel(), null, null,
uc.getUID(), uc.getUID(), nowTime, null, null, null, null, null, null, null, null, null,epcRepositoryModel.getSecurityLevel());
repository.insert(repositoryModel);
// 3.调用模型转换的方法
this.handleEPCToFlowChart(uc,repositoryId,newRepositoryId,targetMethod);
// 4.放入缓存同时放入历史记录表中
return null;
}
/**
* 数据批量转换
* @param param
* @return
*/
@Override
public String modelConvertBatch(UserContext uc,Map<String, Object> param) {
// 1.批量放入缓存队列中
// 2.批量新模型文件入库
// 3.调用转换的方法
// 4.存入历史记录表中
return null;
}
private void handleEPCToFlowChart(UserContext _uc,String repositoryId,String newRepositoryId,String targetMethodId){
// 3根据当前EPC的define生成flowChart的define
BaseModel baseModel = CoeDesignerAPIManager.getInstance().getDefinition(repositoryId, 0);
String definition = baseModel.getDefinition();
// 3.1 处理 define 中的 elements其中的事件逻辑与或
JSONObject defineJsonObj = JSONObject.parseObject(definition);
JSONObject page = defineJsonObj.getJSONObject("page");
JSONObject elements = defineJsonObj.getJSONObject("elements");
Map<String, EventNode> eventNodeMap = new HashMap<>();
Map<String,Map<String,List<LinkerAdapter>>> linkerAdapterMap = new HashMap<>();
Set<String> toBeDeletes = new HashSet<>();
// 保存图形y坐标的最大值
double[] maxShapeY = {0.0};
elements.keySet().stream().forEach(key -> {
JSONObject element = elements.getJSONObject(key);
String shapeName = element.getString("name");
JSONObject props = element.getJSONObject("props");
// 找出所有的事件图形
if ("event".equals(shapeName)){
// 将当前ID保存 方便后续处理 记录图形的坐标以及宽高进而算出图形中心点 用作事件线的一个折点
// JSONObject props = element.getJSONObject("props");
EventNode eventNode = new EventNode(key,props.getDoubleValue("x"),props.getDoubleValue("y"),props.getDoubleValue("w"),props.getDoubleValue("h"));
eventNodeMap.put(key,eventNode);
}
if (!"linker".equals(shapeName)) {
element.put("category",targetMethodId);
double y = props.getDoubleValue("y");
if (y > maxShapeY[0]) maxShapeY[0] = y;
}
});
eventNodeMap.keySet().stream().forEach(key -> {
EventNode eventNode = eventNodeMap.get(key);
elements.keySet().stream()
.filter(k -> "linker".equals(elements.getJSONObject(k).getString("name")))
.forEach(k -> {
JSONObject linkerObj = elements.getJSONObject(k);
JSONObject fromObj = linkerObj.getJSONObject("from");
JSONObject toObj = linkerObj.getJSONObject("to");
JSONArray points = linkerObj.getJSONArray("points");
// 找到从事件出去的线 进而找出事件线的to
if (eventNode.getId().equals(fromObj.getString("id"))){
String toId = toObj.getString("id");
if (!linkerAdapterMap.containsKey(key)){
Map<String,List<LinkerAdapter>> map = new HashMap<>();
List<LinkerAdapter> linkerAdapters = new ArrayList<>();
map.put("to",linkerAdapters);
linkerAdapterMap.put(key,map);
}
Map<String,List<LinkerAdapter>> map = linkerAdapterMap.get(key);
if (!map.containsKey("to")){
List<LinkerAdapter> linkerAdapters = new ArrayList<>();
map.put("to",linkerAdapters);
}
List<LinkerAdapter> linkerAdapterList = map.get("to");
Position position = new Position(toObj.getDoubleValue("x"),toObj.getDoubleValue("y"));
List<Position> pointList = new ArrayList<>();
points.stream().forEach(item -> {
JSONObject point = (JSONObject) item;
Position poi = new Position(point.getDoubleValue("x"),point.getDoubleValue("y"));
pointList.add(poi);
});
Position linkPoint = new Position(fromObj.getDoubleValue("x"),fromObj.getDoubleValue("y"));
LinkerAdapter linkerAdapter = new LinkerAdapter(toId,"to",position,pointList,linkPoint);
linkerAdapterList.add(linkerAdapter);
// 记录下待删除的连线的key
toBeDeletes.add(k);
}else if (eventNode.getId().equals(toObj.getString("id"))){ // 找到指向事件的线 进而找出事件线的from
String fromId = fromObj.getString("id");
if (!linkerAdapterMap.containsKey(key)){
Map<String,List<LinkerAdapter>> map = new HashMap<>();
List<LinkerAdapter> linkerAdapters = new ArrayList<>();
map.put("from",linkerAdapters);
linkerAdapterMap.put(key,map);
}
Map<String,List<LinkerAdapter>> map = linkerAdapterMap.get(key);
if (!map.containsKey("from")){
List<LinkerAdapter> linkerAdapters = new ArrayList<>();
map.put("from",linkerAdapters);
}
List<LinkerAdapter> linkerAdapterList = map.get("from");
Position position = new Position(fromObj.getDoubleValue("x"),fromObj.getDoubleValue("y"));
List<Position> pointList = new ArrayList<>();
points.stream().forEach(item -> {
JSONObject point = (JSONObject) item;
Position poi = new Position(point.getDoubleValue("x"),point.getDoubleValue("y"));
pointList.add(poi);
});
Position linkPoint = new Position(toObj.getDoubleValue("x"),toObj.getDoubleValue("y"));
LinkerAdapter linkerAdapter = new LinkerAdapter(fromId,"from",position,pointList,linkPoint);
linkerAdapterList.add(linkerAdapter);
// 记录下待删除的连线的key
toBeDeletes.add(k);
}
});
// 记录下待删除图形的key
toBeDeletes.add(key);
});
// 3.2 根据封装的LinkerAdapter生成新的linker
linkerAdapterMap.keySet().stream().forEach(key -> {
EventNode eventNode = eventNodeMap.get(key);
Position centerShapePosi = eventNode.getCenterShapePosi();
Map<String, List<LinkerAdapter>> listMap = linkerAdapterMap.get(key);
List<LinkerAdapter> fromLinkerList = listMap.get("from");
List<LinkerAdapter> toLinkerList = listMap.get("to");
if (!listMap.containsKey("from") || !listMap.containsKey("to")) { // 只有指出或者接收的线
if (listMap.containsKey("to")){ // 没有指向event的线
toLinkerList.stream().forEach(linkerAdapter -> {
Position toLinkerPosi = linkerAdapter.getPosition();
JSONObject linkerDef = JSONObject.parseObject(LinkerDefConstant.linker);
String linkDefId = UUIDGener.getObjectId();
linkerDef.put("id",linkDefId);
linkerDef.put("text","事件");
linkerDef.put("points", ConvertUtil.getLinkerPoints(linkerAdapter.getPoints()));
JSONObject from = linkerDef.getJSONObject("from");
from.put("x",centerShapePosi.getX());
from.put("y",centerShapePosi.getY());
linkerDef.put("from",from);
JSONObject to = linkerDef.getJSONObject("to");
to.put("x",toLinkerPosi.getX());
to.put("y",toLinkerPosi.getY());
List<Position> positionList = new ArrayList<>();
positionList.add(centerShapePosi);
if (linkerAdapter.getPoints().size() > 0) positionList.addAll(linkerAdapter.getPoints());
positionList.add(toLinkerPosi);
to.put("angle",ConvertUtil.getLinkerAngle(positionList,"to"));
to.put("id",linkerAdapter.getId());
linkerDef.put("to",to);
elements.put(linkDefId,linkerDef);
});
}else if (listMap.containsKey("from")){ // 没有从event出发的线
fromLinkerList.stream().forEach(linkerAdapter -> {
Position fromLinkPosi = linkerAdapter.getPosition();
JSONObject linkerDef = JSONObject.parseObject(LinkerDefConstant.linker);
String linkDefId = UUIDGener.getObjectId();
linkerDef.put("id",linkDefId);
linkerDef.put("text","事件");
linkerDef.put("points",ConvertUtil.getLinkerPoints(linkerAdapter.getPoints()));
JSONObject from = linkerDef.getJSONObject("from");
from.put("x",fromLinkPosi.getX());
from.put("y",fromLinkPosi.getY());
from.put("id",linkerAdapter.getId());
List<Position> positionList = new ArrayList<>();
positionList.add(fromLinkPosi);
if (linkerAdapter.getPoints().size() > 0) positionList.addAll(linkerAdapter.getPoints());
positionList.add(centerShapePosi);
from.put("angle",ConvertUtil.getLinkerAngle(positionList,"from"));
linkerDef.put("from",from);
JSONObject to = linkerDef.getJSONObject("to");
to.put("x",centerShapePosi.getX());
to.put("y",centerShapePosi.getY());
linkerDef.put("to",to);
elements.put(linkDefId,linkerDef);
});
}
}else if (listMap.containsKey("from") && listMap.containsKey("to")){
if (fromLinkerList.size() == 1 && toLinkerList.size() == 1){
LinkerAdapter fromLinkerAdapter = fromLinkerList.get(0);
LinkerAdapter toLinkerAdapter = toLinkerList.get(0);
JSONObject linkerDef = JSONObject.parseObject(LinkerDefConstant.linker);
String linkDefId = UUIDGener.getObjectId();
linkerDef.put("id",linkDefId);
linkerDef.put("text","事件");
List<Position> pointList = new ArrayList<>();
if (fromLinkerAdapter.getPoints().size() > 0) pointList.addAll(fromLinkerAdapter.getPoints());
// 判断当前事件节点是否要作为一个折点
Position fromLinkPoint = fromLinkerAdapter.getLinkPoint();
Position toLinkPoint = toLinkerAdapter.getLinkPoint();
if (fromLinkPoint.getX() != toLinkPoint.getX() && fromLinkPoint.getY() != toLinkPoint.getY()){
pointList.add(centerShapePosi);
}
if (toLinkerAdapter.getPoints().size() > 0) pointList.addAll(toLinkerAdapter.getPoints());
linkerDef.put("points",ConvertUtil.getLinkerPoints(pointList));
List<Position> allPosition = new ArrayList<>();
allPosition.add(fromLinkerAdapter.getPosition());
if (pointList.size() > 0) allPosition.addAll(pointList);
allPosition.add(toLinkerAdapter.getPosition());
JSONObject from = linkerDef.getJSONObject("from");
from.put("id",fromLinkerAdapter.getId());
from.put("x",fromLinkerAdapter.getPosition().getX());
from.put("y",fromLinkerAdapter.getPosition().getY());
from.put("angle",ConvertUtil.getLinkerAngle(allPosition,"from"));
linkerDef.put("from",from);
JSONObject to = linkerDef.getJSONObject("to");
to.put("id",toLinkerAdapter.getId());
to.put("x",toLinkerAdapter.getPosition().getX());
to.put("y",toLinkerAdapter.getPosition().getY());
to.put("angle",ConvertUtil.getLinkerAngle(allPosition,"to"));
linkerDef.put("to",to);
elements.put(linkDefId,linkerDef);
}else if (fromLinkerList.size() > toLinkerList.size()){
}
}
});
// 3.3 增加开始与结束节点
JSONObject startNode = ShapeUtil.getProcessShapeDefinition("process.flowchart", "开始/结束");
String startNodeId = UUIDGener.getObjectId();
startNode.put("id",startNodeId);
JSONObject startNodeProps = startNode.getJSONObject("props");
double padding = page.getDoubleValue("padding");
startNodeProps.put("x",padding + 10);
startNodeProps.put("y",padding + 10);
startNode.put("props",startNodeProps);
startNode.put("text","开始");
elements.put(startNodeId,startNode);
JSONObject endNode = ShapeUtil.getProcessShapeDefinition("process.flowchart", "开始/结束");
String endNodeId = UUIDGener.getObjectId();
endNode.put("id",endNodeId);
JSONObject endNodeProps = endNode.getJSONObject("props");
double pageWidth = page.getDoubleValue("width");
endNodeProps.put("x",(pageWidth / 2) - (endNodeProps.getDoubleValue("w") / 2));
endNodeProps.put("y",maxShapeY[0] + endNodeProps.getDoubleValue("h") + 100);
endNode.put("props",endNodeProps);
endNode.put("text","结束");
elements.put(endNodeId,endNode);
// 4 删除待删除的节点
toBeDeletes.stream().forEach(key -> {
if (elements.containsKey(key)){
elements.remove(key);
}
});
// 5保存define
defineJsonObj.put("elements",elements);
BaseModel model = CoeDesignerAPIManager.getInstance().getDefinition(newRepositoryId, 0);
if (model == null) {
model = CoeDesignerUtil.createModel(newRepositoryId, 0);
}
model.setDefinition(JSONObject.toJSONString(defineJsonObj));
CoeDesignerAPIManager.getInstance().storeDefinition(model);
// 6处理转换后的flowchart模型的文件属性 节点属性 形状显示规则
}
}

View File

@ -0,0 +1,85 @@
package com.actionsoft.apps.coe.pal.modelconvert.util;
import com.actionsoft.apps.coe.pal.modelconvert.constant.ConvertType;
import com.actionsoft.apps.coe.pal.modelconvert.constant.LinkerDefConstant;
import com.actionsoft.apps.coe.pal.modelconvert.model.Position;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class ConvertUtil {
/**
* 匹配转换的类型
* @param sourceMethod
* @param targetMethod
* @return
*/
public static ConvertType matchConvertType(String sourceMethod,String targetMethod){
Optional<ConvertType> optionalConvertType = Arrays.stream(ConvertType.values())
.filter(convertType -> convertType.getSourceMethod().equals(sourceMethod) && convertType.getTargetMethod().equals(targetMethod))
.findFirst();
return optionalConvertType.get();
}
/**
* 获取连线angle
*
* @param positionModels
* @param type
* @return
*/
public static double getLinkerAngle(List<Position> positionModels, String type) {
if (positionModels.size() < 2) {
System.out.println("出错了");
return 0;
} else if (positionModels.size() == 2) {
if (positionModels.get(0).getX() == positionModels.get(1).getX()) {
if ("from".equals(type)) {
return (positionModels.get(0).getY() - positionModels.get(1).getY() > 0) ? LinkerDefConstant.ANGLE_DOWN : LinkerDefConstant.ANGLE_UP;
} else {
return (positionModels.get(0).getY() - positionModels.get(1).getY() > 0) ? LinkerDefConstant.ANGLE_UP : LinkerDefConstant.ANGLE_DOWN;
}
} else {
if ("from".equals(type)) {
return (positionModels.get(0).getX() - positionModels.get(1).getX() > 0) ? LinkerDefConstant.ANGLE_RIGHT : LinkerDefConstant.ANGLE_LEFT;
} else {
return (positionModels.get(0).getX() - positionModels.get(1).getX() > 0) ? LinkerDefConstant.ANGLE_LEFT : LinkerDefConstant.ANGLE_RIGHT;
}
}
} else {
List<Position> list = new ArrayList<>();
if ("from".equals(type)) {
list.add(new Position(positionModels.get(0).getX(), positionModels.get(0).getY()));
list.add(new Position(positionModels.get(1).getX(), positionModels.get(1).getY()));
} else {
list.add(new Position(positionModels.get(positionModels.size() - 2).getX(), positionModels.get(positionModels.size() - 2).getY()));
list.add(new Position(positionModels.get(positionModels.size() - 1).getX(), positionModels.get(positionModels.size() - 1).getY()));
}
return getLinkerAngle(list, type);
}
}
/**
* 获取连线的折点不包括起始端
*
* @param positionModels
* @return
*/
public static Object getLinkerPoints(List<Position> positionModels) {
JSONArray result = new JSONArray();
if (positionModels.size() > 0) {
for (int i = 0; i < positionModels.size(); i++) {
JSONObject obj = new JSONObject();
obj.put("x", positionModels.get(i).getX());
obj.put("y", positionModels.get(i).getY());
result.add(obj);
}
}
return result;
}
}

View File

@ -0,0 +1,28 @@
package com.actionsoft.apps.coe.pal.modelconvert.web;
import com.actionsoft.bpms.commons.mvc.view.ActionWeb;
import com.actionsoft.bpms.server.UserContext;
public class ModelConvertWeb extends ActionWeb {
private UserContext _uc;
public ModelConvertWeb() {
}
public ModelConvertWeb(UserContext userContext) {
super(userContext);
_uc = userContext;
}
public String mainPage(UserContext context, String wsId, String teamId) {
_uc = context;
return page(wsId, teamId);
}
public String page(String wsId,String teamId){
return "";
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<aws-actions>
<cmd-bean name="com.actionsoft.apps.coe.pal.test_handle">
</cmd-bean>
</aws-actions>