Flowable源码注释(二十五)BPMN部署器(下)

本文详细解析了Flowable中的BpmnDeployer类,主要关注流程定义的版本管理和事件调度。通过getPreviousDerivedFromVersionsOfProcessDefinitions方法获取新旧流程定义的映射,setProcessDefinitionVersionsAndIds方法设置版本和标识,以及事件调度。此外,还涉及到持久化、定时器和事件更新,以及流程定义的初始化事件。这些操作确保了流程定义在不同版本间的正确管理和流程实例的有序执行。

Flowable源码地址:https://github.com/flowable/flowable-engine

Flowable-6.7.2 源码注释地址:https://github.com/solojin/flowable-6.7.2-annotated

BpmnDeployer BPMN部署器(下)

public class BpmnDeployer implements EngineDeployer {
    
    ...
        
	/**
     * 构造一个映射从新的流程定义实体到根据主键和租户从版本派生的上一个流程定义实体。
     * 如果不存在以前的版本,则不会创建映射条目。
     */
    protected Map<ProcessDefinitionEntity, ProcessDefinitionEntity> getPreviousDerivedFromVersionsOfProcessDefinitions(
            ParsedDeployment parsedDeployment) {

        Map<ProcessDefinitionEntity, ProcessDefinitionEntity> result = new LinkedHashMap<>();

        for (ProcessDefinitionEntity newDefinition : parsedDeployment.getAllProcessDefinitions()) {
            ProcessDefinitionEntity existingDefinition = bpmnDeploymentHelper.getMostRecentDerivedVersionOfProcessDefinition(newDefinition);

            if (existingDefinition != null) {
                result.put(newDefinition, existingDefinition);
            }
        }

        return result;
    }

