All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.activiti.engine.impl.history.DefaultHistoryManager Maven / Gradle / Ivy

There is a newer version: 3.0.Beta
Show newest version
/* 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.activiti.engine.impl.history;

import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.delegate.event.ActivitiEventDispatcher;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.cfg.IdGenerator;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.AbstractManager;
import org.activiti.engine.impl.persistence.cache.EntityCache;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.task.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;

/**
 * Manager class that centralises recording of all history-related operations that are originated from inside the engine.
 * 
 */
public class DefaultHistoryManager extends AbstractManager implements HistoryManager {

  private static Logger log = LoggerFactory.getLogger(DefaultHistoryManager.class.getName());

  private HistoryLevel historyLevel;

  public DefaultHistoryManager(ProcessEngineConfigurationImpl processEngineConfiguration, HistoryLevel historyLevel) {
    super(processEngineConfiguration);
    this.historyLevel = historyLevel;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# isHistoryLevelAtLeast(org.activiti.engine.impl.history.HistoryLevel)
   */
  @Override
  public boolean isHistoryLevelAtLeast(HistoryLevel level) {
    if (log.isDebugEnabled()) {
      log.debug("Current history level: {}, level required: {}", historyLevel, level);
    }
    // Comparing enums actually compares the location of values declared in
    // the enum
    return historyLevel.isAtLeast(level);
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#isHistoryEnabled ()
   */
  @Override
  public boolean isHistoryEnabled() {
    if (log.isDebugEnabled()) {
      log.debug("Current history level: {}", historyLevel);
    }
    return !historyLevel.equals(HistoryLevel.NONE);
  }

  // Process related history

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordProcessInstanceEnd(java.lang.String, java.lang.String, java.lang.String)
   */
  @Override
  public void recordProcessInstanceEnd(String processInstanceId, String deleteReason, String activityId) {

    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceEntityManager().findById(processInstanceId);

      if (historicProcessInstance != null) {
        historicProcessInstance.markEnded(deleteReason);
        historicProcessInstance.setEndActivityId(activityId);
        
        // Fire event
        ActivitiEventDispatcher activitiEventDispatcher = getEventDispatcher();
        if (activitiEventDispatcher != null && activitiEventDispatcher.isEnabled()) {
          activitiEventDispatcher.dispatchEvent(
              ActivitiEventBuilder.createEntityEvent(ActivitiEventType.HISTORIC_PROCESS_INSTANCE_ENDED, historicProcessInstance));
        }
        
      }
    }
  }

  @Override
  public void recordProcessInstanceNameChange(String processInstanceId, String newName) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceEntityManager().findById(processInstanceId);

      if (historicProcessInstance != null) {
        historicProcessInstance.setName(newName);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordProcessInstanceStart (org.activiti.engine.impl.persistence.entity.ExecutionEntity)
   */
  @Override
  public void recordProcessInstanceStart(ExecutionEntity processInstance, FlowElement startElement) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceEntityManager().create(processInstance); 
      historicProcessInstance.setStartActivityId(startElement.getId());

      // Insert historic process-instance
      getHistoricProcessInstanceEntityManager().insert(historicProcessInstance, false);
      
      // Fire event
      ActivitiEventDispatcher activitiEventDispatcher = getEventDispatcher();
      if (activitiEventDispatcher != null && activitiEventDispatcher.isEnabled()) {
        activitiEventDispatcher.dispatchEvent(
            ActivitiEventBuilder.createEntityEvent(ActivitiEventType.HISTORIC_PROCESS_INSTANCE_CREATED, historicProcessInstance));
      }

    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordSubProcessInstanceStart (org.activiti.engine.impl.persistence.entity.ExecutionEntity,
   * org.activiti.engine.impl.persistence.entity.ExecutionEntity)
   */
  @Override
  public void recordSubProcessInstanceStart(ExecutionEntity parentExecution, ExecutionEntity subProcessInstance, FlowElement initialElement) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {

      HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceEntityManager().create(subProcessInstance); 

      // Fix for ACT-1728: startActivityId not initialized with subprocess instance
      if (historicProcessInstance.getStartActivityId() == null) {
        historicProcessInstance.setStartActivityId(initialElement.getId());
      }
      getHistoricProcessInstanceEntityManager().insert(historicProcessInstance, false);
      
      // Fire event
      ActivitiEventDispatcher activitiEventDispatcher = getEventDispatcher();
      if (activitiEventDispatcher != null && activitiEventDispatcher.isEnabled()) {
        activitiEventDispatcher.dispatchEvent(
            ActivitiEventBuilder.createEntityEvent(ActivitiEventType.HISTORIC_PROCESS_INSTANCE_CREATED, historicProcessInstance));
      }

      HistoricActivityInstanceEntity activitiyInstance = findActivityInstance(parentExecution, false, true);
      if (activitiyInstance != null) {
        activitiyInstance.setCalledProcessInstanceId(subProcessInstance.getProcessInstanceId());
      }

    }
  }

  // Activity related history

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordActivityStart (org.activiti.engine.impl.persistence.entity.ExecutionEntity)
   */
  @Override
  public void recordActivityStart(ExecutionEntity executionEntity) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      if (executionEntity.getActivityId() != null && executionEntity.getCurrentFlowElement() != null) {
        
        HistoricActivityInstanceEntity historicActivityInstanceEntity = null;
        
        // Historic activity instance could have been created (but only in cache, never persisted)
        // for example when submitting form properties
        HistoricActivityInstanceEntity historicActivityInstanceEntityFromCache = 
            getHistoricActivityInstanceFromCache(executionEntity.getId(), executionEntity.getActivityId(), true);
        if (historicActivityInstanceEntityFromCache != null) {
          historicActivityInstanceEntity = historicActivityInstanceEntityFromCache;
        } else {
          historicActivityInstanceEntity = createHistoricActivityInstanceEntity(executionEntity);
        }
        
        // Fire event
        ActivitiEventDispatcher activitiEventDispatcher = getEventDispatcher();
        if (activitiEventDispatcher != null && activitiEventDispatcher.isEnabled()) {
          activitiEventDispatcher.dispatchEvent(
              ActivitiEventBuilder.createEntityEvent(ActivitiEventType.HISTORIC_ACTIVITY_INSTANCE_CREATED, historicActivityInstanceEntity));
        }
        
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordActivityEnd (org.activiti.engine.impl.persistence.entity.ExecutionEntity)
   */
  @Override
  public void recordActivityEnd(ExecutionEntity executionEntity, String deleteReason) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricActivityInstanceEntity historicActivityInstance = findActivityInstance(executionEntity, false, true);
      if (historicActivityInstance != null) {
        historicActivityInstance.markEnded(deleteReason);
        
        // Fire event
        ActivitiEventDispatcher activitiEventDispatcher = getEventDispatcher();
        if (activitiEventDispatcher != null && activitiEventDispatcher.isEnabled()) {
          activitiEventDispatcher.dispatchEvent(
              ActivitiEventBuilder.createEntityEvent(ActivitiEventType.HISTORIC_ACTIVITY_INSTANCE_ENDED, historicActivityInstance));
        }
      }
    }
  }

