flowableUI源码分析(三)

应用发布

使用的表

  • act_app_deployment 应用部署
  • act_app_appdef 应用定义
  • act_app_deployment_resource 应用zip包中每个资源文件
    /**
     * 应用发布->流程部署
     */
    @PostMapping(value = "/rest/app-definitions/{modelId}/publish", produces = "application/json")
    public AppDefinitionUpdateResultRepresentation publishAppDefinition(@PathVariable("modelId") String modelId,
        @RequestBody AppDefinitionPublishRepresentation publishModel) {
        AppDefinitionUpdateResultRepresentation resultRepresentation = null;
        try {
            resultRepresentation = appDefinitionImportService.publishAppDefinition(modelId, publishModel);
        } catch (Exception ex) {
            resultRepresentation = new AppDefinitionUpdateResultRepresentation();
            resultRepresentation.setError(true);
            resultRepresentation.setErrorDescription(ex.getMessage());
        }
        return resultRepresentation;
    }

1.首先从模型表act_de_model中获取流程定义模型

Model appModel = modelService.getModel(modelId);
    public void publishAppDefinition(String comment, Model appDefinitionModel, String userId) {
        if (appRepositoryService == null) {
            throw new FlowableIllegalStateException("Cannot publish apps from a standalone Modeler application");
        }

        //todo 版本更新+1
        modelService.createNewModelVersion(appDefinitionModel, comment, userId);

        AppDefinition appDefinition = null;
        try {
            // 构建流程定义pojo对象
            appDefinition = resolveAppDefinition(appDefinitionModel);
        } catch (Exception e) {
            LOGGER.error("Error deserializing app {}", appDefinitionModel.getId(), e);
            throw new InternalServerErrorException("Could not deserialize app definition");
        }
        if (appDefinition != null) {
            // 1.创建可部署zip流
            byte[] deployZipArtifact = createDeployableZipArtifact(appDefinitionModel, appDefinition);
            // 2.部署应用,把应用信息和zip存档到act_app_deployment表中
            if (deployZipArtifact != null) {
                deployZipArtifact(deployZipArtifact, appDefinitionModel.getKey(), appDefinitionModel.getName());
            }
        }
    }

部署应用,插入应用名称、应用key、应用zip到表act_app_deployment

5.1 创建可部署zip流
    protected void createDeployableModels(AbstractModel parentModel, Map<String, byte[]> deployableAssets, ConverterContext converterContext) {
        //  使用app_mode主键链表查询act_de_model_relation 和act_de_model关联的model
        List<Model> referencedModels = modelRepository.findByParentModelId(parentModel.getId());
        for (Model childModel : referencedModels) {
            if (Model.MODEL_TYPE_FORM == childModel.getModelType()) {
                converterContext.addFormModel(childModel);

            } else if (Model.MODEL_TYPE_DECISION_TABLE == childModel.getModelType()) {
                converterContext.addDecisionTableModel(childModel);

            } else if (Model.MODEL_TYPE_DECISION_SERVICE == childModel.getModelType()) {
                converterContext.addDecisionServiceModel(childModel);
                List<Model> referencedDecisionTableModels = modelRepository.findByParentModelId(childModel.getId());
                referencedDecisionTableModels.stream()
                    .filter(refModel -> Model.MODEL_TYPE_DECISION_TABLE == refModel.getModelType())
                    .forEach(converterContext::addReferencedDecisionTableModel);

            } else if (Model.MODEL_TYPE_CMMN == childModel.getModelType()) {
                converterContext.addCaseModel(childModel);
                createDeployableModels(childModel, deployableAssets, converterContext);
            
            } else if (Model.MODEL_TYPE_BPMN == childModel.getModelType()) {
                converterContext.addProcessModel(childModel);
                // 创建可部署模型
                createDeployableModels(childModel, deployableAssets, converterContext);
            }
        }

        Map<String, EventModel> eventModelMap = new HashMap<>();
        Map<String, ChannelModel> channelModelMap = new HashMap<>();
        if (parentModel.getModelType() == null || parentModel.getModelType() == AbstractModel.MODEL_TYPE_BPMN) {
            // BPM流程图每个节点转化为对象
            BpmnModel bpmnModel = modelService.getBpmnModel(parentModel, converterContext);
            List<FlowElement> eventRegistryElements = new ArrayList<>();
            Map<String, StartEvent> noneStartEventMap = new HashMap<>();
            // 后置处理流程节点。 处理任务开始节点、发送事件服务任务、子流程
            postProcessFlowElements(eventRegistryElements, noneStartEventMap, bpmnModel);
            
            BpmnEventModelUtil.fillEventModelMap(eventRegistryElements, eventModelMap);
            BpmnEventModelUtil.fillChannelModelMap(eventRegistryElements, channelModelMap);

            // 用户任务节点处理,看processUserTasks方法作用,
            // 当前用户任务节点填写为$INITIATOR流程发起人, 查找起始节点并把userTask设置为初始节点....
            // userTask.setAssignee("${" + startEventMap.get(process.getId()).getInitiator() + "}");
            for (Process process : bpmnModel.getProcesses()) {
                processUserTasks(process.getFlowElements(), process, noneStartEventMap);
            }
            // 生成xml文件
            byte[] modelXML = modelService.getBpmnXML(bpmnModel);
            deployableAssets.put(parentModel.getKey().replaceAll(" ", "") + ".bpmn", modelXML);
            
        } else {
            CmmnModel cmmnModel = modelService.getCmmnModel(parentModel, converterContext);
            List<BaseElement> eventRegistryElements = new ArrayList<>();
            postProcessPlanItemDefinitions(eventRegistryElements, cmmnModel);
            
            CmmnEventModelUtil.fillEventModelMap(eventRegistryElements, eventModelMap);
            CmmnEventModelUtil.fillChannelModelMap(eventRegistryElements, channelModelMap);
            
            byte[] modelXML = modelService.getCmmnXML(cmmnModel);
            deployableAssets.put(parentModel.getKey().replaceAll(" ", "") + ".cmmn", modelXML);
        }
        
        if (eventModelMap.size() > 0) {
            for (EventModel eventModel : eventModelMap.values()) {
                String eventJson = eventJsonConverter.convertToJson(eventModel);
                deployableAssets.put("event-" + eventModel.getKey() + ".event", eventJson.getBytes(StandardCharsets.UTF_8));
            }
            
            if (channelModelMap.size() > 0) {
                for (ChannelModel channelModel : channelModelMap.values()) {
                    String channelJson = channelJsonConverter.convertToJson(channelModel);
                    deployableAssets.put("channel-" + channelModel.getKey() + ".channel", channelJson.getBytes(StandardCharsets.UTF_8));
                }
            }
        }
    }