    /**
     * 设置每个流程定义实体的版本和标识符。
     * 如果映射包含流程定义的旧版本,则该版本将设置为该旧实体的版本加一;否则设置为1.
     * 还调度实体创建 ENTITY_CREATED 事件。
     */
    protected void setProcessDefinitionVersionsAndIds(ParsedDeployment parsedDeployment,
            Map<ProcessDefinitionEntity, ProcessDefinitionEntity> mapNewToOldProcessDefinitions) {
        
        CommandContext commandContext = Context.getCommandContext();

        for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
            int version = 1;

            ProcessDefinitionEntity latest = mapNewToOldProcessDefinitions.get(processDefinition);
            if (latest != null) {
                version = latest.getVersion() + 1;
            }

            processDefinition.setVersion(version);
            processDefinition.setId(getIdForNewProcessDefinition(processDefinition));
            Process process = parsedDeployment.getProcessModelForProcessDefinition(processDefinition);
            FlowElement initialElement = process.getInitialFlowElement();
            if (initialElement instanceof StartEvent) {
                StartEvent startEvent = (StartEvent) initialElement;
                if (startEvent.getFormKey() != null) {
                    processDefinition.setHasStartFormKey(true);
                }
            }

            cachingAndArtifactsManager.updateProcessDefinitionCache(parsedDeployment);

            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
            FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
            if (eventDispatcher != null && eventDispatcher.isEnabled()) {
                eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_CREATED, processDefinition),
                        processEngineConfiguration.getEngineCfgKey());
            }
        }
    }
    
    protected void setDerivedProcessDefinitionVersionsAndIds(ParsedDeployment parsedDeployment, 
            Map<ProcessDefinitionEntity, ProcessDefinitionEntity> mapNewToOldProcessDefinitions, Map<String, Object> deploymentSettings) {
        
        CommandContext commandContext = Context.getCommandContext();
        
        for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
            int derivedVersion = 1;
            
            ProcessDefinitionEntity latest = mapNewToOldProcessDefinitions.get(processDefinition);
            if (latest != null) {
                derivedVersion = latest.getDerivedVersion() + 1;
            }
            
            processDefinition.setVersion(0);
            processDefinition.setDerivedVersion(derivedVersion);
            if (usePrefixId) {
                processDefinition.setId(processDefinition.getIdPrefix() + idGenerator.getNextId());
            } else {
                processDefinition.setId(idGenerator.getNextId());
            }
            
            processDefinition.setDerivedFrom((String) deploymentSettings.get(DeploymentSettings.DERIVED_PROCESS_DEFINITION_ID));
            processDefinition.setDerivedFromRoot((String) deploymentSettings.get(DeploymentSettings.DERIVED_PROCESS_DEFINITION_ROOT_ID));

            Process process = parsedDeployment.getProcessModelForProcessDefinition(processDefinition);
            FlowElement initialElement = process.getInitialFlowElement();
            if (initialElement instanceof StartEvent) {
                StartEvent startEvent = (StartEvent) initialElement;
                if (startEvent.getFormKey() != null) {
                    processDefinition.setHasStartFormKey(true);
                }
            }
            
            cachingAndArtifactsManager.updateProcessDefinitionCache(parsedDeployment);

            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
            FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
            if (eventDispatcher != null && eventDispatcher.isEnabled()) {
                eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_CREATED, processDefinition),
                        processEngineConfiguration.getEngineCfgKey());
            }
        }
    }

    /**
     * 保存每个进程定义。假设部署是新的,之前从未保存过定义,并且它们的所有值都已正确设置.
     */
    protected void persistProcessDefinitionsAndAuthorizations(ParsedDeployment parsedDeployment) {
        CommandContext commandContext = Context.getCommandContext();
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        ProcessDefinitionEntityManager processDefinitionManager = processEngineConfiguration.getProcessDefinitionEntityManager();

        for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
            processDefinitionManager.insert(processDefinition, false);
            bpmnDeploymentHelper.addAuthorizationsForNewProcessDefinition(parsedDeployment.getProcessModelForProcessDefinition(processDefinition), processDefinition);
        }
    }

    protected void updateTimersAndEvents(ParsedDeployment parsedDeployment,
            Map<ProcessDefinitionEntity, ProcessDefinitionEntity> mapNewToOldProcessDefinitions) {

        for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
            bpmnDeploymentHelper.updateTimersAndEvents(processDefinition,
                    mapNewToOldProcessDefinitions.get(processDefinition),
                    parsedDeployment);
        }
    }

    protected void dispatchProcessDefinitionEntityInitializedEvent(ParsedDeployment parsedDeployment) {
        CommandContext commandContext = Context.getCommandContext();
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        for (ProcessDefinitionEntity processDefinitionEntity : parsedDeployment.getAllProcessDefinitions()) {
            FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
            if (eventDispatcher != null && eventDispatcher.isEnabled()) {
                eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_INITIALIZED, processDefinitionEntity),
                        processEngineConfiguration.getEngineCfgKey());
            }
        }
    }

    /**
     * 返回用于新进程定义的ID;
     * 子类可以覆盖此项以提供自己的标识方案。
     * 整个引擎中的流程定义ID必须是唯一的!
     */
    protected String getIdForNewProcessDefinition(ProcessDefinitionEntity processDefinition) {
        String prefixId = "";
        if (usePrefixId) {
            prefixId = processDefinition.getIdPrefix();
        } 
        
        String nextId = idGenerator.getNextId();

        String result = prefixId + processDefinition.getKey() + ":" + processDefinition.getVersion() + ":" + nextId; // ACT-505
        // ACT-115: id的最大长度为64个字符
        if (result.length() > 64) {
            // 由于长度超出了长进程定义键
            result = prefixId + nextId;
        }

        return result;
    }

    /**
     * 加载每个进程定义的持久化版本,并将内存版本上的值设置为一致。
     */
    protected void makeProcessDefinitionsConsistentWithPersistedVersions(ParsedDeployment parsedDeployment) {
        for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
            ProcessDefinitionEntity persistedProcessDefinition = bpmnDeploymentHelper.getPersistedInstanceOfProcessDefinition(processDefinition);

            if (persistedProcessDefinition != null) {
                processDefinition.setId(persistedProcessDefinition.getId());
                processDefinition.setVersion(persistedProcessDefinition.getVersion());
                processDefinition.setSuspensionState(persistedProcessDefinition.getSuspensionState());
                processDefinition.setHasStartFormKey(persistedProcessDefinition.hasStartFormKey());
                processDefinition.setGraphicalNotationDefined(persistedProcessDefinition.isGraphicalNotationDefined());
            }
        }
    }

    protected void createLocalizationValues(String processDefinitionId, Process process) {
        if (process == null) {
            return;
        }

        CommandContext commandContext = Context.getCommandContext();
        DynamicBpmnService dynamicBpmnService = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDynamicBpmnService();
        ObjectNode infoNode = dynamicBpmnService.getProcessDefinitionInfo(processDefinitionId);

        boolean localizationValuesChanged = false;
        List<ExtensionElement> localizationElements = process.getExtensionElements().get("localization");
        if (localizationElements != null) {
            for (ExtensionElement localizationElement : localizationElements) {
                if (BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX.equals(localizationElement.getNamespacePrefix()) ||
                        BpmnXMLConstants.ACTIVITI_EXTENSIONS_PREFIX.equals(localizationElement.getNamespacePrefix())) {

                    String locale = localizationElement.getAttributeValue(null, "locale");
                    String name = localizationElement.getAttributeValue(null, "name");
                    String documentation = null;
                    List<ExtensionElement> documentationElements = localizationElement.getChildElements().get("documentation");
                    if (documentationElements != null) {
                        for (ExtensionElement documentationElement : documentationElements) {
                            documentation = StringUtils.trimToNull(documentationElement.getElementText());
                            break;
                        }
                    }

                    String processId = process.getId();
                    if (!isEqualToCurrentLocalizationValue(locale, processId, "name", name, infoNode)) {
                        dynamicBpmnService.changeLocalizationName(locale, processId, name, infoNode);
                        localizationValuesChanged = true;
                    }

                    if (documentation != null && !isEqualToCurrentLocalizationValue(locale, processId, "description", documentation, infoNode)) {
                        dynamicBpmnService.changeLocalizationDescription(locale, processId, documentation, infoNode);
                        localizationValuesChanged = true;
                    }
                }
            }
        }

        boolean isFlowElementLocalizationChanged = localizeFlowElements(process.getFlowElements(), infoNode);
        boolean isDataObjectLocalizationChanged = localizeDataObjectElements(process.getDataObjects(), infoNode);
        if (isFlowElementLocalizationChanged || isDataObjectLocalizationChanged) {
            localizationValuesChanged = true;
        }

        if (localizationValuesChanged) {
            dynamicBpmnService.saveProcessDefinitionInfo(processDefinitionId, infoNode);
        }
    }

    protected boolean localizeFlowElements(Collection<FlowElement> flowElements, ObjectNode infoNode) {
        boolean localizationValuesChanged = false;

        if (flowElements == null) {
            return localizationValuesChanged;
        }

        CommandContext commandContext = Context.getCommandContext();
        DynamicBpmnService dynamicBpmnService = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDynamicBpmnService();

        for (FlowElement flowElement : flowElements) {
            if (flowElement instanceof UserTask || flowElement instanceof SubProcess) {
                List<ExtensionElement> localizationElements = flowElement.getExtensionElements().get("localization");
                if (localizationElements != null) {
                    for (ExtensionElement localizationElement : localizationElements) {
                        if (BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX.equals(localizationElement.getNamespacePrefix()) ||
                                BpmnXMLConstants.ACTIVITI_EXTENSIONS_PREFIX.equals(localizationElement.getNamespacePrefix())) {

                            String locale = localizationElement.getAttributeValue(null, "locale");
                            String name = localizationElement.getAttributeValue(null, "name");
                            String documentation = null;
                            List<ExtensionElement> documentationElements = localizationElement.getChildElements().get("documentation");
                            if (documentationElements != null) {
                                for (ExtensionElement documentationElement : documentationElements) {
                                    documentation = StringUtils.trimToNull(documentationElement.getElementText());
                                    break;
                                }
                            }

                            String flowElementId = flowElement.getId();
                            if (!isEqualToCurrentLocalizationValue(locale, flowElementId, "name", name, infoNode)) {
                                dynamicBpmnService.changeLocalizationName(locale, flowElementId, name, infoNode);
                                localizationValuesChanged = true;
                            }

                            if (documentation != null && !isEqualToCurrentLocalizationValue(locale, flowElementId, "description", documentation, infoNode)) {
                                dynamicBpmnService.changeLocalizationDescription(locale, flowElementId, documentation, infoNode);
                                localizationValuesChanged = true;
                            }
                        }
                    }
                }

                if (flowElement instanceof SubProcess) {
                    SubProcess subprocess = (SubProcess) flowElement;
                    boolean isFlowElementLocalizationChanged = localizeFlowElements(subprocess.getFlowElements(), infoNode);
                    boolean isDataObjectLocalizationChanged = localizeDataObjectElements(subprocess.getDataObjects(), infoNode);
                    if (isFlowElementLocalizationChanged || isDataObjectLocalizationChanged) {
                        localizationValuesChanged = true;
                    }
                }
            }
        }

        return localizationValuesChanged;
    }

    protected boolean isEqualToCurrentLocalizationValue(String language, String id, String propertyName, String propertyValue, ObjectNode infoNode) {
        boolean isEqual = false;
        JsonNode localizationNode = infoNode.path("localization").path(language).path(id).path(propertyName);
        if (!localizationNode.isMissingNode() && !localizationNode.isNull() && localizationNode.asText().equals(propertyValue)) {
            isEqual = true;
        }
        return isEqual;
    }

    protected boolean localizeDataObjectElements(List<ValuedDataObject> dataObjects, ObjectNode infoNode) {
        boolean localizationValuesChanged = false;
        CommandContext commandContext = Context.getCommandContext();
        DynamicBpmnService dynamicBpmnService = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDynamicBpmnService();

        for (ValuedDataObject dataObject : dataObjects) {
            List<ExtensionElement> localizationElements = dataObject.getExtensionElements().get("localization");
            if (localizationElements != null) {
                for (ExtensionElement localizationElement : localizationElements) {
                    if (BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX.equals(localizationElement.getNamespacePrefix()) ||
                            BpmnXMLConstants.ACTIVITI_EXTENSIONS_PREFIX.equals(localizationElement.getNamespacePrefix())) {

                        String locale = localizationElement.getAttributeValue(null, "locale");
                        String name = localizationElement.getAttributeValue(null, "name");
                        String documentation = null;

                        List<ExtensionElement> documentationElements = localizationElement.getChildElements().get("documentation");
                        if (documentationElements != null) {
                            for (ExtensionElement documentationElement : documentationElements) {
                                documentation = StringUtils.trimToNull(documentationElement.getElementText());
                                break;
                            }
                        }

                        if (name != null && !isEqualToCurrentLocalizationValue(locale, dataObject.getId(), DynamicBpmnConstants.LOCALIZATION_NAME, name, infoNode)) {
                            dynamicBpmnService.changeLocalizationName(locale, dataObject.getId(), name, infoNode);
                            localizationValuesChanged = true;
                        }

                        if (documentation != null && !isEqualToCurrentLocalizationValue(locale, dataObject.getId(),
                                DynamicBpmnConstants.LOCALIZATION_DESCRIPTION, documentation, infoNode)) {

                            dynamicBpmnService.changeLocalizationDescription(locale, dataObject.getId(), documentation, infoNode);
                            localizationValuesChanged = true;
                        }
                    }
                }
            }
        }

        return localizationValuesChanged;
    }

    public IdGenerator getIdGenerator() {
        return idGenerator;
    }

    public void setIdGenerator(IdGenerator idGenerator) {
        this.idGenerator = idGenerator;
    }

    public ParsedDeploymentBuilderFactory getExParsedDeploymentBuilderFactory() {
        return parsedDeploymentBuilderFactory;
    }

    public void setParsedDeploymentBuilderFactory(ParsedDeploymentBuilderFactory parsedDeploymentBuilderFactory) {
        this.parsedDeploymentBuilderFactory = parsedDeploymentBuilderFactory;
    }

    public BpmnDeploymentHelper getBpmnDeploymentHelper() {
        return bpmnDeploymentHelper;
    }

    public void setBpmnDeploymentHelper(BpmnDeploymentHelper bpmnDeploymentHelper) {
        this.bpmnDeploymentHelper = bpmnDeploymentHelper;
    }

    public CachingAndArtifactsManager getCachingAndArtifcatsManager() {
        return cachingAndArtifactsManager;
    }

    public void setCachingAndArtifactsManager(CachingAndArtifactsManager manager) {
        this.cachingAndArtifactsManager = manager;
    }

    public ProcessDefinitionDiagramHelper getProcessDefinitionDiagramHelper() {
        return processDefinitionDiagramHelper;
    }

    public void setProcessDefinitionDiagramHelper(ProcessDefinitionDiagramHelper processDefinitionDiagramHelper) {
        this.processDefinitionDiagramHelper = processDefinitionDiagramHelper;
    }

    public boolean isUsePrefixId() {
        return usePrefixId;
    }

    public void setUsePrefixId(boolean usePrefixId) {
        this.usePrefixId = usePrefixId;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值