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.
/* 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 static org.flowable.engine.impl.util.CommandContextUtil.getEntityCache;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.common.engine.impl.cfg.IdGenerator;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.ActivityInstanceQueryImpl;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.history.HistoryManager;
import org.flowable.engine.impl.persistence.entity.data.ActivityInstanceDataManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
/**
* @author martin.grofcik
*/
public class ActivityInstanceEntityManagerImpl
extends AbstractProcessEngineEntityManager
implements ActivityInstanceEntityManager {
protected static final String NO_ACTIVITY_ID_PREFIX = "_flow_";
protected static final String NO_ACTIVITY_ID_SEPARATOR = "__";
protected final boolean usePrefixId;
public ActivityInstanceEntityManagerImpl(ProcessEngineConfigurationImpl processEngineConfiguration, ActivityInstanceDataManager activityInstanceDataManager) {
super(processEngineConfiguration, activityInstanceDataManager);
this.usePrefixId = processEngineConfiguration.isUsePrefixId();
}
protected List findUnfinishedActivityInstancesByExecutionAndActivityId(String executionId, String activityId) {
return dataManager.findUnfinishedActivityInstancesByExecutionAndActivityId(executionId, activityId);
}
@Override
public List findActivityInstancesByExecutionAndActivityId(String executionId, String activityId) {
return dataManager.findActivityInstancesByExecutionIdAndActivityId(executionId, activityId);
}
@Override
public List findActivityInstancesByProcessInstanceId(String processInstanceId, boolean includeDeleted) {
return dataManager.findActivityInstancesByProcessInstanceId(processInstanceId, includeDeleted);
}
@Override
public ActivityInstanceEntity findActivityInstanceByTaskId(String taskId) {
return dataManager.findActivityInstanceByTaskId(taskId);
}
@Override
public void deleteActivityInstancesByProcessInstanceId(String processInstanceId) {
dataManager.deleteActivityInstancesByProcessInstanceId(processInstanceId);
}
@Override
public long findActivityInstanceCountByQueryCriteria(ActivityInstanceQueryImpl historicActivityInstanceQuery) {
return dataManager.findActivityInstanceCountByQueryCriteria(historicActivityInstanceQuery);
}
@Override
public List findActivityInstancesByQueryCriteria(ActivityInstanceQueryImpl historicActivityInstanceQuery) {
return dataManager.findActivityInstancesByQueryCriteria(historicActivityInstanceQuery);
}
@Override
public List findActivityInstancesByNativeQuery(Map parameterMap) {
return dataManager.findActivityInstancesByNativeQuery(parameterMap);
}
@Override
public long findActivityInstanceCountByNativeQuery(Map parameterMap) {
return dataManager.findActivityInstanceCountByNativeQuery(parameterMap);
}
@Override
public void recordActivityStart(ExecutionEntity executionEntity) {
ActivityInstance activityInstance = recordRuntimeActivityStart(executionEntity);
if (activityInstance != null) {
getHistoryManager().recordActivityStart(activityInstance);
}
}
@Override
public void recordActivityEnd(ExecutionEntity executionEntity, String deleteReason) {
ActivityInstance activityInstance = recordActivityInstanceEnd(executionEntity, deleteReason);
// If the activity instance is null, this means that no runtime activity instance nor historic activity instance exists.
// In the DefaultHistoryManager implementation, the end is ignored (which it needs to be, this is for example when an execution
// has reached a certain step, but hasn't gone into the behavior yet. When the execution is deleted, this method is called,
// but no historic activity instance should be created for this use case).
// However, in the async history manager, this leads to the creation of an activity-end history job.
// To have this consistent, the recordActivityEnd is thus only called when there is a runtime activity available.
if (activityInstance != null) {
getHistoryManager().recordActivityEnd(activityInstance);
}
}
@Override
public void recordSequenceFlowTaken(ExecutionEntity executionEntity) {
ActivityInstanceEntity activityInstance = createActivityInstanceEntity(executionEntity);
activityInstance.setDurationInMillis(0L);
activityInstance.setEndTime(activityInstance.getStartTime());
getHistoryManager().createHistoricActivityInstance(activityInstance);
}
@Override
public void recordSubProcessInstanceStart(ExecutionEntity parentExecution, ExecutionEntity subProcessInstance) {
ActivityInstanceEntity activityInstance = findUnfinishedActivityInstance(parentExecution);
if (activityInstance != null) {
activityInstance.setCalledProcessInstanceId(subProcessInstance.getProcessInstanceId());
getHistoryManager().updateHistoricActivityInstance(activityInstance);
}
getHistoryManager().recordProcessInstanceStart(subProcessInstance);
}
@Override
public void recordTaskCreated(TaskEntity task, ExecutionEntity execution) {
recordActivityTaskCreated(task, execution);
getHistoryManager().recordTaskCreated(task, execution);
}
protected void recordActivityTaskCreated(TaskEntity task, ExecutionEntity execution) {
if (execution != null) {
ActivityInstanceEntity activityInstance = findUnfinishedActivityInstance(execution);
if (activityInstance != null) {
activityInstance.setTaskId(task.getId());
getHistoryManager().updateHistoricActivityInstance(activityInstance);
}
}
}
@Override
public void recordTaskInfoChange(TaskEntity taskEntity, Date changeTime) {
ActivityInstanceEntity activityInstanceEntity = recordActivityTaskInfoChange(taskEntity);
getHistoryManager().recordTaskInfoChange(taskEntity, activityInstanceEntity != null ? activityInstanceEntity.getId() : null, changeTime);
}
@Override
public void syncUserTaskExecution(ExecutionEntity executionEntity, FlowElement newFlowElement, String oldActivityId, TaskEntity task) {
syncUserTaskExecutionActivityInstance(executionEntity, oldActivityId, newFlowElement);
getHistoryManager().updateActivity(executionEntity, oldActivityId, newFlowElement, task, getClock().getCurrentTime());
}
@Override
public void updateActivityInstancesProcessDefinitionId(String newProcessDefinitionId, String processInstanceId) {
ActivityInstanceQueryImpl activityQuery = new ActivityInstanceQueryImpl();
activityQuery.processInstanceId(processInstanceId);
List activities = findActivityInstancesByQueryCriteria(activityQuery);
if (activities != null) {
for (ActivityInstance activityInstance : activities) {
ActivityInstanceEntity activityEntity = (ActivityInstanceEntity) activityInstance;
activityEntity.setProcessDefinitionId(newProcessDefinitionId);
update(activityEntity);
}
}
}
protected void syncUserTaskExecutionActivityInstance(ExecutionEntity childExecution, String oldActivityId,
FlowElement newFlowElement) {
ActivityInstanceEntityManager activityInstanceEntityManager = CommandContextUtil.getActivityInstanceEntityManager();
List activityInstances = activityInstanceEntityManager.findActivityInstancesByExecutionAndActivityId(childExecution.getId(), oldActivityId);
for (ActivityInstanceEntity activityInstance : activityInstances) {
activityInstance.setProcessDefinitionId(childExecution.getProcessDefinitionId());
activityInstance.setActivityId(childExecution.getActivityId());
activityInstance.setActivityName(newFlowElement.getName());
}
}
protected ActivityInstanceEntity recordActivityTaskInfoChange(TaskEntity taskEntity) {
ActivityInstanceEntity activityInstance = null;
ExecutionEntity executionEntity = getExecutionEntityManager().findById(taskEntity.getExecutionId());
if (executionEntity != null) {
if (!Objects.equals(getOriginalAssignee(taskEntity), taskEntity.getAssignee())) {
activityInstance = findActivityInstanceByTaskId(taskEntity.getId());
if (activityInstance == null) {
HistoricActivityInstanceEntity historicActivityInstance = getHistoryManager().findHistoricActivityInstance(executionEntity, true);
if (historicActivityInstance != null) {
activityInstance = createActivityInstance(historicActivityInstance);
}
}
if (activityInstance != null) {
activityInstance.setAssignee(taskEntity.getAssignee());
getHistoryManager().updateHistoricActivityInstance(activityInstance);
}
}
}
return activityInstance;
}
@SuppressWarnings("unchecked")
protected Object getOriginalAssignee(TaskEntity taskEntity) {
if (taskEntity.getOriginalPersistentState() != null) {
return ((Map) taskEntity.getOriginalPersistentState()).get("assignee");
} else {
return null;
}
}
protected ActivityInstance recordRuntimeActivityStart(ExecutionEntity executionEntity) {
ActivityInstance activityInstance = null;
if (executionEntity.getActivityId() != null && executionEntity.getCurrentFlowElement() != null) {
activityInstance = findUnfinishedActivityInstance(executionEntity);
if (activityInstance == null) {
return createActivityInstance(executionEntity);
}
}
return null;
}
protected ActivityInstance createActivityInstance(ExecutionEntity executionEntity) {
ActivityInstance activityInstance = null;
if (executionEntity.getActivityId() != null && executionEntity.getCurrentFlowElement() != null) {
// activity instance could have been created (but only in cache, never persisted)
// for example when submitting form properties
activityInstance = getActivityInstanceFromCache(executionEntity.getId(), executionEntity.getActivityId(), true);
if (activityInstance == null) {
activityInstance = createActivityInstanceEntity(executionEntity);
} else {
// activityInstance is not null only on its creation time
activityInstance = null;
}
}
return activityInstance;
}
protected ActivityInstance recordActivityInstanceEnd(ExecutionEntity executionEntity, String deleteReason) {
// It is possible that we record the activity instance end twice,
// which could lead to having no finished activity instance in the DB.
// if there is a finished runtime one, we should use the runtime one.
//
// It is also OK for pre 6.4.1.2 activity instances (when the runtime activities were added).
// Since the first time we go through here we won't find anything in the cache and the DB,
// so we will create one from the history (this will add one to the cache).
//
// The second time we go through here, there will be nothing in the DB, but one finished one in the cache.
// This one should be used, in order to avoid going to the historic tables again.
ActivityInstanceEntity activityInstance = findUnfinishedActivityInstance(executionEntity, true);
if (activityInstance != null) {
if (activityInstance.getEndTime() == null) {
activityInstance.markEnded(deleteReason);
}
} else {
// in the case of upgrade from 6.4.1.1 to 6.4.1.2 we have to create the runtime activityInstance (when a matching historicActivityInstance is found)
HistoricActivityInstanceEntity historicActivityInstance = getHistoryManager().findHistoricActivityInstance(executionEntity, true);
if (historicActivityInstance != null) {
activityInstance = createActivityInstance(historicActivityInstance);
activityInstance.markEnded(deleteReason);
}
}
return activityInstance;
}
@Override
public ActivityInstanceEntity findUnfinishedActivityInstance(ExecutionEntity execution) {
return findUnfinishedActivityInstance(execution, false);
}
protected ActivityInstanceEntity findUnfinishedActivityInstance(ExecutionEntity execution, boolean returnNotFinishedFromCacheIfNothingInDb) {
String activityId = getActivityIdForExecution(execution);
if (activityId != null) {
// No use looking for the ActivityInstance when no activityId is provided.
String executionId = execution.getId();
// Check the cache
ActivityInstanceEntity activityInstanceFromCache = getActivityInstanceFromCache(executionId, activityId, true);
if (activityInstanceFromCache != null) {
return activityInstanceFromCache;
}
// If the execution was freshly created, there is no need to check the database,
// there can never be an entry for a activity instance with this execution id.
if (!execution.isInserted() && !execution.isProcessInstanceType()) {
// Check the database
List activityInstances = findUnfinishedActivityInstancesByExecutionAndActivityId(executionId, activityId);
// cache can be updated before DB
ActivityInstanceEntity activityFromCache = getActivityInstanceFromCache(executionId, activityId, false);
if (activityFromCache != null && activityFromCache.getEndTime() != null) {
activityInstances.remove(activityFromCache);
}
if (activityInstances.size() > 0) {
return activityInstances.get(0);
} else if (returnNotFinishedFromCacheIfNothingInDb) {
return activityFromCache;
}
}
}
return null;
}
protected ActivityInstanceEntity createActivityInstanceEntity(ExecutionEntity execution) {
IdGenerator idGenerator = engineConfiguration.getIdGenerator();
String processDefinitionId = execution.getProcessDefinitionId();
String processInstanceId = execution.getProcessInstanceId();
ActivityInstanceEntity activityInstanceEntity = create();
if (usePrefixId) {
activityInstanceEntity.setId(activityInstanceEntity.getIdPrefix() + idGenerator.getNextId());
} else {
activityInstanceEntity.setId(idGenerator.getNextId());
}
activityInstanceEntity.setProcessDefinitionId(processDefinitionId);
activityInstanceEntity.setProcessInstanceId(processInstanceId);
activityInstanceEntity.setExecutionId(execution.getId());
if (execution.getActivityId() != null ) {
activityInstanceEntity.setActivityId(execution.getActivityId());
} else {
// sequence flow activity id can be null
if (execution.getCurrentFlowElement() instanceof SequenceFlow) {
SequenceFlow currentFlowElement = (SequenceFlow) execution.getCurrentFlowElement();
activityInstanceEntity.setActivityId(getArtificialSequenceFlowId(currentFlowElement));
}
}
if (execution.getCurrentFlowElement() != null) {
activityInstanceEntity.setActivityName(execution.getCurrentFlowElement().getName());
activityInstanceEntity.setActivityType(parseActivityType(execution.getCurrentFlowElement()));
}
Date now = getClock().getCurrentTime();
activityInstanceEntity.setStartTime(now);
activityInstanceEntity.setTransactionOrder(getTransactionOrderFromCache(processInstanceId));
if (execution.getTenantId() != null) {
activityInstanceEntity.setTenantId(execution.getTenantId());
}
insert(activityInstanceEntity);
return activityInstanceEntity;
}
protected ActivityInstanceEntity getActivityInstanceFromCache(String executionId, String activityId, boolean endTimeMustBeNull) {
List cachedActivityInstances = getEntityCache().findInCache(ActivityInstanceEntity.class);
for (ActivityInstanceEntity cachedActivityInstance : cachedActivityInstances) {
if (activityId != null
&& activityId.equals(cachedActivityInstance.getActivityId())
&& (!endTimeMustBeNull || cachedActivityInstance.getEndTime() == null)) {
if (executionId.equals(cachedActivityInstance.getExecutionId())) {
return cachedActivityInstance;
}
}
}
return null;
}
protected int getTransactionOrderFromCache(String processInstanceId) {
int transactionOrder = 1;
List cachedActivityInstances = getEntityCache().findInCache(ActivityInstanceEntity.class);
for (ActivityInstanceEntity cachedActivityInstance : cachedActivityInstances) {
if (processInstanceId.equals(cachedActivityInstance.getProcessInstanceId())) {
if (cachedActivityInstance.isInserted() && cachedActivityInstance.getTransactionOrder() != null &&
cachedActivityInstance.getTransactionOrder() >= transactionOrder) {
transactionOrder = cachedActivityInstance.getTransactionOrder() + 1;
}
}
}
return transactionOrder;
}
protected String parseActivityType(FlowElement element) {
String elementType = element.getClass().getSimpleName();
elementType = elementType.substring(0, 1).toLowerCase() + elementType.substring(1);
return elementType;
}
protected String getActivityIdForExecution(ExecutionEntity execution) {
String activityId = null;
if (execution.getCurrentFlowElement() instanceof FlowNode) {
activityId = execution.getCurrentFlowElement().getId();
} else if (execution.getCurrentFlowElement() instanceof SequenceFlow
&& execution.getCurrentFlowableListener() == null) { // while executing sequence flow listeners, we don't want historic activities
activityId = ((SequenceFlow) execution.getCurrentFlowElement()).getSourceFlowElement().getId();
}
return activityId;
}
protected ActivityInstanceEntity createActivityInstance(HistoricActivityInstance historicActivityInstance) {
ActivityInstanceEntity activityInstanceEntity = create();
activityInstanceEntity.setId(historicActivityInstance.getId());
activityInstanceEntity.setProcessDefinitionId(historicActivityInstance.getProcessDefinitionId());
activityInstanceEntity.setProcessInstanceId(historicActivityInstance.getProcessInstanceId());
activityInstanceEntity.setCalledProcessInstanceId(historicActivityInstance.getCalledProcessInstanceId());
activityInstanceEntity.setExecutionId(historicActivityInstance.getExecutionId());
activityInstanceEntity.setTaskId(historicActivityInstance.getTaskId());
activityInstanceEntity.setActivityId(historicActivityInstance.getActivityId());
activityInstanceEntity.setActivityName(historicActivityInstance.getActivityName());
activityInstanceEntity.setActivityType(historicActivityInstance.getActivityType());
activityInstanceEntity.setAssignee(historicActivityInstance.getAssignee());
activityInstanceEntity.setStartTime(historicActivityInstance.getStartTime());
activityInstanceEntity.setEndTime(historicActivityInstance.getEndTime());
activityInstanceEntity.setTransactionOrder(historicActivityInstance.getTransactionOrder());
activityInstanceEntity.setDeleteReason(historicActivityInstance.getDeleteReason());
activityInstanceEntity.setDurationInMillis(historicActivityInstance.getDurationInMillis());
activityInstanceEntity.setTenantId(historicActivityInstance.getTenantId());
insert(activityInstanceEntity);
return activityInstanceEntity;
}
protected String getArtificialSequenceFlowId(SequenceFlow sequenceFlow) {
return NO_ACTIVITY_ID_PREFIX + sequenceFlow.getSourceRef() + NO_ACTIVITY_ID_SEPARATOR + sequenceFlow.getTargetRef();
}
protected HistoryManager getHistoryManager() {
return engineConfiguration.getHistoryManager();
}
protected ExecutionEntityManager getExecutionEntityManager() {
return engineConfiguration.getExecutionEntityManager();
}
}