5.2 部署应用
    /**
     * 应用部署,sql执行。act_app_deployment、 act_app_deployment_resource
     */
    protected void deployZipArtifact(byte[] zipArtifact, String deploymentKey, String deploymentName) {
        // 构建sql
        AppDeploymentBuilder deploymentBuilder = appRepositoryService.createDeployment()
                .key(deploymentKey)
                .name(deploymentName);
        String tenantId = tenantProvider.getTenantId();

        if (tenantId != null) {
            deploymentBuilder.tenantId(tenantId);
        }

        try (InputStream bytesStream = new ByteArrayInputStream(zipArtifact);
             ZipInputStream zipStream = new ZipInputStream(bytesStream)) {
            // zip包中每个资源文件流(表单、bpnm)存档
            deploymentBuilder.addZipInputStream(zipStream);

        } catch (IOException ex) {
            throw new UncheckedIOException("Failed to read bytes", ex);
        }
        //执行sql
        deploymentBuilder.deploy();
    }

5.4 应用资源文件存档

@Override
public AppDeploymentBuilder addZipInputStream(ZipInputStream zipInputStream) {
    try {
        ZipEntry entry = zipInputStream.getNextEntry();
        while (entry != null) {
            if (!entry.isDirectory()) {
                String entryName = entry.getName();
                byte[] bytes = IoUtil.readInputStream(zipInputStream, entryName);
                AppResourceEntity resource = resourceEntityManager.create();
                resource.setName(entryName);
                resource.setBytes(bytes);
                deployment.addResource(resource);
            }
            entry = zipInputStream.getNextEntry();
        }
    } catch (Exception e) {
        throw new FlowableException("problem reading zip input stream", e);
    }
    return this;
}

    @Override
    public AppDeploymentBuilder addZipInputStream(ZipInputStream zipInputStream) {
        try {
            ZipEntry entry = zipInputStream.getNextEntry();
            //循环存储资源
            while (entry != null) {
                if (!entry.isDirectory()) {
                    String entryName = entry.getName();
                    byte[] bytes = IoUtil.readInputStream(zipInputStream, entryName);
                    AppResourceEntity resource = resourceEntityManager.create();
                    resource.setName(entryName);
                    resource.setBytes(bytes);
                    deployment.addResource(resource);
                }
                entry = zipInputStream.getNextEntry();
            }
        } catch (Exception e) {
            throw new FlowableException("problem reading zip input stream", e);
        }
        return this;
    }

6. 发布应用查询

涉及表

  • act_app_appdef
    @GetMapping(value = "/rest/runtime/app-definitions")
    public ResultListDataRepresentation getAppDefinitions() {
        return appDefinitionService.getAppDefinitions();
    }

找到逻辑代码,查询act_app_appdef表中版本最高的应用

    protected List<AppDefinitionRepresentation> getTaskAppList(SecurityScope currentUser) {
        List<AppDefinitionRepresentation> resultList = new ArrayList<>();

        //  查询
        List<AppDefinition> appDefinitions = appRepositoryService.createAppDefinitionQuery().latestVersion().list();
        return resultList;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值