package com.highdatas.mdm.service.act.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.highdatas.mdm.pojo.Result; import com.highdatas.mdm.util.WorkflowUtils; import lombok.extern.slf4j.Slf4j; import org.activiti.bpmn.converter.BpmnXMLConverter; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.FlowElement; import org.activiti.editor.constants.ModelDataJsonConstants; import org.activiti.editor.language.json.converter.BpmnJsonConverter; import org.activiti.engine.ActivitiException; import org.activiti.engine.RepositoryService; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.Model; import org.activiti.engine.repository.ModelQuery; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.task.Task; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.ClassUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import java.io.*; import java.util.*; import java.util.zip.ZipInputStream; @Slf4j @Service public class RepositoryServiceImpl extends BaseServiceImpl implements com.highdatas.mdm.service.act.RepositoryService{ private static final String MODEL_NAME = "name"; private static final String MODEL_REVISION = "revision"; private static final String MODEL_DESCRIPTION = "description"; @Autowired RepositoryService service; @Autowired ObjectMapper objectMapper; @Value("${img.url}") String basePath; //download public void getModelXml(HttpServletResponse response, String modelId) throws IOException { Model model = service.getModel(modelId); BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); JsonNode editorNode = new ObjectMapper().readTree(service.getModelEditorSource(model.getId())); BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode); BpmnXMLConverter xmlConverter = new BpmnXMLConverter(); byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel); ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes); IOUtils.copy(in, response.getOutputStream()); String filename = bpmnModel.getMainProcess().getId() + ".bpmn20.xml"; response.setHeader("Content-Disposition", "attachment; filename=" + filename); response.flushBuffer(); } public boolean updateProcessDefStatus(String type, String modelId) { Model model = service.createModelQuery().modelId(modelId).singleResult(); ProcessDefinition processDefinition = service.createProcessDefinitionQuery().deploymentId(model.getDeploymentId()).singleResult(); String processDefinitionId = processDefinition.getId(); try { if ("active".equalsIgnoreCase(type)) { service.activateProcessDefinitionById(processDefinitionId, true, null); } else if ("suspend".equalsIgnoreCase(type)) { service.suspendProcessDefinitionById(processDefinitionId, true, null); } return true; //resultPool.addValue(type +" update success"); } catch (Exception e) { e.printStackTrace(); //resultPool.addValue(type +" update fail"); log.debug(type +" update fail"); return false; } } public boolean deleteDeployModel(String modelId) { try { Model modelData = service.getModel(modelId); String deploymentId = modelData.getDeploymentId(); if (deploymentId != null) { service.deleteDeployment(deploymentId, true); modelData.setDeploymentId(null); modelData.setCategory(null); } return true; //resultPool.addValue("删除部署成功,部署ID=" + deploymentId); } catch (Exception e) { e.printStackTrace(); //resultPool.addValue("删除部署失败,modelId=" + modelId); log.error("根据模型删除部署流程失败:modelId="+modelId, e); return false; } } public boolean deployModel(String modelId) { try { Model modelData = service.getModel(modelId); ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(service.getModelEditorSource(modelData.getId())); byte[] bpmnBytes = null; BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode); bpmnBytes = new BpmnXMLConverter().convertToXML(model); String processName = modelData.getName() + ".bpmn20.xml"; Deployment deployment = service.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes,"UTF-8")).deploy(); modelData.setDeploymentId(deployment.getId()); modelData.setCategory(deployment.getId()); service.saveModel(modelData); return true; // resultPool.addValue("部署成功,部署ID=" + deployment.getId()); } catch (Exception e) { e.printStackTrace(); //resultPool.addValue("部署失败,modelId=" + modelId); log.error("根据模型部署流程失败:modelId="+modelId, e); return false; } } @Override public boolean deleteModel(String modelId) { try { Model model = service.getModel(modelId); String deploymentId = model.getDeploymentId(); if (deploymentId != null) { //TODO // updateDeletedStatus("agreement",deploymentId); // updateDeletedStatus("rebateslit",deploymentId); //updateDeletedStatus("agreement",deploymentId); service.deleteDeployment(deploymentId,true); } service.deleteModel(modelId); return true; //resultPool.addValue("delete model successful"); } catch (Exception e) { e.printStackTrace(); log.debug("delete model failed"); //resultPool.addValue("delete model failed"); return false; } } public String createModel(String modelName, String key, String desp) throws UnsupportedEncodingException { ObjectMapper objectMapper = new ObjectMapper(); ObjectNode editorNode = objectMapper.createObjectNode(); editorNode.put("id", "canvas"); editorNode.put("resourceId", "canvas"); ObjectNode stencilSetNode = objectMapper.createObjectNode(); stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#"); editorNode.set("stencilset", stencilSetNode); Model modelData = service.newModel(); ObjectNode modelObjectNode = objectMapper.createObjectNode(); modelObjectNode.put(MODEL_NAME, modelName); modelObjectNode.put(MODEL_REVISION, 1); modelObjectNode.put(MODEL_DESCRIPTION, desp); modelData.setMetaInfo(modelObjectNode.toString()); modelData.setName(modelName); modelData.setKey(key); service.saveModel(modelData); service.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8")); String id = modelData.getId(); return id; //resultPool.addValue(id); } @SuppressWarnings("unchecked") public void uploadFlow(HttpServletRequest request) { try{ //TODO 修改需 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(factory); servletFileUpload.setHeaderEncoding("UTF-8"); List items = servletFileUpload.parseRequest(request); if (items.isEmpty()) { //resultPool.error("请选择上传文件"); return; } FileItem fileItem = items.get(0); InputStream inputStream = fileItem.getInputStream(); Deployment deployment = null; String extension = FilenameUtils.getExtension(fileItem.getName()); if (extension.equals("zip") || extension.equals("bar")) { ZipInputStream zip = new ZipInputStream(inputStream); deployment = service.createDeployment().addZipInputStream(zip).deploy(); } else { deployment = service.createDeployment().addInputStream(fileItem.getName(), inputStream).deploy(); } ProcessDefinition processDefinition = service.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult(); Model model = change2Model(processDefinition); byte[] modelEditorSource = service.getModelEditorSource(model.getId()); String string = new String(modelEditorSource, "utf-8"); log.debug(string); //TODO dir WorkflowUtils.exportDiagramToFile(service, processDefinition, "model/"+model.getId()+".png"); } catch (Exception e) { e.printStackTrace(); log.error("error on deploy process, because of file input stream", e); } } private Model change2Model(ProcessDefinition processDefinition)throws Exception { InputStream bpmnStream = service.getResourceAsStream(processDefinition.getDeploymentId(),processDefinition.getResourceName()); String processDefinitionKey = processDefinition.getKey(); int modelVersion = 1; XMLInputFactory xif = XMLInputFactory.newInstance(); InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8"); XMLStreamReader xtr = xif.createXMLStreamReader(in); BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr); BpmnJsonConverter converter = new BpmnJsonConverter(); ObjectNode modelNode = converter.convertToJson(bpmnModel); List list = service.createModelQuery().modelKey(processDefinitionKey).orderByModelVersion().desc().list(); if (list.size() != 0) { Model MaxVerModel = list.get(0); Integer version = MaxVerModel.getVersion(); modelVersion = version+1; } Model modelData = service.newModel(); modelData.setKey(processDefinitionKey); modelData.setName(processDefinition.getResourceName()); modelData.setCategory(processDefinition.getDeploymentId()); modelData.setDeploymentId(processDefinition.getDeploymentId()); modelData.setVersion(modelVersion); ObjectNode modelObjectNode = new ObjectMapper().createObjectNode(); modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName()); modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, modelVersion); modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription()); modelData.setMetaInfo(modelObjectNode.toString()); service.saveModel(modelData); service.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8")); return modelData; } public void readProcessResource(String resoucreType, String processDefinitionId,HttpServletResponse response) { String resourceName = ""; ProcessDefinition processDefinition = service.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult(); if ("xml".equalsIgnoreCase(resoucreType)) { } else if ("image".equalsIgnoreCase(resoucreType)) { resourceName = processDefinition.getDiagramResourceName(); } //TODO resp InputStream resourceAsStream = service.getResourceAsStream(processDefinition.getDeploymentId(), resourceName); try { byte[] b = new byte[1024]; int len = -1; while ((len = resourceAsStream.read(b, 0, 1024)) != -1) { response.getOutputStream().write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); error("file can not be read"); } finally { try { resourceAsStream.close(); } catch (IOException e) { e.printStackTrace(); error("steam can not be close"); } } } public Result getProcessList() { List processList = new ArrayList(); ModelQuery modelQuery = service.createModelQuery().orderByModelVersion().desc(); List list = modelQuery.list(); for (Model model: list) { boolean isAdd = true; String deploymentId = model.getDeploymentId(); Deployment deployment = null; ProcessDefinition prodef= null; if (deploymentId != null) { prodef = service.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); deployment = service.createDeploymentQuery().deploymentId(deploymentId).singleResult(); } for (Object[] obj : processList) { Model processModel = (Model) obj[0]; if (model.getKey().equals(processModel.getKey())) { if (model.getVersion() <= processModel.getVersion()) { isAdd = false; continue; } } } if (isAdd) { processList.add(new Object[]{model, deployment,prodef}); } } JSONArray array = new JSONArray(); for (Object[] bean : processList) { JSONObject object = new JSONObject(); Model model = (Model)bean[0]; Deployment deployment = (Deployment)bean[1]; ProcessDefinition prodef = (ProcessDefinition)bean[2]; if (model != null) { object.fluentPut("id", model.getId()); object.fluentPut("category", model.getCategory()); object.fluentPut("version", model.getVersion()); object.fluentPut("createTime", model.getCreateTime()); object.fluentPut("lastUpdateTime", model.getLastUpdateTime()); object.fluentPut("description", model.getMetaInfo()); } //2. if (deployment != null) { object.fluentPut("isDeploymented", "true"); object.fluentPut("deploymentTime", deployment.getDeploymentTime()); }else { object.fluentPut("isDeploymented", "false"); object.fluentPut("deploymentTime", "未部署"); } //3. if (prodef != null) { object.fluentPut("isSuspension", String.valueOf(prodef.isSuspended())); object.fluentPut("name", prodef.getName()); }else { object.fluentPut("isSuspension", "false"); object.fluentPut("name", model.getName()); } array.add(object); } return Result.success(array); //return processList; //resultPool.addValue("processList", processList, new ModelWriter()); } public Model getModel(String modelId) { Model model = service.getModel(modelId); ObjectNode modelNode; if (model != null) { try { if (StringUtils.isNotEmpty(model.getMetaInfo())) { modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo()); } else { modelNode = objectMapper.createObjectNode(); modelNode.put(ModelDataJsonConstants.MODEL_NAME, model.getName()); } modelNode.put(ModelDataJsonConstants.MODEL_ID, model.getId()); ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(new String(service.getModelEditorSource(model.getId()), "utf-8")); modelNode.put("model", editorJsonNode); // resultPool.addValue("name",model.getName()); // resultPool.addValue("description", model.getMetaInfo()); // resultPool.addValue("modelId", modelId); // resultPool.addJson("model", editorJsonNode.toString()); } catch (Exception e) { log.error("Error creating model JSON", e); throw new ActivitiException("Error creating model JSON", e); } } return model; } public boolean saveModel(String modelId, HttpServletRequest request) { HashMap hashMap = new HashMap(); StringBuilder builder = new StringBuilder(); FileOutputStream fileOutputStream2 = null; ByteArrayOutputStream outStream = null; FileOutputStream fileOutputStream = null; try { //1.1 request.setCharacterEncoding("utf-8"); Map parameterMap = request.getParameterMap(); Set keys = parameterMap.keySet(); for (String key : keys) { String[] strings = parameterMap.get(key); for (String string : strings) { builder.append(string); } hashMap.put(key, builder.toString()); builder.setLength(0); } String jsonXmlString = hashMap.get("json_xml"); jsonXmlString = jsonXmlString.replaceAll("\\+\\+", "&&"); hashMap.put("json_xml", jsonXmlString); Model model = service.getModel(modelId); Integer version = model.getVersion(); String key = model.getKey(); //1.2 add new model version++ Model newModel = service.newModel(); ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo()); modelJson.put(MODEL_NAME, hashMap.get("name")); modelJson.put(MODEL_DESCRIPTION, hashMap.get("description")); modelJson.put(MODEL_REVISION, (version + 1)); newModel.setMetaInfo(modelJson.toString()); newModel.setVersion((version + 1)); newModel.setName(hashMap.get("name")); newModel.setKey(key); //1.3 ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(hashMap.get("json_xml").getBytes("utf-8")); BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode); if (bpmnModel.getProcesses().size() == 0) { return false; } byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel); String processName = newModel.getName()+ ".bpmn20.xml"; Deployment deployment = service.createDeployment().name(newModel.getName()).addString(processName,new String(bpmnBytes,"UTF-8")).deploy(); newModel.setDeploymentId(deployment.getId()); newModel.setCategory(deployment.getId()); service.saveModel(newModel); //1.4 service.addModelEditorSource(newModel.getId(), hashMap.get("json_xml").getBytes("utf-8")); InputStream svgStream = new ByteArrayInputStream(hashMap.get("svg_xml").getBytes("utf-8")); TranscoderInput input = new TranscoderInput(svgStream); PNGTranscoder transcoder = new PNGTranscoder(); outStream = new ByteArrayOutputStream(); TranscoderOutput output = new TranscoderOutput(outStream); transcoder.transcode(input, output); final byte[] result = outStream.toByteArray(); service.addModelEditorSourceExtra(newModel.getId(), result); String newModelId = newModel.getId(); //TODO dir 2. String path = basePath + newModelId; File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } //2.1 save model xml to server File file = new File(path,newModelId + ".bpmn20.xml"); if (file.exists()) { file.delete(); } log.info(file.getAbsolutePath()); file.createNewFile(); fileOutputStream2 = new FileOutputStream(file); fileOutputStream2.write(bpmnBytes); //2.2 save model png to server fileOutputStream = new FileOutputStream(new File(path,newModelId + ".png")); InputStream svgs = new ByteArrayInputStream(hashMap.get("svg_xml").getBytes("utf-8")); TranscoderInput inputs = new TranscoderInput(svgs); TranscoderOutput outputs = new TranscoderOutput(fileOutputStream); transcoder.transcode(inputs, outputs); fileOutputStream.flush(); return true; } catch (Exception e) { log.error("Error saving model", e); return false; } finally { try { if (fileOutputStream != null) { fileOutputStream.close(); } if (fileOutputStream2 != null) { fileOutputStream2.close(); } if (outStream != null) { outStream.close(); } } catch (IOException e) { log.error("Error close ioStream ", e); e.printStackTrace(); return false; } } } public void getEditor() { // File file = new File(Configer.getPath_Config(), "stencilset.json"); // String value = null; // // FileInputStream fileInputStream = new FileInputStream(file); // try { // value = IOUtils.toString(fileInputStream, "utf-8"); // } // finally { // fileInputStream.close(); // } //resultPool.setJson(value); } public static void save2File(InputStream input, String filePath,String fileName) { BufferedOutputStream bos = null; FileOutputStream fos = null; File file = null; try { file = new File(filePath,fileName); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); int ch = 0; int read = input.read(); while((ch=read) != -1){ fos.write(ch); } } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } private void updateDeletedStatus(String tableName, String deploymentId) throws Exception { //TODO db // NamedSQL getDeletedWorkflowItem = NamedSQL.getInstance("getDeletedWorkflowItem"); // getDeletedWorkflowItem.setParam("tablename", tableName); // getDeletedWorkflowItem.setParam("deploymentid", deploymentId); // EntitySet entitySet = SQLRunner.getEntitySet(getDeletedWorkflowItem); // // for (Entity entity : entitySet) { // String id = entity.getString("id"); // Entity line = DataHandler.getLine(tableName, id); // String statusCode = line.getString("statuscode"); // // if (statusCode.equalsIgnoreCase("open")) { // continue; // } // line.setString("statuscode", "input"); // line.update(); // // DataHandler.clearFieldbyEntity(line, "keycode"); // } } public String getNextPosition(Task task) { String currentPosition = task.getTaskDefinitionKey(); String processDefinitionId = task.getProcessDefinitionId(); BpmnModel bpmnModel = service.getBpmnModel(processDefinitionId); if (bpmnModel != null) { Collection flowElements = bpmnModel.getMainProcess().getFlowElements(); FlowElement[] flowArray = new FlowElement[flowElements.size()]; flowElements.toArray(flowArray); int pos = -1; //1. goto current position for (int i = 0; i < flowArray.length - 1; i++) { FlowElement flowElement = flowArray[i]; if (flowElement.getId().equalsIgnoreCase(currentPosition)) { pos = i; } } if (pos < 0) { return null; } //2. find parent for (int i = pos + 1; i < flowArray.length -1; i++) { FlowElement element = flowArray[i]; String type = element.getClass().getSimpleName(); if (!"UserTask".equalsIgnoreCase(type)) { continue; } return element.getId(); } } return null; } }