Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.flowable.engine.impl.persistence.entity.ExecutionEntityManagerImpl Maven / Gradle / Ivy
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.flowable.engine.impl.persistence.entity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.flowable.bpmn.model.CaseServiceTask;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.cmmn.api.CallbackTypes;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.api.constant.ReferenceTypes;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.api.scope.ScopeTypes;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.common.engine.impl.logging.LoggingSessionConstants;
import org.flowable.common.engine.impl.persistence.cache.CachedEntityMatcher;
import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManager;
import org.flowable.common.engine.impl.persistence.entity.ByteArrayRef;
import org.flowable.engine.delegate.event.impl.FlowableEventBuilder;
import org.flowable.engine.history.DeleteReason;
import org.flowable.engine.impl.ExecutionQueryImpl;
import org.flowable.engine.impl.ProcessInstanceQueryImpl;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.cmmn.CaseInstanceService;
import org.flowable.engine.impl.delegate.SubProcessActivityBehavior;
import org.flowable.engine.impl.history.HistoryManager;
import org.flowable.engine.impl.persistence.CountingExecutionEntity;
import org.flowable.engine.impl.persistence.entity.data.ExecutionDataManager;
import org.flowable.engine.impl.runtime.callback.ProcessInstanceState;
import org.flowable.engine.impl.util.BpmnLoggingSessionUtil;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.CountingEntityUtil;
import org.flowable.engine.impl.util.EventUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.engine.impl.util.ProcessInstanceHelper;
import org.flowable.engine.impl.util.TaskHelper;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.entitylink.api.EntityLink;
import org.flowable.entitylink.api.EntityLinkService;
import org.flowable.entitylink.service.impl.persistence.entity.EntityLinkEntity;
import org.flowable.eventsubscription.service.EventSubscriptionService;
import org.flowable.eventsubscription.service.impl.persistence.entity.EventSubscriptionEntity;
import org.flowable.eventsubscription.service.impl.persistence.entity.MessageEventSubscriptionEntity;
import org.flowable.identitylink.service.IdentityLinkService;
import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntity;
import org.flowable.identitylink.service.impl.persistence.entity.data.impl.cachematcher.IdentityLinksByProcessInstanceMatcher;
import org.flowable.job.service.JobService;
import org.flowable.job.service.event.impl.FlowableJobEventBuilder;
import org.flowable.job.service.impl.asyncexecutor.AsyncExecutor;
import org.flowable.job.service.impl.persistence.entity.ExternalWorkerJobEntity;
import org.flowable.job.service.impl.persistence.entity.ExternalWorkerJobEntityManager;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Tom Baeyens
* @author Joram Barrez
*/
public class ExecutionEntityManagerImpl
extends AbstractProcessEngineEntityManager
implements ExecutionEntityManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionEntityManagerImpl.class);
public ExecutionEntityManagerImpl(ProcessEngineConfigurationImpl processEngineConfiguration, ExecutionDataManager executionDataManager) {
super(processEngineConfiguration, executionDataManager);
}
// Overriding the default delete methods to set the 'isDeleted' flag
@Override
public void delete(ExecutionEntity entity) {
delete(entity, true);
}
@Override
public void delete(ExecutionEntity entity, boolean fireDeleteEvent) {
super.delete(entity, fireDeleteEvent);
entity.setDeleted(true);
}
// FIND METHODS
@Override
public ExecutionEntity findSubProcessInstanceBySuperExecutionId(String superExecutionId) {
return dataManager.findSubProcessInstanceBySuperExecutionId(superExecutionId);
}
@Override
public List findChildExecutionsByParentExecutionId(String parentExecutionId) {
return dataManager.findChildExecutionsByParentExecutionId(parentExecutionId);
}
@Override
public List findChildExecutionsByProcessInstanceId(String processInstanceId) {
return dataManager.findChildExecutionsByProcessInstanceId(processInstanceId);
}
@Override
public List findExecutionsByParentExecutionAndActivityIds(final String parentExecutionId, final Collection activityIds) {
return dataManager.findExecutionsByParentExecutionAndActivityIds(parentExecutionId, activityIds);
}
@Override
public long findExecutionCountByQueryCriteria(ExecutionQueryImpl executionQuery) {
return dataManager.findExecutionCountByQueryCriteria(executionQuery);
}
@Override
public List findExecutionsByQueryCriteria(ExecutionQueryImpl executionQuery) {
return dataManager.findExecutionsByQueryCriteria(executionQuery);
}
@Override
public long findProcessInstanceCountByQueryCriteria(ProcessInstanceQueryImpl executionQuery) {
return dataManager.findProcessInstanceCountByQueryCriteria(executionQuery);
}
@Override
public List findProcessInstanceByQueryCriteria(ProcessInstanceQueryImpl executionQuery) {
return dataManager.findProcessInstanceByQueryCriteria(executionQuery);
}
@Override
public ExecutionEntity findByRootProcessInstanceId(String rootProcessInstanceId) {
List executions = dataManager.findExecutionsByRootProcessInstanceId(rootProcessInstanceId);
return processExecutionTree(rootProcessInstanceId, executions);
}
/**
* Processes a collection of {@link ExecutionEntity} instances, which form on execution tree. All the executions share the same rootProcessInstanceId (which is provided). The return value will be
* the root {@link ExecutionEntity} instance, with all child {@link ExecutionEntity} instances populated and set using the {@link ExecutionEntity} instances from the provided collections
*/
protected ExecutionEntity processExecutionTree(String rootProcessInstanceId, List executions) {
ExecutionEntity rootExecution = null;
// Collect executions
Map executionMap = new HashMap<>(executions.size());
for (ExecutionEntity executionEntity : executions) {
if (executionEntity.getId().equals(rootProcessInstanceId)) {
rootExecution = executionEntity;
}
executionMap.put(executionEntity.getId(), executionEntity);
}
// Set relationships
for (ExecutionEntity executionEntity : executions) {
// Root process instance relationship
if (executionEntity.getRootProcessInstanceId() != null) {
executionEntity.setRootProcessInstance(executionMap.get(executionEntity.getRootProcessInstanceId()));
}
// Process instance relationship
if (executionEntity.getProcessInstanceId() != null) {
executionEntity.setProcessInstance(executionMap.get(executionEntity.getProcessInstanceId()));
}
// Parent - child relationship
if (executionEntity.getParentId() != null) {
ExecutionEntity parentExecutionEntity = executionMap.get(executionEntity.getParentId());
executionEntity.setParent(parentExecutionEntity);
parentExecutionEntity.addChildExecution(executionEntity);
}
// Super - sub execution relationship
if (executionEntity.getSuperExecution() != null) {
ExecutionEntity superExecutionEntity = executionMap.get(executionEntity.getSuperExecutionId());
executionEntity.setSuperExecution(superExecutionEntity);
superExecutionEntity.setSubProcessInstance(executionEntity);
}
}
return rootExecution;
}
@Override
public List findProcessInstanceAndVariablesByQueryCriteria(ProcessInstanceQueryImpl executionQuery) {
return dataManager.findProcessInstanceAndVariablesByQueryCriteria(executionQuery);
}
@Override
public Collection findInactiveExecutionsByProcessInstanceId(final String processInstanceId) {
return dataManager.findInactiveExecutionsByProcessInstanceId(processInstanceId);
}
@Override
public Collection findInactiveExecutionsByActivityIdAndProcessInstanceId(final String activityId, final String processInstanceId) {
return dataManager.findInactiveExecutionsByActivityIdAndProcessInstanceId(activityId, processInstanceId);
}
@Override
public List findExecutionsByNativeQuery(Map parameterMap) {
return dataManager.findExecutionsByNativeQuery(parameterMap);
}
@Override
public List findProcessInstanceByNativeQuery(Map parameterMap) {
return dataManager.findProcessInstanceByNativeQuery(parameterMap);
}
@Override
public long findExecutionCountByNativeQuery(Map parameterMap) {
return dataManager.findExecutionCountByNativeQuery(parameterMap);
}
@Override
public long countActiveExecutionsByParentId(String parentId) {
return dataManager.countActiveExecutionsByParentId(parentId);
}
// CREATE METHODS
@Override
public ExecutionEntity createProcessInstanceExecution(ProcessDefinition processDefinition, String predefinedProcessInstanceId,
String businessKey, String processInstanceName,
String callbackId, String callbackType, String referenceId, String referenceType,
String propagatedStageInstanceId, String tenantId, String initiatorVariableName, String startActivityId) {
ExecutionEntity processInstanceExecution = dataManager.create();
if (CountingEntityUtil.isExecutionRelatedEntityCountEnabledGlobally()) {
((CountingExecutionEntity) processInstanceExecution).setCountEnabled(true);
}
if (predefinedProcessInstanceId != null) {
processInstanceExecution.setId(predefinedProcessInstanceId);
}
processInstanceExecution.setProcessDefinitionId(processDefinition.getId());
processInstanceExecution.setProcessDefinitionKey(processDefinition.getKey());
processInstanceExecution.setProcessDefinitionName(processDefinition.getName());
processInstanceExecution.setProcessDefinitionVersion(processDefinition.getVersion());
processInstanceExecution.setDeploymentId(processDefinition.getDeploymentId());
processInstanceExecution.setBusinessKey(businessKey);
processInstanceExecution.setName(processInstanceName);
// Callbacks
if (callbackId != null) {
processInstanceExecution.setCallbackId(callbackId);
}
if (callbackType != null) {
processInstanceExecution.setCallbackType(callbackType);
}
if (referenceId != null) {
processInstanceExecution.setReferenceId(referenceId);
}
if (referenceType != null) {
processInstanceExecution.setReferenceType(referenceType);
}
if (propagatedStageInstanceId != null) {
processInstanceExecution.setPropagatedStageInstanceId(propagatedStageInstanceId);
}
processInstanceExecution.setScope(true); // process instance is always a scope for all child executions
// Inherit tenant id (if any)
if (tenantId != null) {
processInstanceExecution.setTenantId(tenantId);
}
String authenticatedUserId = Authentication.getAuthenticatedUserId();
processInstanceExecution.setStartActivityId(startActivityId);
processInstanceExecution.setStartTime(CommandContextUtil.getProcessEngineConfiguration().getClock().getCurrentTime());
processInstanceExecution.setStartUserId(authenticatedUserId);
// Store in database
insert(processInstanceExecution, false);
if (initiatorVariableName != null) {
processInstanceExecution.setVariable(initiatorVariableName, authenticatedUserId);
}
// Need to be after insert, cause we need the id
processInstanceExecution.setProcessInstanceId(processInstanceExecution.getId());
processInstanceExecution.setRootProcessInstanceId(processInstanceExecution.getId());
if (engineConfiguration.getIdentityLinkInterceptor() != null) {
engineConfiguration.getIdentityLinkInterceptor().handleCreateProcessInstance(processInstanceExecution);
}
// Fire events
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_CREATED, processInstanceExecution),
engineConfiguration.getEngineCfgKey());
}
return processInstanceExecution;
}
/**
* Creates a new execution. properties processDefinition, processInstance and activity will be initialized.
*/
@Override
public ExecutionEntity createChildExecution(ExecutionEntity parentExecutionEntity) {
ExecutionEntity childExecution = dataManager.create();
inheritCommonProperties(parentExecutionEntity, childExecution);
childExecution.setParent(parentExecutionEntity);
childExecution.setProcessDefinitionId(parentExecutionEntity.getProcessDefinitionId());
childExecution.setProcessDefinitionKey(parentExecutionEntity.getProcessDefinitionKey());
childExecution.setProcessInstanceId(parentExecutionEntity.getProcessInstanceId() != null
? parentExecutionEntity.getProcessInstanceId() : parentExecutionEntity.getId());
childExecution.setScope(false);
// manage the bidirectional parent-child relation
parentExecutionEntity.addChildExecution(childExecution);
// Insert the child execution
insert(childExecution, false);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Child execution {} created with parent {}", childExecution, parentExecutionEntity.getId());
}
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_CREATED, childExecution),
engineConfiguration.getEngineCfgKey());
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_INITIALIZED, childExecution),
engineConfiguration.getEngineCfgKey());
}
return childExecution;
}
@Override
public ExecutionEntity createSubprocessInstance(ProcessDefinition processDefinition, ExecutionEntity superExecutionEntity,
String businessKey, String activityId) {
ExecutionEntity subProcessInstance = dataManager.create();
inheritCommonProperties(superExecutionEntity, subProcessInstance);
subProcessInstance.setProcessDefinitionId(processDefinition.getId());
subProcessInstance.setProcessDefinitionKey(processDefinition.getKey());
subProcessInstance.setProcessDefinitionName(processDefinition.getName());
subProcessInstance.setSuperExecution(superExecutionEntity);
subProcessInstance.setRootProcessInstanceId(superExecutionEntity.getRootProcessInstanceId());
subProcessInstance.setScope(true); // process instance is always a scope for all child executions
String authenticatedUserId = Authentication.getAuthenticatedUserId();
subProcessInstance.setStartActivityId(activityId);
subProcessInstance.setStartUserId(authenticatedUserId);
subProcessInstance.setBusinessKey(businessKey);
// Store in database
insert(subProcessInstance, false);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Child execution {} created with super execution {}", subProcessInstance, superExecutionEntity.getId());
}
subProcessInstance.setProcessInstanceId(subProcessInstance.getId());
superExecutionEntity.setSubProcessInstance(subProcessInstance);
if (engineConfiguration.getIdentityLinkInterceptor() != null) {
engineConfiguration.getIdentityLinkInterceptor().handleCreateSubProcessInstance(subProcessInstance, superExecutionEntity);
}
engineConfiguration.getProcessInstanceHelper().processAvailableEventSubProcesses(subProcessInstance,
ProcessDefinitionUtil.getProcess(processDefinition.getId()),CommandContextUtil.getCommandContext());
FlowableEventDispatcher flowableEventDispatcher = engineConfiguration.getEventDispatcher();
if (flowableEventDispatcher != null && flowableEventDispatcher.isEnabled()) {
flowableEventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_CREATED, subProcessInstance),
engineConfiguration.getEngineCfgKey());
}
return subProcessInstance;
}
protected void inheritCommonProperties(ExecutionEntity parentExecutionEntity, ExecutionEntity childExecution) {
// Inherits the 'count' feature from the parent.
// If the parent was not 'counting', we can't make the child 'counting' again.
if (parentExecutionEntity instanceof CountingExecutionEntity) {
CountingExecutionEntity countingParentExecutionEntity = (CountingExecutionEntity) parentExecutionEntity;
((CountingExecutionEntity) childExecution).setCountEnabled(countingParentExecutionEntity.isCountEnabled());
}
// inherit the stage instance id, if present
childExecution.setPropagatedStageInstanceId(parentExecutionEntity.getPropagatedStageInstanceId());
childExecution.setRootProcessInstanceId(parentExecutionEntity.getRootProcessInstanceId());
childExecution.setActive(true);
childExecution.setStartTime(getClock().getCurrentTime());
if (parentExecutionEntity.getTenantId() != null) {
childExecution.setTenantId(parentExecutionEntity.getTenantId());
}
}
// UPDATE METHODS
@Override
public void updateExecutionTenantIdForDeployment(String deploymentId, String newTenantId) {
dataManager.updateExecutionTenantIdForDeployment(deploymentId, newTenantId);
}
// DELETE METHODS
@Override
public void deleteProcessInstancesByProcessDefinition(String processDefinitionId, String deleteReason, boolean cascade) {
List processInstanceIds = dataManager.findProcessInstanceIdsByProcessDefinitionId(processDefinitionId);
for (String processInstanceId : processInstanceIds) {
deleteProcessInstanceCascade(findById(processInstanceId), deleteReason, cascade, true);
}
if (cascade) {
getHistoryManager().recordDeleteHistoricProcessInstancesByProcessDefinitionId(processDefinitionId);
}
}
@Override
public void deleteProcessInstance(String processInstanceId, String deleteReason, boolean cascade) {
deleteProcessInstance(processInstanceId, deleteReason, cascade, false);
}
@Override
public void deleteProcessInstance(String processInstanceId, String deleteReason, boolean cascade, boolean directDeleteInDatabase) {
ExecutionEntity processInstanceExecution = findById(processInstanceId);
if (processInstanceExecution == null) {
throw new FlowableObjectNotFoundException("No process instance found for id '" + processInstanceId + "'", ProcessInstance.class);
}
deleteProcessInstanceCascade(processInstanceExecution, deleteReason, cascade, directDeleteInDatabase);
// Special care needed for a process instance of a call activity: the parent process instance needs to be triggered for completion
// This can't be added to the deleteProcessInstanceCascade method, as this will also trigger all child and/or multi-instance
// process instances for child call activities, which shouldn't happen.
if (processInstanceExecution.getSuperExecutionId() != null) {
ExecutionEntity superExecution = processInstanceExecution.getSuperExecution();
if (superExecution != null
&& superExecution.getCurrentFlowElement() instanceof FlowNode
&& ((FlowNode) superExecution.getCurrentFlowElement()).getBehavior() instanceof SubProcessActivityBehavior) {
SubProcessActivityBehavior subProcessActivityBehavior = (SubProcessActivityBehavior) ((FlowNode) superExecution.getCurrentFlowElement()).getBehavior();
try {
subProcessActivityBehavior.completing(superExecution, processInstanceExecution);
superExecution.setSubProcessInstance(null);
subProcessActivityBehavior.completed(superExecution);
} catch (Exception e) {
throw new FlowableException("Could not complete parent process instance for call activity with process instance execution "
+ processInstanceExecution.getId(), e);
}
}
}
}
protected void deleteProcessInstanceCascade(ExecutionEntity execution, String deleteReason, boolean deleteHistory, boolean directDeleteInDatabase) {
// fill default reason if none provided
if (deleteReason == null) {
deleteReason = DeleteReason.PROCESS_INSTANCE_DELETED;
}
getActivityInstanceEntityManager().deleteActivityInstancesByProcessInstanceId(execution.getId());
List childExecutions = collectChildren(execution.getProcessInstance());
for (ExecutionEntity subExecutionEntity : childExecutions) {
if (subExecutionEntity.isMultiInstanceRoot()) {
for (ExecutionEntity miExecutionEntity : subExecutionEntity.getExecutions()) {
if (miExecutionEntity.getSubProcessInstance() != null) {
deleteProcessInstanceCascade(miExecutionEntity.getSubProcessInstance(), deleteReason, deleteHistory, directDeleteInDatabase);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
FlowElement callActivityElement = miExecutionEntity.getCurrentFlowElement();
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createActivityCancelledEvent(callActivityElement.getId(),
callActivityElement.getName(), miExecutionEntity.getId(), miExecutionEntity.getProcessInstanceId(),
miExecutionEntity.getProcessDefinitionId(), "callActivity", deleteReason), engineConfiguration.getEngineCfgKey());
}
}
}
} else if (subExecutionEntity.getSubProcessInstance() != null) {
deleteProcessInstanceCascade(subExecutionEntity.getSubProcessInstance(), deleteReason, deleteHistory, directDeleteInDatabase);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
FlowElement callActivityElement = subExecutionEntity.getCurrentFlowElement();
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createActivityCancelledEvent(callActivityElement.getId(),
callActivityElement.getName(), subExecutionEntity.getId(), subExecutionEntity.getProcessInstanceId(),
subExecutionEntity.getProcessDefinitionId(), "callActivity", deleteReason), engineConfiguration.getEngineCfgKey());
}
}
}
TaskHelper.deleteTasksByProcessInstanceId(execution.getId(), deleteReason, deleteHistory);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createCancelledEvent(execution.getProcessInstanceId(),
execution.getProcessInstanceId(), execution.getProcessDefinitionId(), deleteReason), engineConfiguration.getEngineCfgKey());
}
// delete the execution BEFORE we delete the history, otherwise we will
// produce orphan HistoricVariableInstance instances
ExecutionEntity processInstanceExecutionEntity = execution.getProcessInstance();
if (processInstanceExecutionEntity == null) {
return;
}
for (int i = childExecutions.size() - 1; i >= 0; i--) {
ExecutionEntity childExecutionEntity = childExecutions.get(i);
deleteExecutionAndRelatedData(childExecutionEntity, deleteReason, deleteHistory, directDeleteInDatabase);
}
deleteExecutionAndRelatedData(execution, deleteReason, deleteHistory, directDeleteInDatabase, true, null);
if (deleteHistory) {
getHistoryManager().recordProcessInstanceDeleted(execution.getId(), execution.getProcessDefinitionId(), execution.getTenantId());
}
getHistoryManager().recordProcessInstanceEnd(processInstanceExecutionEntity, deleteReason, null, getClock().getCurrentTime());
processInstanceExecutionEntity.setDeleted(true);
}
@Override
public void deleteExecutionAndRelatedData(ExecutionEntity executionEntity, String deleteReason, boolean deleteHistory,
boolean directDeleteInDatabase, boolean cancel, FlowElement cancelActivity) {
if (!deleteHistory && executionEntity.isActive()
&& executionEntity.getCurrentFlowElement() != null
&& !executionEntity.isMultiInstanceRoot()) {
CommandContextUtil.getActivityInstanceEntityManager().recordActivityEnd(executionEntity, deleteReason);
}
deleteRelatedDataForExecution(executionEntity, deleteReason, directDeleteInDatabase);
delete(executionEntity);
if (cancel && !executionEntity.isProcessInstanceType()) {
dispatchActivityCancelled(executionEntity, cancelActivity != null ? cancelActivity : executionEntity.getCurrentFlowElement());
}
if (executionEntity.isProcessInstanceType() && executionEntity.getCallbackId() != null) {
CommandContext commandContext = CommandContextUtil.getCommandContext();
ProcessInstanceHelper processInstanceHelper = CommandContextUtil.getProcessInstanceHelper(commandContext);
if (cancel) {
processInstanceHelper.callCaseInstanceStateChangeCallbacks(commandContext, executionEntity,
ProcessInstanceState.RUNNING, ProcessInstanceState.CANCELLED);
} else {
processInstanceHelper.callCaseInstanceStateChangeCallbacks(commandContext, executionEntity,
ProcessInstanceState.RUNNING, ProcessInstanceState.COMPLETED);
}
}
}
@Override
public void deleteExecutionAndRelatedData(ExecutionEntity executionEntity, String deleteReason, boolean deleteHistory) {
deleteExecutionAndRelatedData(executionEntity, deleteReason, deleteHistory, false, false, null);
}
@Override
public void deleteExecutionAndRelatedData(ExecutionEntity executionEntity, String deleteReason, boolean deleteHistory, boolean directDeleteInDatabase) {
deleteExecutionAndRelatedData(executionEntity, deleteReason, deleteHistory, directDeleteInDatabase, false, null);
}
@Override
public void deleteProcessInstanceExecutionEntity(String processInstanceId, String currentFlowElementId, String deleteReason,
boolean cascade, boolean cancel, boolean fireEvents) {
ExecutionEntity processInstanceEntity = findById(processInstanceId);
if (processInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No process instance found for id '" + processInstanceId + "'", ProcessInstance.class);
}
if (processInstanceEntity.isDeleted()) {
return;
}
// Call activities
for (ExecutionEntity subExecutionEntity : processInstanceEntity.getExecutions()) {
if (subExecutionEntity.getSubProcessInstance() != null && !subExecutionEntity.isEnded()) {
deleteProcessInstanceCascade(subExecutionEntity.getSubProcessInstance(), deleteReason, cascade, false);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled() && fireEvents) {
FlowElement callActivityElement = subExecutionEntity.getCurrentFlowElement();
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createActivityCancelledEvent(callActivityElement.getId(),
callActivityElement.getName(), subExecutionEntity.getId(), processInstanceId, subExecutionEntity.getProcessDefinitionId(),
"callActivity", deleteReason), engineConfiguration.getEngineCfgKey());
}
}
}
// delete event scope executions
for (ExecutionEntity childExecution : processInstanceEntity.getExecutions()) {
if (childExecution.isEventScope()) {
deleteExecutionAndRelatedData(childExecution, null, cascade, false);
}
}
deleteChildExecutions(processInstanceEntity, deleteReason, cancel);
deleteExecutionAndRelatedData(processInstanceEntity, deleteReason, cascade, false);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled() && fireEvents) {
if (!cancel) {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.PROCESS_COMPLETED, processInstanceEntity),
engineConfiguration.getEngineCfgKey());
} else {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createCancelledEvent(processInstanceEntity.getId(),
processInstanceEntity.getId(), processInstanceEntity.getProcessDefinitionId(), deleteReason),
engineConfiguration.getEngineCfgKey());
}
}
if (engineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_PROCESS_COMPLETED, "Completed process instance with id " + processInstanceEntity.getId(), processInstanceEntity);
}
getHistoryManager().recordProcessInstanceEnd(processInstanceEntity, deleteReason, currentFlowElementId, getClock().getCurrentTime());
processInstanceEntity.setDeleted(true);
}
@Override
public void deleteChildExecutions(ExecutionEntity executionEntity, String deleteReason, boolean cancel) {
deleteChildExecutions(executionEntity, null, null, deleteReason, cancel, null);
}
@Override
public void deleteChildExecutions(ExecutionEntity executionEntity, Collection executionIdsNotToDelete,
Collection executionIdsNotToSendCancelledEventFor, String deleteReason,
boolean cancel, FlowElement cancelActivity) {
// The children of an execution for a tree. For correct deletions (taking care of foreign keys between child-parent)
// the leafs of this tree must be deleted first before the parents elements.
List childExecutions = collectChildren(executionEntity, executionIdsNotToDelete);
for (int i = childExecutions.size() - 1; i >= 0; i--) {
ExecutionEntity childExecutionEntity = childExecutions.get(i);
if (!childExecutionEntity.isEnded()) {
if (executionIdsNotToDelete == null || !executionIdsNotToDelete.contains(childExecutionEntity.getId())) {
if (childExecutionEntity.isProcessInstanceType()) {
deleteProcessInstanceExecutionEntity(childExecutionEntity.getId(),
cancelActivity != null ? cancelActivity.getId() : null, deleteReason, true, cancel, true);
} else {
if (cancel && (childExecutionEntity.isActive() || childExecutionEntity.isMultiInstanceRoot())
&& (executionIdsNotToSendCancelledEventFor == null || !executionIdsNotToSendCancelledEventFor.contains(childExecutionEntity.getId()))) {
dispatchExecutionCancelled(childExecutionEntity,
cancelActivity != null ? cancelActivity : childExecutionEntity.getCurrentFlowElement());
}
}
deleteExecutionAndRelatedData(childExecutionEntity, deleteReason, false, false);
}
}
}
}
@Override
public List collectChildren(ExecutionEntity executionEntity) {
return collectChildren(executionEntity, null);
}
protected List collectChildren(ExecutionEntity executionEntity, Collection executionIdsToExclude) {
List childExecutions = new ArrayList<>();
collectChildren(executionEntity, childExecutions, executionIdsToExclude != null ? executionIdsToExclude : Collections.emptyList());
return childExecutions;
}
@SuppressWarnings("unchecked")
protected void collectChildren(ExecutionEntity executionEntity, List collectedChildExecution, Collection executionIdsToExclude) {
List childExecutions = (List) executionEntity.getExecutions();
if (childExecutions != null && childExecutions.size() > 0) {
// Have a fixed ordering of child executions (important for the order in which events are sent)
childExecutions.sort(ExecutionEntity.EXECUTION_ENTITY_START_TIME_ASC_COMPARATOR);
for (ExecutionEntity childExecution : childExecutions) {
if (!executionIdsToExclude.contains(childExecution.getId())) {
if (!childExecution.isDeleted()) {
collectedChildExecution.add(childExecution);
}
collectChildren(childExecution, collectedChildExecution, executionIdsToExclude);
}
}
}
ExecutionEntity subProcessInstance = executionEntity.getSubProcessInstance();
if (subProcessInstance != null && !executionIdsToExclude.contains(subProcessInstance.getId())) {
if (!subProcessInstance.isDeleted()) {
collectedChildExecution.add(subProcessInstance);
}
collectChildren(subProcessInstance, collectedChildExecution, executionIdsToExclude);
}
}
protected void dispatchExecutionCancelled(ExecutionEntity execution, FlowElement cancelActivity) {
ExecutionEntityManager executionEntityManager = engineConfiguration.getExecutionEntityManager();
// subprocesses
for (ExecutionEntity subExecution : executionEntityManager.findChildExecutionsByParentExecutionId(execution.getId())) {
dispatchExecutionCancelled(subExecution, cancelActivity);
}
// call activities
ExecutionEntity subProcessInstance = engineConfiguration.getExecutionEntityManager().findSubProcessInstanceBySuperExecutionId(execution.getId());
if (subProcessInstance != null) {
dispatchExecutionCancelled(subProcessInstance, cancelActivity);
}
// activity with message/signal boundary events
FlowElement currentFlowElement = execution.getCurrentFlowElement();
if (currentFlowElement instanceof FlowNode) {
if (execution.isMultiInstanceRoot()) {
dispatchMultiInstanceActivityCancelled(execution, cancelActivity);
}
else {
dispatchActivityCancelled(execution, cancelActivity);
}
}
}
protected void dispatchActivityCancelled(ExecutionEntity execution, FlowElement cancelActivity) {
FlowableEventDispatcher eventDispatcher = engineConfiguration.getEventDispatcher();
if (eventDispatcher != null && eventDispatcher.isEnabled()) {
eventDispatcher.dispatchEvent(
FlowableEventBuilder.createActivityCancelledEvent(execution.getCurrentFlowElement().getId(),
execution.getCurrentFlowElement().getName(), execution.getId(), execution.getProcessInstanceId(),
execution.getProcessDefinitionId(), getActivityType((FlowNode) execution.getCurrentFlowElement()), cancelActivity),
engineConfiguration.getEngineCfgKey());
}
}
protected void dispatchMultiInstanceActivityCancelled(ExecutionEntity execution, FlowElement cancelActivity) {
FlowableEventDispatcher eventDispatcher = engineConfiguration.getEventDispatcher();
if (eventDispatcher != null && eventDispatcher.isEnabled()) {
eventDispatcher.dispatchEvent(
FlowableEventBuilder.createMultiInstanceActivityCancelledEvent(execution.getCurrentFlowElement().getId(),
execution.getCurrentFlowElement().getName(), execution.getId(), execution.getProcessInstanceId(),
execution.getProcessDefinitionId(), getActivityType((FlowNode) execution.getCurrentFlowElement()), cancelActivity),
engineConfiguration.getEngineCfgKey());
}
}
protected String getActivityType(FlowNode flowNode) {
String elementType = flowNode.getClass().getSimpleName();
elementType = elementType.substring(0, 1).toLowerCase() + elementType.substring(1);
return elementType;
}
@Override
public ExecutionEntity findFirstScope(ExecutionEntity executionEntity) {
ExecutionEntity currentExecutionEntity = executionEntity;
while (currentExecutionEntity != null) {
if (currentExecutionEntity.isScope()) {
return currentExecutionEntity;
}
ExecutionEntity parentExecutionEntity = currentExecutionEntity.getParent();
if (parentExecutionEntity == null) {
parentExecutionEntity = currentExecutionEntity.getSuperExecution();
}
currentExecutionEntity = parentExecutionEntity;
}
return null;
}
@Override
public ExecutionEntity findFirstMultiInstanceRoot(ExecutionEntity executionEntity) {
ExecutionEntity currentExecutionEntity = executionEntity;
while (currentExecutionEntity != null) {
if (currentExecutionEntity.isMultiInstanceRoot()) {
return currentExecutionEntity;
}
ExecutionEntity parentExecutionEntity = currentExecutionEntity.getParent();
if (parentExecutionEntity == null) {
parentExecutionEntity = currentExecutionEntity.getSuperExecution();
}
currentExecutionEntity = parentExecutionEntity;
}
return null;
}
protected CachedEntityMatcher identityLinkByProcessInstanceMatcher = new IdentityLinksByProcessInstanceMatcher();
@Override
public void deleteRelatedDataForExecution(ExecutionEntity executionEntity, String deleteReason, boolean directDeleteInDatabase) {
// To start, deactivate the current incoming execution
executionEntity.setEnded(true);
executionEntity.setActive(false);
CommandContext commandContext = CommandContextUtil.getCommandContext();
boolean enableExecutionRelationshipCounts = CountingEntityUtil.isExecutionRelatedEntityCountEnabled(executionEntity);
// If event dispatching is disabled, related entities can be deleted in bulk. Otherwise, they need to be fetched
// and events need to be sent for each of them separately (the bulk delete still happens).
FlowableEventDispatcher eventDispatcher = CommandContextUtil.getProcessEngineConfiguration(commandContext).getEventDispatcher();
boolean eventDispatcherEnabled = eventDispatcher != null && eventDispatcher.isEnabled();
deleteIdentityLinks(executionEntity, commandContext, eventDispatcherEnabled);
deleteEntityLinks(executionEntity, commandContext, eventDispatcherEnabled);
deleteVariables(executionEntity, commandContext, enableExecutionRelationshipCounts, eventDispatcherEnabled);
deleteUserTasks(executionEntity, deleteReason, commandContext, enableExecutionRelationshipCounts, eventDispatcherEnabled);
deleteJobs(executionEntity, commandContext, enableExecutionRelationshipCounts, eventDispatcherEnabled);
deleteEventSubScriptions(executionEntity, enableExecutionRelationshipCounts, eventDispatcherEnabled);
deleteActivityInstances(executionEntity, commandContext);
deleteSubCases(executionEntity, directDeleteInDatabase, commandContext);
}
protected void deleteSubCases(ExecutionEntity executionEntity, boolean directDeleteInDatabase, CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
CaseInstanceService caseInstanceService = processEngineConfiguration.getCaseInstanceService();
if (caseInstanceService != null) {
if (executionEntity.getReferenceId() != null && ReferenceTypes.EXECUTION_CHILD_CASE.equals(executionEntity.getReferenceType())) {
if (directDeleteInDatabase) {
caseInstanceService.deleteCaseInstanceWithoutAgenda(executionEntity.getReferenceId());
} else {
caseInstanceService.deleteCaseInstance(executionEntity.getReferenceId());
}
} else if (executionEntity.getCurrentFlowElement() instanceof CaseServiceTask) {
// backwards compatibility in case there is no reference
// (cases created before the double reference in the execution) was added
caseInstanceService.deleteCaseInstancesForExecutionId(executionEntity.getId());
}
}
}
protected void deleteActivityInstances(ExecutionEntity executionEntity, CommandContext commandContext) {
if (executionEntity.isProcessInstanceType()) {
engineConfiguration.getActivityInstanceEntityManager().deleteActivityInstancesByProcessInstanceId(executionEntity.getId());
}
}
protected void deleteIdentityLinks(ExecutionEntity executionEntity, CommandContext commandContext, boolean eventDispatcherEnabled) {
if (executionEntity.isProcessInstanceType()) {
IdentityLinkService identityLinkService = engineConfiguration.getIdentityLinkServiceConfiguration().getIdentityLinkService();
boolean deleteIdentityLinks = true;
if (eventDispatcherEnabled) {
Collection identityLinks = identityLinkService.findIdentityLinksByProcessInstanceId(executionEntity.getId());
for (IdentityLinkEntity identityLink : identityLinks) {
fireEntityDeletedEvent(identityLink);
}
deleteIdentityLinks = !identityLinks.isEmpty();
}
if (deleteIdentityLinks) {
identityLinkService.deleteIdentityLinksByProcessInstanceId(executionEntity.getId());
}
}
}
protected void deleteEntityLinks(ExecutionEntity executionEntity, CommandContext commandContext, boolean eventDispatcherEnabled) {
// Entity links are deleted by a root instance only.
// (A callback id is set for a child process instance of a case instance.
// A super execution id is set for a child process instance of a process instance)
// Can't simply check for callBackId being null however, as other usages of callbackType still need to be cleaned up
if (engineConfiguration.isEnableEntityLinks() && executionEntity.isProcessInstanceType() && isRootProcessInstance(executionEntity)) {
EntityLinkService entityLinkService = engineConfiguration.getEntityLinkServiceConfiguration().getEntityLinkService();
boolean deleteEntityLinks = true;
if (eventDispatcherEnabled) {
List entityLinks = entityLinkService.findEntityLinksByRootScopeIdAndRootType(executionEntity.getId(), ScopeTypes.BPMN);
for (EntityLink entityLink : entityLinks) {
fireEntityDeletedEvent((EntityLinkEntity) entityLink);
}
deleteEntityLinks = !entityLinks.isEmpty();
}
if (deleteEntityLinks) {
entityLinkService.deleteEntityLinksByRootScopeIdAndType(executionEntity.getId(), ScopeTypes.BPMN);
}
}
}
protected boolean isRootProcessInstance(ExecutionEntity executionEntity) {
// An execution is a root process instance when it doesn't have a super execution and,
// it has no callback or it is not a child of a case instance
return executionEntity.getSuperExecutionId() == null
&& (executionEntity.getCallbackId() == null || !CallbackTypes.PLAN_ITEM_CHILD_PROCESS.equals(executionEntity.getCallbackType()));
}
protected void deleteVariables(ExecutionEntity executionEntity, CommandContext commandContext, boolean enableExecutionRelationshipCounts, boolean eventDispatcherEnabled) {
if (!enableExecutionRelationshipCounts ||
(enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getVariableCount() > 0)) {
Collection executionVariables = executionEntity.getVariableInstancesLocal().values();
if (!executionVariables.isEmpty()) {
List variableByteArrayRefs = new ArrayList<>();
for (VariableInstance variableInstance : executionVariables) {
if (variableInstance instanceof VariableInstanceEntity) {
VariableInstanceEntity variableInstanceEntity = (VariableInstanceEntity) variableInstance;
if (variableInstanceEntity.getByteArrayRef() != null && variableInstanceEntity.getByteArrayRef().getId() != null) {
variableByteArrayRefs.add(variableInstanceEntity.getByteArrayRef());
}
if (eventDispatcherEnabled) {
FlowableEventDispatcher eventDispatcher = engineConfiguration.getEventDispatcher();
if (eventDispatcher != null) {
eventDispatcher.dispatchEvent(EventUtil.createVariableDeleteEvent(variableInstanceEntity),
engineConfiguration.getEngineCfgKey());
eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, variableInstance),
engineConfiguration.getEngineCfgKey());
}
}
}
}
// First byte arrays that reference variable, then variables in bulk
for (ByteArrayRef variableByteArrayRef : variableByteArrayRefs) {
getByteArrayEntityManager().deleteByteArrayById(variableByteArrayRef.getId());
}
engineConfiguration.getVariableServiceConfiguration().getVariableService().deleteVariablesByExecutionId(executionEntity.getId());
}
List variableInstances = engineConfiguration.getVariableServiceConfiguration().getVariableService()
.createInternalVariableInstanceQuery()
.subScopeId(executionEntity.getId())
.scopeTypes(ScopeTypes.BPMN_DEPENDENT)
.list();
boolean deleteVariableInstances = !variableInstances.isEmpty();
for (VariableInstanceEntity variableInstance : variableInstances) {
if (eventDispatcherEnabled) {
FlowableEventDispatcher eventDispatcher = CommandContextUtil.getEventDispatcher(commandContext);
if (eventDispatcher != null) {
eventDispatcher.dispatchEvent(EventUtil.createVariableDeleteEvent(variableInstance),
engineConfiguration.getEngineCfgKey());
eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, variableInstance),
engineConfiguration.getEngineCfgKey());
}
}
if (variableInstance.getByteArrayRef() != null && variableInstance.getByteArrayRef().getId() != null) {
variableInstance.getByteArrayRef().delete(engineConfiguration.getEngineCfgKey());
}
}
if (deleteVariableInstances) {
engineConfiguration.getVariableServiceConfiguration().getVariableInstanceEntityManager()
.deleteBySubScopeIdAndScopeTypes(executionEntity.getId(), ScopeTypes.BPMN_DEPENDENT);
}
}
}
protected void deleteUserTasks(ExecutionEntity executionEntity, String deleteReason, CommandContext commandContext,
boolean enableExecutionRelationshipCounts, boolean eventDispatcherEnabled) {
if (!enableExecutionRelationshipCounts ||
(enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getTaskCount() > 0)) {
TaskHelper.deleteTasksForExecution(executionEntity,
engineConfiguration.getTaskServiceConfiguration().getTaskService().findTasksByExecutionId(executionEntity.getId()), deleteReason);
}
}
protected void deleteJobs(ExecutionEntity executionEntity, CommandContext commandContext, boolean enableExecutionRelationshipCounts, boolean eventDispatcherEnabled) {
// Jobs have byte array references that don't store the execution id.
// This means a bulk delete is not done for jobs. Generally there aren't many jobs / execution either.
if (!enableExecutionRelationshipCounts
|| (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getTimerJobCount() > 0)) {
engineConfiguration.getJobServiceConfiguration().getTimerJobService().deleteTimerJobsByExecutionId(executionEntity.getId());
}
JobService jobService = engineConfiguration.getJobServiceConfiguration().getJobService();
if (!enableExecutionRelationshipCounts
|| (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getJobCount() > 0)) {
jobService.deleteJobsByExecutionId(executionEntity.getId());
}
if (!enableExecutionRelationshipCounts
|| (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getSuspendedJobCount() > 0)) {
jobService.deleteSuspendedJobsByExecutionId(executionEntity.getId());
}
if (!enableExecutionRelationshipCounts
|| (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getDeadLetterJobCount() > 0)) {
jobService.deleteDeadLetterJobsByExecutionId(executionEntity.getId());
}
if (!enableExecutionRelationshipCounts || ((CountingExecutionEntity) executionEntity).getExternalWorkerJobCount() > 0) {
Collection externalWorkerJobsForExecution = jobService.findExternalWorkerJobsByExecutionId(executionEntity.getId());
ExternalWorkerJobEntityManager externalWorkerJobEntityManager = engineConfiguration.getJobServiceConfiguration()
.getExternalWorkerJobEntityManager();
IdentityLinkService identityLinkService = engineConfiguration.getIdentityLinkServiceConfiguration().getIdentityLinkService();
for (ExternalWorkerJobEntity job : externalWorkerJobsForExecution) {
externalWorkerJobEntityManager.delete(job);
identityLinkService.deleteIdentityLinksByScopeIdAndType(job.getCorrelationId(), ScopeTypes.EXTERNAL_WORKER);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
getEventDispatcher().dispatchEvent(FlowableJobEventBuilder.createEntityEvent(FlowableEngineEventType.JOB_CANCELED, job),
engineConfiguration.getEngineCfgKey());
}
}
}
}
protected void deleteEventSubScriptions(ExecutionEntity executionEntity, boolean enableExecutionRelationshipCounts, boolean eventDispatcherEnabled) {
if (!enableExecutionRelationshipCounts
|| (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getEventSubscriptionCount() > 0)) {
EventSubscriptionService eventSubscriptionService = engineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService();
boolean deleteEventSubscriptions = true;
if (eventDispatcherEnabled) {
List eventSubscriptions = eventSubscriptionService.findEventSubscriptionsByExecution(executionEntity.getId());
for (EventSubscriptionEntity eventSubscription : eventSubscriptions) {
fireEntityDeletedEvent(eventSubscription);
if (MessageEventSubscriptionEntity.EVENT_TYPE.equals(eventSubscription.getEventType())) {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createMessageEvent(FlowableEngineEventType.ACTIVITY_MESSAGE_CANCELLED,
eventSubscription.getActivityId(), eventSubscription.getEventName(), null, eventSubscription.getExecutionId(),
eventSubscription.getProcessInstanceId(), eventSubscription.getProcessDefinitionId()),
engineConfiguration.getEngineCfgKey());
}
}
deleteEventSubscriptions = !eventSubscriptions.isEmpty();
}
if (deleteEventSubscriptions) {
eventSubscriptionService.deleteEventSubscriptionsByExecutionId(executionEntity.getId());
}
}
}
// OTHER METHODS
@Override
public void updateProcessInstanceLockTime(String processInstanceId, String lockOwner, Date lockTime) {
Date expirationTime = getClock().getCurrentTime();
dataManager.updateProcessInstanceLockTime(processInstanceId, lockTime, lockOwner, expirationTime);
}
@Override
public void clearProcessInstanceLockTime(String processInstanceId) {
dataManager.clearProcessInstanceLockTime(processInstanceId);
}
@Override
public void clearAllProcessInstanceLockTimes(String lockOwner) {
dataManager.clearAllProcessInstanceLockTimes(lockOwner);
}
@Override
public String updateProcessInstanceBusinessKey(ExecutionEntity executionEntity, String businessKey) {
if (executionEntity.isProcessInstanceType() && businessKey != null) {
executionEntity.setBusinessKey(businessKey);
getHistoryManager().updateProcessBusinessKeyInHistory(executionEntity);
if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
getEventDispatcher().dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_UPDATED, executionEntity),
engineConfiguration.getEngineCfgKey());
}
return businessKey;
}
return null;
}
protected HistoryManager getHistoryManager() {
return engineConfiguration.getHistoryManager();
}
protected AsyncExecutor getAsyncExecutor() {
return engineConfiguration.getAsyncExecutor();
}
protected ByteArrayEntityManager getByteArrayEntityManager() {
return engineConfiguration.getByteArrayEntityManager();
}
protected ActivityInstanceEntityManager getActivityInstanceEntityManager() {
return engineConfiguration.getActivityInstanceEntityManager();
}
}