  @Override
  public HistoricActivityInstanceEntity findActivityInstance(ExecutionEntity execution, boolean createOnNotFound, boolean endTimeMustBeNull) {
    String activityId = null;
    if (execution.getCurrentFlowElement() instanceof FlowNode) {
      activityId = execution.getCurrentFlowElement().getId();
    } else if (execution.getCurrentFlowElement() instanceof SequenceFlow
        && execution.getCurrentActivitiListener() == null) { // while executing sequence flow listeners, we don't want historic activities
      activityId = ( (SequenceFlow) (execution.getCurrentFlowElement())).getSourceFlowElement().getId();
    } 
    
    if (activityId != null) {
      return findActivityInstance(execution, activityId, createOnNotFound, endTimeMustBeNull);
    }
    
    return null;
  }
    
    
  public HistoricActivityInstanceEntity findActivityInstance(ExecutionEntity execution, String activityId, boolean createOnNotFound, boolean endTimeMustBeNull) {
    
    // No use looking for the HistoricActivityInstance when no activityId is provided.
    if (activityId == null) {
      return null;
    }
    
    String executionId = execution.getId();

    // Check the cache
    HistoricActivityInstanceEntity historicActivityInstanceEntityFromCache = 
        getHistoricActivityInstanceFromCache(executionId, activityId, endTimeMustBeNull);
    if (historicActivityInstanceEntityFromCache != null) {
      return historicActivityInstanceEntityFromCache;
    }
    
    // If the execution was freshly created, there is no need to check the database, 
    // there can never be an entry for a historic activity instance with this execution id.
    if (!execution.isInserted() && !execution.isProcessInstanceType()) {

      // Check the database
      List historicActivityInstances = getHistoricActivityInstanceEntityManager()
          .findUnfinishedHistoricActivityInstancesByExecutionAndActivityId(executionId, activityId); 
  
      if (historicActivityInstances.size() > 0) {
        return historicActivityInstances.get(0);
      }
      
    }
    
    if (execution.getParentId() != null) {
      HistoricActivityInstanceEntity historicActivityInstanceFromParent 
        = findActivityInstance((ExecutionEntity) execution.getParent(), activityId, false, endTimeMustBeNull); // always false for create, we only check if it can be found
      if (historicActivityInstanceFromParent != null) {
        return historicActivityInstanceFromParent;
      }
    }
    
    if (createOnNotFound 
        && activityId != null
        && ( (execution.getCurrentFlowElement() != null && execution.getCurrentFlowElement() instanceof FlowNode) || execution.getCurrentFlowElement() == null)) {
      return createHistoricActivityInstanceEntity(execution);
    }

    return null;
  }

