Package org.camunda.bpm.engine.impl.cmmn.entity.runtime

Source Code of org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity

/* 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.camunda.bpm.engine.impl.cmmn.entity.runtime;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.ProcessEngineServices;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cmmn.entity.repository.CaseDefinitionEntity;
import org.camunda.bpm.engine.impl.cmmn.execution.CmmnExecution;
import org.camunda.bpm.engine.impl.cmmn.execution.CmmnSentryPart;
import org.camunda.bpm.engine.impl.cmmn.model.CmmnActivity;
import org.camunda.bpm.engine.impl.cmmn.model.CmmnCaseDefinition;
import org.camunda.bpm.engine.impl.cmmn.operation.CmmnAtomicOperation;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.core.instance.CoreExecution;
import org.camunda.bpm.engine.impl.core.operation.CoreAtomicOperation;
import org.camunda.bpm.engine.impl.core.variable.scope.CoreVariableStore;
import org.camunda.bpm.engine.impl.db.DbEntity;
import org.camunda.bpm.engine.impl.db.HasDbReferences;
import org.camunda.bpm.engine.impl.db.HasDbRevision;
import org.camunda.bpm.engine.impl.history.HistoryLevel;
import org.camunda.bpm.engine.impl.history.event.HistoryEvent;
import org.camunda.bpm.engine.impl.history.event.HistoryEventTypes;
import org.camunda.bpm.engine.impl.history.handler.HistoryEventHandler;
import org.camunda.bpm.engine.impl.history.producer.CmmnHistoryEventProducer;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity;
import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity;
import org.camunda.bpm.engine.impl.persistence.entity.VariableInstanceEntity;
import org.camunda.bpm.engine.impl.pvm.PvmProcessDefinition;
import org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl;
import org.camunda.bpm.engine.impl.task.TaskDecorator;
import org.camunda.bpm.engine.runtime.CaseExecution;
import org.camunda.bpm.engine.runtime.CaseInstance;
import org.camunda.bpm.model.cmmn.CmmnModelInstance;
import org.camunda.bpm.model.cmmn.instance.CmmnElement;
import org.camunda.bpm.model.xml.instance.ModelElementInstance;
import org.camunda.bpm.model.xml.type.ModelElementType;

/**
* @author Roman Smirnov
*
*/
public class CaseExecutionEntity extends CmmnExecution implements CaseExecution, CaseInstance, DbEntity, HasDbRevision, HasDbReferences {

  private static final long serialVersionUID = 1L;

  // current position /////////////////////////////////////////////////////////

  /** the case instance.  this is the root of the execution tree.
   * the caseInstance of a case instance is a self reference. */
  protected transient CaseExecutionEntity caseInstance;

  /** the parent execution */
  protected transient CaseExecutionEntity parent;

  /** nested executions */
  protected List<CaseExecutionEntity> caseExecutions;

  /** nested case sentry parts */
  protected List<CaseSentryPartEntity> caseSentryParts;
  protected Map<String, List<CmmnSentryPart>> sentries;

  /** reference to a sub process instance, not-null if currently subprocess is started from this execution */
  protected transient ExecutionEntity subProcessInstance;

  protected transient CaseExecutionEntity subCaseInstance;

  protected transient CaseExecutionEntity superCaseExecution;

  // associated entities /////////////////////////////////////////////////////

  protected CaseExecutionEntityVariableStore variableStore = new CaseExecutionEntityVariableStore(this);

  // Persistence //////////////////////////////////////////////////////////////

  protected int revision = 1;
  protected String caseDefinitionId;
  protected String activityId;
  protected String activityName;
  protected String caseInstanceId;
  protected String parentId;
  protected String superCaseExecutionId;

  // case definition ///////////////////////////////////////////////////////////

  public String getCaseDefinitionId() {
    return caseDefinitionId;
  }

  /** ensures initialization and returns the case definition. */
  public CmmnCaseDefinition getCaseDefinition() {
    ensureCaseDefinitionInitialized();
    return caseDefinition;
  }

  public void setCaseDefinition(CmmnCaseDefinition caseDefinition) {
    super.setCaseDefinition(caseDefinition);

    caseDefinitionId = null;
    if (caseDefinition != null) {
      caseDefinitionId = caseDefinition.getId();
    }

  }

  protected void ensureCaseDefinitionInitialized() {
    if ((caseDefinition == null) && (caseDefinitionId != null)) {

      CaseDefinitionEntity deployedCaseDefinition = Context
        .getProcessEngineConfiguration()
        .getDeploymentCache()
        .getCaseDefinitionById(caseDefinitionId);

      setCaseDefinition(deployedCaseDefinition);
    }
  }

  // parent ////////////////////////////////////////////////////////////////////

  public CaseExecutionEntity getParent() {
    ensureParentInitialized();
    return parent;
  }

  public void setParent(CmmnExecution parent) {
    this.parent = (CaseExecutionEntity) parent;

    if (parent != null) {
      this.parentId = parent.getId();
    } else {
      this.parentId = null;
    }
  }

  protected void ensureParentInitialized() {
    if (parent == null && parentId != null) {
      if(isExecutionTreePrefetchEnabled()) {
        ensureCaseExecutionTreeInitialized();

      } else {
        parent = Context
            .getCommandContext()
            .getCaseExecutionManager()
            .findCaseExecutionById(parentId);

      }
    }
  }

  /**
   * @see ExecutionEntity#ensureExecutionTreeInitialized
   */
  protected void ensureCaseExecutionTreeInitialized() {
    List<CaseExecutionEntity> executions = Context.getCommandContext()
      .getCaseExecutionManager()
      .findChildCaseExecutionsByCaseInstanceId(caseInstanceId);

    CaseExecutionEntity caseInstance = null;

    Map<String, CaseExecutionEntity> executionMap = new HashMap<String, CaseExecutionEntity>();
    for (CaseExecutionEntity execution : executions) {
      execution.caseExecutions = new ArrayList<CaseExecutionEntity>();
      executionMap.put(execution.getId(), execution);
      if(execution.isCaseInstanceExecution()) {
        caseInstance = execution;
      }
    }

    for (CaseExecutionEntity execution : executions) {
      String parentId = execution.getParentId();
      CaseExecutionEntity parent = executionMap.get(parentId);
      if(!execution.isCaseInstanceExecution()) {
        execution.caseInstance = caseInstance;
        execution.parent = parent;
        parent.caseExecutions.add(execution);
      } else {
        execution.caseInstance = execution;
      }
    }
  }

  /**
   * @return true if execution tree prefetching is enabled
   */
  protected boolean isExecutionTreePrefetchEnabled() {
    return Context.getProcessEngineConfiguration()
      .isExecutionTreePrefetchEnabled();
  }

  public String getParentId() {
    return parentId;
  }

  // activity //////////////////////////////////////////////////////////////////

  public String getActivityId() {
    return activityId;
  }

  public String getActivityName() {
    return activityName;
  }

  public CmmnActivity getActivity() {
    ensureActivityInitialized();
    return super.getActivity();
  }

  public void setActivity(CmmnActivity activity) {
    super.setActivity(activity);
    if (activity != null) {
      this.activityId = activity.getId();
      this.activityName = activity.getName();
    } else {
      this.activityId = null;
      this.activityName = null;
    }
  }

  protected void ensureActivityInitialized() {
    if ((activity == null) && (activityId != null)) {
      setActivity(getCaseDefinition().findActivity(activityId));
    }
  }

  // case executions ////////////////////////////////////////////////////////////////

  public List<CaseExecutionEntity> getCaseExecutions() {
    return new ArrayList<CaseExecutionEntity>(getCaseExecutionsInternal());
  }

  protected List<CaseExecutionEntity> getCaseExecutionsInternal() {
    ensureCaseExecutionsInitialized();
    return caseExecutions;
  }

  protected void ensureCaseExecutionsInitialized() {
    if (caseExecutions == null) {
      this.caseExecutions = Context
        .getCommandContext()
        .getCaseExecutionManager()
        .findChildCaseExecutionsByParentCaseExecutionId(id);
    }
  }

  // task ///////////////////////////////////////////////////////////////////

  public TaskEntity getTask() {
    ensureTaskInitialized();
    return task;
  }

  protected void ensureTaskInitialized() {
    if (task == null) {
      task = Context
        .getCommandContext()
        .getTaskManager()
        .findTaskByCaseExecutionId(id);
    }
  }

  public TaskEntity createTask(TaskDecorator taskDecorator) {
    TaskEntity task = super.createTask(taskDecorator);
    fireHistoricCaseActivityInstanceUpdate();
    return task;
  }

  // case instance /////////////////////////////////////////////////////////

  public String getCaseInstanceId() {
    return caseInstanceId;
  }

  public CaseExecutionEntity getCaseInstance() {
    ensureCaseInstanceInitialized();
    return caseInstance;
  }

  public void setCaseInstance(CmmnExecution caseInstance) {
    this.caseInstance = (CaseExecutionEntity) caseInstance;

    if (caseInstance != null) {
      this.caseInstanceId = this.caseInstance.getId();
    }
  }

  protected void ensureCaseInstanceInitialized() {
    if ((caseInstance == null) && (caseInstanceId != null)) {

      caseInstance =  Context
        .getCommandContext()
        .getCaseExecutionManager()
        .findCaseExecutionById(caseInstanceId);

    }
  }

  @Override
  public boolean isCaseInstanceExecution() {
    return parentId == null;
  }

  protected CaseExecutionEntity createCaseExecution(CmmnActivity activity) {
    CaseExecutionEntity child = newCaseExecution();

    // set activity to execute
    child.setActivity(activity);

    // handle child/parent-relation
    child.setParent(this);
    getCaseExecutionsInternal().add(child);

    // set case instance
    child.setCaseInstance(getCaseInstance());

    // set case definition
    child.setCaseDefinition(getCaseDefinition());

    return child;
  }

  protected CaseExecutionEntity newCaseExecution() {
    CaseExecutionEntity newCaseExecution = new CaseExecutionEntity();

    Context
      .getCommandContext()
      .getCaseExecutionManager()
      .insertCaseExecution(newCaseExecution);

    return newCaseExecution;
  }

  // sub process instance ///////////////////////////////////////////////////

  public ExecutionEntity getSubProcessInstance() {
    ensureSubProcessInstanceInitialized();
    return subProcessInstance;
  }

  public void setSubProcessInstance(PvmExecutionImpl subProcessInstance) {
    this.subProcessInstance = (ExecutionEntity) subProcessInstance;
  }

  public ExecutionEntity createSubProcessInstance(PvmProcessDefinition processDefinition) {
    return createSubProcessInstance(processDefinition, null);
  }

  public ExecutionEntity createSubProcessInstance(PvmProcessDefinition processDefinition, String businessKey) {
    return createSubProcessInstance(processDefinition, businessKey, getCaseInstanceId());
  }

  public ExecutionEntity createSubProcessInstance(PvmProcessDefinition processDefinition, String businessKey, String caseInstanceId) {
    ExecutionEntity subProcessInstance = (ExecutionEntity) processDefinition.createProcessInstance(businessKey, caseInstanceId);

    // manage bidirectional super-subprocess relation
    subProcessInstance.setSuperCaseExecution(this);
    setSubProcessInstance(subProcessInstance);

    fireHistoricCaseActivityInstanceUpdate();

    return subProcessInstance;
  }

  protected void ensureSubProcessInstanceInitialized() {
    if (subProcessInstance == null) {
      subProcessInstance = Context
        .getCommandContext()
        .getExecutionManager()
        .findSubProcessInstanceBySuperCaseExecutionId(id);
    }
  }

  // sub-/super- case instance ////////////////////////////////////////////////////

  public CaseExecutionEntity getSubCaseInstance() {
    ensureSubCaseInstanceInitialized();
    return subCaseInstance;
  }

  public void setSubCaseInstance(CmmnExecution subCaseInstance) {
    this.subCaseInstance = (CaseExecutionEntity) subCaseInstance;
  }

  public CaseExecutionEntity createSubCaseInstance(CmmnCaseDefinition caseDefinition) {
    return createSubCaseInstance(caseDefinition, null);
  }

  public CaseExecutionEntity createSubCaseInstance(CmmnCaseDefinition caseDefinition, String businessKey) {
    CaseExecutionEntity subCaseInstance = (CaseExecutionEntity) caseDefinition.createCaseInstance(businessKey);

    // manage bidirectional super-sub-case-instances relation
    subCaseInstance.setSuperCaseExecution(this);
    setSubCaseInstance(subCaseInstance);

    fireHistoricCaseActivityInstanceUpdate();

    return subCaseInstance;
  }

  public void fireHistoricCaseActivityInstanceUpdate() {
    ProcessEngineConfigurationImpl configuration = Context.getProcessEngineConfiguration();
    HistoryLevel historyLevel = configuration.getHistoryLevel();
    if (historyLevel.isHistoryEventProduced(HistoryEventTypes.CASE_ACTIVITY_INSTANCE_UPDATE, this)) {
      CmmnHistoryEventProducer eventProducer = configuration.getCmmnHistoryEventProducer();
      HistoryEventHandler eventHandler = configuration.getHistoryEventHandler();

      HistoryEvent event = eventProducer.createCaseActivityInstanceUpdateEvt(this);
      eventHandler.handleEvent(event);
    }
  }

  protected void ensureSubCaseInstanceInitialized() {
    if (subCaseInstance == null) {
      subCaseInstance = Context
        .getCommandContext()
        .getCaseExecutionManager()
        .findSubCaseInstanceBySuperCaseExecutionId(id);
    }
  }

  public String getSuperCaseExecutionId() {
    return superCaseExecutionId;
  }

  public void setSuperCaseExecutionId(String superCaseExecutionId) {
    this.superCaseExecutionId = superCaseExecutionId;
  }

  public CmmnExecution getSuperCaseExecution() {
    ensureSuperCaseExecutionInitialized();
    return superCaseExecution;
  }

  public void setSuperCaseExecution(CmmnExecution superCaseExecution) {
    this.superCaseExecution = (CaseExecutionEntity) superCaseExecution;

    if (superCaseExecution != null) {
      this.superCaseExecutionId = superCaseExecution.getId();
    } else {
      this.superCaseExecutionId = null;
    }
  }

  protected void ensureSuperCaseExecutionInitialized() {
    if (superCaseExecution == null && superCaseExecutionId != null) {
      superCaseExecution = Context
        .getCommandContext()
        .getCaseExecutionManager()
        .findCaseExecutionById(superCaseExecutionId);
    }
  }

  // sentry /////////////////////////////////////////////////////////////////////////

  public List<CaseSentryPartEntity> getCaseSentryParts() {
    ensureCaseSentryPartsInitialized();
    return caseSentryParts;
  }

  protected void ensureCaseSentryPartsInitialized() {
    if (caseSentryParts == null) {

      caseSentryParts = Context
        .getCommandContext()
        .getCaseSentryPartManager()
        .findCaseSentryPartsByCaseExecutionId(id);

      // create a map sentries: sentryId -> caseSentryParts
      // for simple select to get all parts for one sentry
      sentries = new HashMap<String, List<CmmnSentryPart>>();

      for (CaseSentryPartEntity sentryPart : caseSentryParts) {

        String sentryId = sentryPart.getSentryId();
        List<CmmnSentryPart> parts = sentries.get(sentryId);

        if (parts == null) {
          parts = new ArrayList<CmmnSentryPart>();
          sentries.put(sentryId, parts);
        }

        parts.add(sentryPart);
      }
    }
  }

  protected void addSentryPart(CmmnSentryPart sentryPart) {
    CaseSentryPartEntity entity = (CaseSentryPartEntity) sentryPart;

    getCaseSentryParts().add(entity);

    String sentryId = sentryPart.getSentryId();
    List<CmmnSentryPart> parts = sentries.get(sentryId);

    if (parts == null) {
      parts = new ArrayList<CmmnSentryPart>();
      sentries.put(sentryId, parts);
    }

    parts.add(entity);
  }

  protected Map<String, List<CmmnSentryPart>> getSentries() {
    ensureCaseSentryPartsInitialized();
    return sentries;
  }

  protected List<CmmnSentryPart> findSentry(String sentryId) {
    ensureCaseSentryPartsInitialized();
    return sentries.get(sentryId);
  }

  protected CaseSentryPartEntity newSentryPart() {
    CaseSentryPartEntity caseSentryPart = new CaseSentryPartEntity();

    Context
      .getCommandContext()
      .getCaseSentryPartManager()
      .insertCaseSentryPart(caseSentryPart);

    return caseSentryPart;
  }

  // variables //////////////////////////////////////////////////////////////

  protected CoreVariableStore getVariableStore() {
    return variableStore;
  }

  protected void initializeVariableInstanceBackPointer(VariableInstanceEntity variableInstance) {
    variableInstance.setCaseInstanceId(caseInstanceId);
    variableInstance.setCaseExecutionId(id);
  }

  protected List<VariableInstanceEntity> loadVariableInstances() {
    return Context
        .getCommandContext()
        .getVariableInstanceManager()
        .findVariableInstancesByCaseExecutionId(id);
  }

  // toString /////////////////////////////////////////////////////////////

  public String toString() {
    if (isCaseInstanceExecution()) {
      return "CaseInstance["+getToStringIdentity()+"]";
    } else {
      return "CaseExecution["+getToStringIdentity()+"]";
    }
  }

  protected String getToStringIdentity() {
    return id;
  }

  // delete/remove ///////////////////////////////////////////////////////

  public void remove() {
    super.remove();

    variableStore.removeVariablesWithoutFiringEvents();

    CommandContext commandContext = Context.getCommandContext();

    for (CaseSentryPartEntity sentryPart : getCaseSentryParts()) {
      commandContext
        .getCaseSentryPartManager()
        .deleteSentryPart(sentryPart);
    }

    // finally delete this execution
    commandContext
      .getCaseExecutionManager()
      .deleteCaseExecution(this);
  }

  // persistence /////////////////////////////////////////////////////////

  public int getRevision() {
    return revision;
  }

  public void setRevision(int revision) {
    this.revision = revision;
  }

  public int getRevisionNext() {
    return revision + 1;
  }

  public void forceUpdate() {
    Context.getCommandContext()
      .getDbEntityManager()
      .forceUpdate(this);
  }

  public boolean hasReferenceTo(DbEntity entity) {

    if (entity instanceof CaseExecutionEntity) {
      CaseExecutionEntity otherEntity = (CaseExecutionEntity) entity;
      String otherId = otherEntity.getId();

      // parentId
      if(parentId != null && parentId.equals(otherId)) {
        return true;
      }

      // superExecutionId
      if(superCaseExecutionId != null && superCaseExecutionId.equals(otherId)) {
        return true;
      }

    }
    return false;

  }

  public Object getPersistentState() {
    Map<String, Object> persistentState = new HashMap<String, Object>();
    persistentState.put("caseDefinitionId", caseDefinitionId);
    persistentState.put("businessKey", businessKey);
    persistentState.put("activityId", activityId);
    persistentState.put("parentId", parentId);
    persistentState.put("currentState", currentState);
    persistentState.put("previousState", previousState);
    return persistentState;
  }

  public CmmnModelInstance getCmmnModelInstance() {
    if(caseDefinitionId != null) {

      return Context.getProcessEngineConfiguration()
        .getDeploymentCache()
        .findCmmnModelInstanceForCaseDefinition(caseDefinitionId);

    } else {
      return null;

    }
  }

  public CmmnElement getCmmnModelElementInstance() {
    CmmnModelInstance cmmnModelInstance = getCmmnModelInstance();
    if(cmmnModelInstance != null) {

      ModelElementInstance modelElementInstance = cmmnModelInstance.getModelElementById(activityId);

      try {
        return (CmmnElement) modelElementInstance;

      } catch(ClassCastException e) {
        ModelElementType elementType = modelElementInstance.getElementType();
        throw new ProcessEngineException("Cannot cast "+modelElementInstance+" to CmmnElement. "
            + "Is of type "+elementType.getTypeName() + " Namespace "
            + elementType.getTypeNamespace(), e);
      }

    } else {
      return null;
    }
  }

  public ProcessEngineServices getProcessEngineServices() {
    return Context
        .getProcessEngineConfiguration()
        .getProcessEngine();
  }

  public <T extends CoreExecution> void performOperation(CoreAtomicOperation<T> operation) {
    Context.getCommandContext()
      .performOperation((CmmnAtomicOperation) operation, this);
  }

  public <T extends CoreExecution> void performOperationSync(CoreAtomicOperation<T> operation) {
    Context.getCommandContext()
      .performOperation((CmmnAtomicOperation) operation, this);
  }

}
TOP

Related Classes of org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.