  protected HistoricActivityInstanceEntity getHistoricActivityInstanceFromCache(String executionId, String activityId, boolean endTimeMustBeNull) {
    List cachedHistoricActivityInstances = getEntityCache().findInCache(HistoricActivityInstanceEntity.class);
    for (HistoricActivityInstanceEntity cachedHistoricActivityInstance : cachedHistoricActivityInstances) {
      if (activityId != null 
          && activityId.equals(cachedHistoricActivityInstance.getActivityId()) 
          && (!endTimeMustBeNull || cachedHistoricActivityInstance.getEndTime() == null)) {
        if (executionId.equals(cachedHistoricActivityInstance.getExecutionId())) {
          return cachedHistoricActivityInstance;
        }
      }
    }
    
    return null;
  }

  protected HistoricActivityInstanceEntity createHistoricActivityInstanceEntity(ExecutionEntity execution) {
    IdGenerator idGenerator = getProcessEngineConfiguration().getIdGenerator();
    
    String processDefinitionId = execution.getProcessDefinitionId();
    String processInstanceId = execution.getProcessInstanceId();
      
    HistoricActivityInstanceEntity historicActivityInstance = getHistoricActivityInstanceEntityManager().create();
    historicActivityInstance.setId(idGenerator.getNextId());
    historicActivityInstance.setProcessDefinitionId(processDefinitionId);
    historicActivityInstance.setProcessInstanceId(processInstanceId);
    historicActivityInstance.setExecutionId(execution.getId());
    historicActivityInstance.setActivityId(execution.getActivityId());
    if (execution.getCurrentFlowElement() != null) {
      historicActivityInstance.setActivityName(execution.getCurrentFlowElement().getName());
      historicActivityInstance.setActivityType(parseActivityType(execution.getCurrentFlowElement()));
    }
    Date now = getClock().getCurrentTime();
    historicActivityInstance.setStartTime(now);
 
    // Inherit tenant id (if applicable)
    if (execution.getTenantId() != null) {
      historicActivityInstance.setTenantId(execution.getTenantId());
    }
    
    getHistoricActivityInstanceEntityManager().insert(historicActivityInstance);
    return historicActivityInstance;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordProcessDefinitionChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordProcessDefinitionChange(String processInstanceId, String processDefinitionId) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceEntityManager().findById(processInstanceId);
      if (historicProcessInstance != null) {
        historicProcessInstance.setProcessDefinitionId(processDefinitionId);
      }
    }
  }

  // Task related history

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskCreated (org.activiti.engine.impl.persistence.entity.TaskEntity,
   * org.activiti.engine.impl.persistence.entity.ExecutionEntity)
   */
  @Override
  public void recordTaskCreated(TaskEntity task, ExecutionEntity execution) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().create(task, execution);
      getHistoricTaskInstanceEntityManager().insert(historicTaskInstance, false);
    }
    
    recordTaskId(task);
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskAssignment (org.activiti.engine.impl.persistence.entity.TaskEntity)
   */
  @Override
  public void recordTaskAssignment(TaskEntity task) {
    ExecutionEntity executionEntity = task.getExecution();
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      if (executionEntity != null) {
        HistoricActivityInstanceEntity historicActivityInstance = findActivityInstance(executionEntity, false, true);
        if (historicActivityInstance != null) {
          historicActivityInstance.setAssignee(task.getAssignee());
        }
      }
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskClaim (org.activiti.engine.impl.persistence.entity.TaskEntity)
   */

  @Override
  public void recordTaskClaim(TaskEntity task) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(task.getId());
      if (historicTaskInstance != null) {
        historicTaskInstance.setClaimTime(task.getClaimTime());
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskId (org.activiti.engine.impl.persistence.entity.TaskEntity)
   */
  @Override
  public void recordTaskId(TaskEntity task) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      ExecutionEntity execution = task.getExecution();
      if (execution != null) {
        HistoricActivityInstanceEntity historicActivityInstance = findActivityInstance(execution, false, true);
        if (historicActivityInstance != null) {
          historicActivityInstance.setTaskId(task.getId());
        }
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskEnd (java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskEnd(String taskId, String deleteReason) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.markEnded(deleteReason);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskAssigneeChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskAssigneeChange(String taskId, String assignee) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setAssignee(assignee);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskOwnerChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskOwnerChange(String taskId, String owner) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setOwner(owner);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskNameChange (java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskNameChange(String taskId, String taskName) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setName(taskName);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskDescriptionChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskDescriptionChange(String taskId, String description) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setDescription(description);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskDueDateChange(java.lang.String, java.util.Date)
   */
  @Override
  public void recordTaskDueDateChange(String taskId, Date dueDate) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setDueDate(dueDate);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskPriorityChange(java.lang.String, int)
   */
  @Override
  public void recordTaskPriorityChange(String taskId, int priority) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setPriority(priority);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskCategoryChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskCategoryChange(String taskId, String category) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setCategory(category);
      }
    }
  }

  @Override
  public void recordTaskFormKeyChange(String taskId, String formKey) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setFormKey(formKey);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskParentTaskIdChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskParentTaskIdChange(String taskId, String parentTaskId) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setParentTaskId(parentTaskId);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskExecutionIdChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskExecutionIdChange(String taskId, String executionId) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setExecutionId(executionId);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordTaskDefinitionKeyChange (org.activiti.engine.impl.persistence.entity.TaskEntity, java.lang.String)
   */
  @Override
  public void recordTaskDefinitionKeyChange(String taskId, String taskDefinitionKey) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setTaskDefinitionKey(taskDefinitionKey);
      }
    }
  }
  
  /* (non-Javadoc)
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordTaskProcessDefinitionChange(java.lang.String, java.lang.String)
   */
  @Override
  public void recordTaskProcessDefinitionChange(String taskId, String processDefinitionId) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricTaskInstanceEntity historicTaskInstance = getHistoricTaskInstanceEntityManager().findById(taskId);
      if (historicTaskInstance != null) {
        historicTaskInstance.setProcessDefinitionId(processDefinitionId);
      }
    }
  }

  // Variables related history

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordVariableCreate (org.activiti.engine.impl.persistence.entity.VariableInstanceEntity)
   */
  @Override
  public void recordVariableCreate(VariableInstanceEntity variable) {
    // Historic variables
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
     getHistoricVariableInstanceEntityManager().copyAndInsert(variable);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordHistoricDetailVariableCreate (org.activiti.engine.impl.persistence.entity.VariableInstanceEntity,
   * org.activiti.engine.impl.persistence.entity.ExecutionEntity, boolean)
   */
  @Override
  public void recordHistoricDetailVariableCreate(VariableInstanceEntity variable, ExecutionEntity sourceActivityExecution, boolean useActivityId) {
    if (isHistoryLevelAtLeast(HistoryLevel.FULL)) {

      HistoricDetailVariableInstanceUpdateEntity historicVariableUpdate = getHistoricDetailEntityManager().copyAndInsertHistoricDetailVariableInstanceUpdateEntity(variable);

      if (useActivityId && sourceActivityExecution != null) {
        HistoricActivityInstanceEntity historicActivityInstance = findActivityInstance(sourceActivityExecution, false, false);
        if (historicActivityInstance != null) {
          historicVariableUpdate.setActivityInstanceId(historicActivityInstance.getId());
        }
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface#recordVariableUpdate (org.activiti.engine.impl.persistence.entity.VariableInstanceEntity)
   */
  @Override
  public void recordVariableUpdate(VariableInstanceEntity variable) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricVariableInstanceEntity historicProcessVariable = getEntityCache().findInCache(HistoricVariableInstanceEntity.class, variable.getId());
      if (historicProcessVariable == null) {
        historicProcessVariable = getHistoricVariableInstanceEntityManager().findHistoricVariableInstanceByVariableInstanceId(variable.getId());
      }

      if (historicProcessVariable != null) {
        getHistoricVariableInstanceEntityManager().copyVariableValue(historicProcessVariable, variable);
      } else {
        getHistoricVariableInstanceEntityManager().copyAndInsert(variable);
      }
    }
  }

  // Comment related history

  
  
  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# createIdentityLinkComment(java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean)
   */
  @Override
  public void createIdentityLinkComment(String taskId, String userId, String groupId, String type, boolean create) {
    createIdentityLinkComment(taskId, userId, groupId, type, create, false);
  }

  @Override
  public void createUserIdentityLinkComment(String taskId, String userId, String type, boolean create) {
    createIdentityLinkComment(taskId, userId, null, type, create, false);
  }

  @Override
  public void createGroupIdentityLinkComment(String taskId, String groupId, String type, boolean create) {
    createIdentityLinkComment(taskId, null, groupId, type, create, false);
  }
  
  @Override
  public void createUserIdentityLinkComment(String taskId, String userId, String type, boolean create, boolean forceNullUserId) {
    createIdentityLinkComment(taskId, userId, null, type, create, forceNullUserId);
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# createIdentityLinkComment(java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean, boolean)
   */
  @Override
  public void createIdentityLinkComment(String taskId, String userId, String groupId, String type, boolean create, boolean forceNullUserId) {
    if (isHistoryEnabled()) {
      String authenticatedUserId = Authentication.getAuthenticatedUserId();
      CommentEntity comment = getCommentEntityManager().create(); 
      comment.setUserId(authenticatedUserId);
      comment.setType(CommentEntity.TYPE_EVENT);
      comment.setTime(getClock().getCurrentTime());
      comment.setTaskId(taskId);
      if (userId != null || forceNullUserId) {
        if (create) {
          comment.setAction(Event.ACTION_ADD_USER_LINK);
        } else {
          comment.setAction(Event.ACTION_DELETE_USER_LINK);
        }
        comment.setMessage(new String[] { userId, type });
      } else {
        if (create) {
          comment.setAction(Event.ACTION_ADD_GROUP_LINK);
        } else {
          comment.setAction(Event.ACTION_DELETE_GROUP_LINK);
        }
        comment.setMessage(new String[] { groupId, type });
      }
      
      getCommentEntityManager().insert(comment);
    }
  }

  @Override
  public void createProcessInstanceIdentityLinkComment(String processInstanceId, String userId, String groupId, String type, boolean create) {
    createProcessInstanceIdentityLinkComment(processInstanceId, userId, groupId, type, create, false);
  }

  @Override
  public void createProcessInstanceIdentityLinkComment(String processInstanceId, String userId, String groupId, String type, boolean create, boolean forceNullUserId) {
    if (isHistoryEnabled()) {
      String authenticatedUserId = Authentication.getAuthenticatedUserId();
      CommentEntity comment = getCommentEntityManager().create();
      comment.setUserId(authenticatedUserId);
      comment.setType(CommentEntity.TYPE_EVENT);
      comment.setTime(getClock().getCurrentTime());
      comment.setProcessInstanceId(processInstanceId);
      if (userId != null || forceNullUserId) {
        if (create) {
          comment.setAction(Event.ACTION_ADD_USER_LINK);
        } else {
          comment.setAction(Event.ACTION_DELETE_USER_LINK);
        }
        comment.setMessage(new String[] { userId, type });
      } else {
        if (create) {
          comment.setAction(Event.ACTION_ADD_GROUP_LINK);
        } else {
          comment.setAction(Event.ACTION_DELETE_GROUP_LINK);
        }
        comment.setMessage(new String[] { groupId, type });
      }
      getCommentEntityManager().insert(comment);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# createAttachmentComment(java.lang.String, java.lang.String, java.lang.String, boolean)
   */
  @Override
  public void createAttachmentComment(String taskId, String processInstanceId, String attachmentName, boolean create) {
    if (isHistoryEnabled()) {
      String userId = Authentication.getAuthenticatedUserId();
      CommentEntity comment = getCommentEntityManager().create();
      comment.setUserId(userId);
      comment.setType(CommentEntity.TYPE_EVENT);
      comment.setTime(getClock().getCurrentTime());
      comment.setTaskId(taskId);
      comment.setProcessInstanceId(processInstanceId);
      if (create) {
        comment.setAction(Event.ACTION_ADD_ATTACHMENT);
      } else {
        comment.setAction(Event.ACTION_DELETE_ATTACHMENT);
      }
      comment.setMessage(attachmentName);
      getCommentEntityManager().insert(comment);
    }
  }

  // Identity link related history
  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# recordIdentityLinkCreated (org.activiti.engine.impl.persistence.entity.IdentityLinkEntity)
   */
  @Override
  public void recordIdentityLinkCreated(IdentityLinkEntity identityLink) {
    // It makes no sense storing historic counterpart for an identity-link
    // that is related
    // to a process-definition only as this is never kept in history
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT) && (identityLink.getProcessInstanceId() != null || identityLink.getTaskId() != null)) {
      HistoricIdentityLinkEntity historicIdentityLinkEntity = getHistoricIdentityLinkEntityManager().create();
      historicIdentityLinkEntity.setId(identityLink.getId());
      historicIdentityLinkEntity.setGroupId(identityLink.getGroupId());
      historicIdentityLinkEntity.setProcessInstanceId(identityLink.getProcessInstanceId());
      historicIdentityLinkEntity.setTaskId(identityLink.getTaskId());
      historicIdentityLinkEntity.setType(identityLink.getType());
      historicIdentityLinkEntity.setUserId(identityLink.getUserId());
      getHistoricIdentityLinkEntityManager().insert(historicIdentityLinkEntity, false);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# deleteHistoricIdentityLink(java.lang.String)
   */
  @Override
  public void deleteHistoricIdentityLink(String id) {
    if (isHistoryLevelAtLeast(HistoryLevel.AUDIT)) {
      getHistoricIdentityLinkEntityManager().delete(id);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.activiti.engine.impl.history.HistoryManagerInterface# updateProcessBusinessKeyInHistory (org.activiti.engine.impl.persistence.entity.ExecutionEntity)
   */
  @Override
  public void updateProcessBusinessKeyInHistory(ExecutionEntity processInstance) {
    if (isHistoryEnabled()) {
      if (log.isDebugEnabled()) {
        log.debug("updateProcessBusinessKeyInHistory : {}", processInstance.getId());
      }
      if (processInstance != null) {
        HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceEntityManager().findById(processInstance.getId());
        if (historicProcessInstance != null) {
          historicProcessInstance.setBusinessKey(processInstance.getProcessInstanceBusinessKey());
          getHistoricProcessInstanceEntityManager().update(historicProcessInstance, false);
        }
      }
    }
  }

  @Override
  public void recordVariableRemoved(VariableInstanceEntity variable) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricVariableInstanceEntity historicProcessVariable = getEntityCache()
          .findInCache(HistoricVariableInstanceEntity.class, variable.getId());
      if (historicProcessVariable == null) {
        historicProcessVariable = getHistoricVariableInstanceEntityManager()
            .findHistoricVariableInstanceByVariableInstanceId(variable.getId());
      }

      if (historicProcessVariable != null) {
        getHistoricVariableInstanceEntityManager().delete(historicProcessVariable);
      } 
    }
  }

  protected String parseActivityType(FlowElement element) {
    String elementType = element.getClass().getSimpleName();
    elementType = elementType.substring(0, 1).toLowerCase() + elementType.substring(1);
    return elementType;
  }
  
  protected EntityCache getEntityCache() {
    return getSession(EntityCache.class);
  }

  public HistoryLevel getHistoryLevel() {
    return historyLevel;
  }

  public void setHistoryLevel(HistoryLevel historyLevel) {
    this.historyLevel = historyLevel;
  }
  
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy