Java Code Examples for org.activiti.engine.impl.context.Context#getProcessEngineConfiguration()

The following examples show how to use org.activiti.engine.impl.context.Context#getProcessEngineConfiguration() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ContinueProcessOperation.java    From activiti6-boot2 with Apache License 2.0 6 votes vote down vote up
protected void executeActivityBehavior(ActivityBehavior activityBehavior, FlowNode flowNode) {
  logger.debug("Executing activityBehavior {} on activity '{}' with execution {}", activityBehavior.getClass(), flowNode.getId(), execution.getId());

  if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
    Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
        ActivitiEventBuilder.createActivityEvent(ActivitiEventType.ACTIVITY_STARTED, flowNode.getId(), flowNode.getName(), execution.getId(),
            execution.getProcessInstanceId(), execution.getProcessDefinitionId(), flowNode));
  }

  try {
    activityBehavior.execute(execution);
  } catch (RuntimeException e) {
    if (LogMDC.isMDCEnabled()) {
      LogMDC.putMDCExecution(execution);
    }
    throw e;
  }
}
 
Example 2
Source File: CachingAndArtifactsManager.java    From activiti6-boot2 with Apache License 2.0 6 votes vote down vote up
/**
 * Ensures that the process definition is cached in the appropriate places, including the
 * deployment's collection of deployed artifacts and the deployment manager's cache, as well
 * as caching any ProcessDefinitionInfos.
 */
public void updateCachingAndArtifacts(ParsedDeployment parsedDeployment) {
  CommandContext commandContext = Context.getCommandContext();
  final ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();
  DeploymentCache<ProcessDefinitionCacheEntry> processDefinitionCache 
    = processEngineConfiguration.getDeploymentManager().getProcessDefinitionCache();
  DeploymentEntity deployment = parsedDeployment.getDeployment();

  for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
    BpmnModel bpmnModel = parsedDeployment.getBpmnModelForProcessDefinition(processDefinition);
    Process process = parsedDeployment.getProcessModelForProcessDefinition(processDefinition);
    ProcessDefinitionCacheEntry cacheEntry = new ProcessDefinitionCacheEntry(processDefinition, bpmnModel, process);
    processDefinitionCache.add(processDefinition.getId(), cacheEntry);
    addDefinitionInfoToCache(processDefinition, processEngineConfiguration, commandContext);
  
    // Add to deployment for further usage
    deployment.addDeployedArtifact(processDefinition);
  }
}
 
Example 3
Source File: ErrorPropagation.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
public static void propagateError(String errorCode, ActivityExecution execution) {

        while (execution != null) {
            String eventHandlerId = findLocalErrorEventHandler(execution, errorCode);
            if (eventHandlerId != null) {
                executeCatch(eventHandlerId, execution, errorCode);
                break;
            }

            if (execution.isProcessInstanceType()) {
                // dispatch process completed event
                if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
                    Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
                            ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT, execution));
                }
            }
            execution = getSuperExecution(execution);
        }
        if (execution == null) {
            throw new BpmnError(errorCode, "No catching boundary event found for error with errorCode '"
                    + errorCode + "', neither in same process nor in parent process");
        }
    }
 
Example 4
Source File: AtomicOperationProcessStart.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
@Override
protected void eventNotificationsCompleted(InterpretableExecution execution) {
    if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
        Map<String, Object> variablesMap = null;
        try {
            variablesMap = execution.getVariables();
        } catch (Throwable t) {
            // In some rare cases getting the execution variables can fail (JPA entity load failure for example)
            // We ignore the exception here, because it's only meant to include variables in the initialized event.
        }
        Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
                ActivitiEventBuilder.createEntityWithVariablesEvent(FlowableEngineEventType.ENTITY_INITIALIZED,
                        execution, variablesMap, false));
        Context.getProcessEngineConfiguration().getEventDispatcher()
                .dispatchEvent(ActivitiEventBuilder.createProcessStartedEvent(execution, variablesMap, false));
    }

    ProcessDefinitionImpl processDefinition = execution.getProcessDefinition();
    StartingExecution startingExecution = execution.getStartingExecution();
    List<ActivityImpl> initialActivityStack = processDefinition.getInitialActivityStack(startingExecution.getInitial());
    execution.setActivity(initialActivityStack.get(0));
    execution.performOperation(PROCESS_START_INITIAL);
}
 
Example 5
Source File: DefaultHistoryManager.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
@Override
public void recordProcessInstanceEnd(String processInstanceId, String deleteReason, String activityId) {

    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
        HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceManager()
                .findHistoricProcessInstance(processInstanceId);

        if (historicProcessInstance != null) {
            historicProcessInstance.markEnded(deleteReason);
            historicProcessInstance.setEndActivityId(activityId);

            // Fire event
            ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration();
            if (config != null && config.getEventDispatcher().isEnabled()) {
                config.getEventDispatcher().dispatchEvent(
                        ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.HISTORIC_PROCESS_INSTANCE_ENDED, historicProcessInstance));
            }
        }
    }
}
 
Example 6
Source File: DefaultHistoryManager.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
@Override
public void recordActivityStart(ExecutionEntity executionEntity) {
    if (isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
        if (executionEntity.getActivity() != null) {
            IdGenerator idGenerator = Context.getProcessEngineConfiguration().getIdGenerator();

            String processDefinitionId = executionEntity.getProcessDefinitionId();
            String processInstanceId = executionEntity.getProcessInstanceId();
            String executionId = executionEntity.getId();

            HistoricActivityInstanceEntity historicActivityInstance = new HistoricActivityInstanceEntity();
            historicActivityInstance.setId(idGenerator.getNextId());
            historicActivityInstance.setProcessDefinitionId(processDefinitionId);
            historicActivityInstance.setProcessInstanceId(processInstanceId);
            historicActivityInstance.setExecutionId(executionId);
            historicActivityInstance.setActivityId(executionEntity.getActivityId());
            historicActivityInstance.setActivityName((String) executionEntity.getActivity().getProperty("name"));
            historicActivityInstance.setActivityType((String) executionEntity.getActivity().getProperty("type"));
            historicActivityInstance.setStartTime(Context.getProcessEngineConfiguration().getClock().getCurrentTime());

            // Inherit tenant id (if applicable)
            if (executionEntity.getTenantId() != null) {
                historicActivityInstance.setTenantId(executionEntity.getTenantId());
            }

            getDbSqlSession().insert(historicActivityInstance);

            // Fire event
            ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration();
            if (config != null && config.getEventDispatcher().isEnabled()) {
                config.getEventDispatcher().dispatchEvent(
                        ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.HISTORIC_ACTIVITY_INSTANCE_CREATED, historicActivityInstance));
            }

        }
    }
}
 
Example 7
Source File: ExecutionEntityImpl.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
@Override
protected VariableInstanceEntity createVariableInstance(String variableName, Object value, ExecutionEntity sourceActivityExecution) {
  VariableInstanceEntity result = super.createVariableInstance(variableName, value, sourceActivityExecution);

  // Dispatch event, if needed
  if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
    Context
        .getProcessEngineConfiguration()
        .getEventDispatcher()
        .dispatchEvent(
            ActivitiEventBuilder.createVariableEvent(ActivitiEventType.VARIABLE_CREATED, variableName, value, result.getType(), result.getTaskId(), result.getExecutionId(), getProcessInstanceId(),
                getProcessDefinitionId()));
  }
  return result;
}
 
Example 8
Source File: ExecutionEntityImpl.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
@Override
protected void updateVariableInstance(VariableInstanceEntity variableInstance, Object value, ExecutionEntity sourceActivityExecution) {
  super.updateVariableInstance(variableInstance, value, sourceActivityExecution);

  // Dispatch event, if needed
  if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
    Context
        .getProcessEngineConfiguration()
        .getEventDispatcher()
        .dispatchEvent(
            ActivitiEventBuilder.createVariableEvent(ActivitiEventType.VARIABLE_UPDATED, variableInstance.getName(), value, variableInstance.getType(), variableInstance.getTaskId(),
                variableInstance.getExecutionId(), getProcessInstanceId(), getProcessDefinitionId()));
  }
}
 
Example 9
Source File: ExecutionEntity.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
@Override
public void remove() {
    ensureParentInitialized();
    if (parent != null) {
        parent.ensureExecutionsInitialized();
        parent.executions.remove(this);
    }

    // delete all the variable instances
    ensureVariableInstancesInitialized();
    deleteVariablesInstanceForLeavingScope();

    // delete all the tasks
    removeTasks(null);

    // remove all jobs
    removeJobs();

    // remove all event subscriptions for this scope, if the scope has event subscriptions:
    removeEventSubscriptions();

    // remove event scopes:
    removeEventScopes();

    // remove identity links
    removeIdentityLinks();

    if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
        Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
                ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, this));
    }

    // finally delete this execution
    Context.getCommandContext()
            .getDbSqlSession()
            .delete(this);
}
 
Example 10
Source File: ProcessDefinitionDiagramCmd.java    From lemon with Apache License 2.0 5 votes vote down vote up
public InputStream execute(CommandContext commandContext) {
    ProcessDefinitionEntity processDefinition = new GetDeploymentProcessDefinitionCmd(
            processDefinitionId).execute(commandContext);
    String diagramResourceName = processDefinition.getDiagramResourceName();
    String deploymentId = processDefinition.getDeploymentId();

    if (deploymentId != null) {
        byte[] bytes = commandContext
                .getResourceEntityManager()
                .findResourceByDeploymentIdAndResourceName(deploymentId,
                        diagramResourceName).getBytes();
        InputStream inputStream = new ByteArrayInputStream(bytes);

        return inputStream;
    }

    GetBpmnModelCmd getBpmnModelCmd = new GetBpmnModelCmd(
            processDefinitionId);
    BpmnModel bpmnModel = getBpmnModelCmd.execute(commandContext);
    ProcessEngineConfiguration processEngineConfiguration = Context
            .getProcessEngineConfiguration();
    InputStream is = new DefaultProcessDiagramGenerator().generateDiagram(
            bpmnModel, "png",
            processEngineConfiguration.getActivityFontName(),
            processEngineConfiguration.getLabelFontName(), null);

    return is;
}
 
Example 11
Source File: ProcessDefinitionUtil.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
public static BpmnModel getBpmnModel(String processDefinitionId) {
  if (Context.getProcessEngineConfiguration() == null) {
    return Activiti5Util.getActiviti5CompatibilityHandler().getProcessDefinitionBpmnModel(processDefinitionId);
    
  } else {
    DeploymentManager deploymentManager = Context.getProcessEngineConfiguration().getDeploymentManager();
    
    // This will check the cache in the findDeployedProcessDefinitionById and resolveProcessDefinition method
    ProcessDefinition processDefinitionEntity = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
    return deploymentManager.resolveProcessDefinition(processDefinitionEntity).getBpmnModel();
  }
}
 
Example 12
Source File: ReflectUtil.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
private static ClassLoader getCustomClassLoader() {
  ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();
  if (processEngineConfiguration != null) {
    final ClassLoader classLoader = processEngineConfiguration.getClassLoader();
    if (classLoader != null) {
      return classLoader;
    }
  }
  return null;
}
 
Example 13
Source File: UpdateProcessCmd.java    From lemon with Apache License 2.0 5 votes vote down vote up
public Void execute(CommandContext commandContext) {
    ProcessDefinitionEntity processDefinitionEntity = commandContext
            .getProcessDefinitionEntityManager().findProcessDefinitionById(
                    processDefinitionId);
    String resourceName = processDefinitionEntity.getResourceName();
    String deploymentId = processDefinitionEntity.getDeploymentId();
    JdbcTemplate jdbcTemplate = new JdbcTemplate(Context
            .getProcessEngineConfiguration().getDataSource());
    jdbcTemplate
            .update("update ACT_GE_BYTEARRAY set BYTES_=? where NAME_=? and DEPLOYMENT_ID_=?",
                    bytes, resourceName, deploymentId);

    Context.getProcessEngineConfiguration().getProcessDefinitionCache()
            .remove(processDefinitionId);

    try {
        // update png
        GetBpmnModelCmd getBpmnModelCmd = new GetBpmnModelCmd(
                processDefinitionId);
        BpmnModel bpmnModel = getBpmnModelCmd.execute(commandContext);
        ProcessEngineConfiguration processEngineConfiguration = Context
                .getProcessEngineConfiguration();
        ProcessDefinitionDiagramCmd processDefinitionDiagramCmd = new ProcessDefinitionDiagramCmd(
                processDefinitionEntity.getId());
        InputStream is = processDefinitionDiagramCmd
                .execute(commandContext);
        byte[] pngBytes = IOUtils.toByteArray(is);
        String diagramResourceName = processDefinitionEntity
                .getDiagramResourceName();
        jdbcTemplate
                .update("update ACT_GE_BYTEARRAY set BYTES_=? where NAME_=? and DEPLOYMENT_ID_=?",
                        pngBytes, diagramResourceName, deploymentId);
    } catch (Exception ex) {
        logger.error(ex.getMessage(), ex);
    }

    return null;
}
 
Example 14
Source File: DefaultHistoryManager.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
protected void endHistoricActivityInstance(HistoricActivityInstanceEntity historicActivityInstance) {
    historicActivityInstance.markEnded(null);

    // Fire event
    ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration();
    if (config != null && config.getEventDispatcher().isEnabled()) {
        config.getEventDispatcher().dispatchEvent(
                ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.HISTORIC_ACTIVITY_INSTANCE_ENDED, historicActivityInstance));
    }
}
 
Example 15
Source File: SecureJavascriptTaskActivityBehavior.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
@Override
public void execute(DelegateExecution execution) {
  ProcessEngineConfigurationImpl config = (ProcessEngineConfigurationImpl) Context.getProcessEngineConfiguration();

    if (Context.getProcessEngineConfiguration().isEnableProcessDefinitionInfoCache()) {
        ObjectNode taskElementProperties = Context.getBpmnOverrideElementProperties(scriptTaskId, execution.getProcessDefinitionId());
        if (taskElementProperties != null && taskElementProperties.has(DynamicBpmnConstants.SCRIPT_TASK_SCRIPT)) {
            String overrideScript = taskElementProperties.get(DynamicBpmnConstants.SCRIPT_TASK_SCRIPT).asText();
            if (StringUtils.isNotEmpty(overrideScript) && overrideScript.equals(script) == false) {
                script = overrideScript;
            }
        }
    }

  boolean noErrors = true;
  try {
	Object result = SecureJavascriptUtil.evaluateScript(execution, script, config.getBeans());
    if (resultVariable != null) {
      execution.setVariable(resultVariable, result);
    }

  } catch (ActivitiException e) {

    LOGGER.warn("Exception while executing " + execution.getCurrentActivityId() + " : " + e.getMessage());

    noErrors = false;
    Throwable rootCause = ExceptionUtils.getRootCause(e);
    if (rootCause instanceof BpmnError) {
      ErrorPropagation.propagateError((BpmnError) rootCause, execution);
    } else {
      throw e;
    }
  }

  if (noErrors) {
    leave(execution);
  }
}
 
Example 16
Source File: ContinueMultiInstanceOperation.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
protected void executeSynchronous(FlowNode flowNode) {
  
  // Execution listener
  if (CollectionUtil.isNotEmpty(flowNode.getExecutionListeners())) {
    executeExecutionListeners(flowNode, ExecutionListener.EVENTNAME_START);
  }
  
  commandContext.getHistoryManager().recordActivityStart(execution);
  
  // Execute actual behavior
  ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior();
  if (activityBehavior != null) {
    logger.debug("Executing activityBehavior {} on activity '{}' with execution {}", activityBehavior.getClass(), flowNode.getId(), execution.getId());
    
    if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
      Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
          ActivitiEventBuilder.createActivityEvent(ActivitiEventType.ACTIVITY_STARTED, flowNode.getId(), flowNode.getName(), execution.getId(),
              execution.getProcessInstanceId(), execution.getProcessDefinitionId(), flowNode));
    }
    
    try {
      activityBehavior.execute(execution);
    } catch (BpmnError error) {
      // re-throw business fault so that it can be caught by an Error Intermediate Event or Error Event Sub-Process in the process
      ErrorPropagation.propagateError(error, execution);
    } catch (RuntimeException e) {
      if (LogMDC.isMDCEnabled()) {
        LogMDC.putMDCExecution(execution);
      }
      throw e;
    }
  } else {
    logger.debug("No activityBehavior on activity '{}' with execution {}", flowNode.getId(), execution.getId());
  }
}
 
Example 17
Source File: AbstractManager.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
protected ProcessEngineConfigurationImpl getProcessEngineConfiguration() {
    return Context.getProcessEngineConfiguration();
}
 
Example 18
Source File: ReflectUtil.java    From activiti6-boot2 with Apache License 2.0 4 votes vote down vote up
private static Class loadClass(ClassLoader classLoader, String className) throws ClassNotFoundException {
  ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();
  boolean useClassForName = processEngineConfiguration == null || processEngineConfiguration.isUseClassForNameClassLoading();
  return useClassForName ? Class.forName(className, true, classLoader) : classLoader.loadClass(className);
}
 
Example 19
Source File: ErrorPropagation.java    From activiti6-boot2 with Apache License 2.0 4 votes vote down vote up
protected static void executeEventHandler(Event event, ExecutionEntity parentExecution, ExecutionEntity currentExecution, String errorId) {
  if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
    BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(parentExecution.getProcessDefinitionId());
    if (bpmnModel != null) {

      String errorCode = bpmnModel.getErrors().get(errorId);
      if (errorCode == null) {
        errorCode = errorId;
      }

      Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
        ActivitiEventBuilder.createErrorEvent(ActivitiEventType.ACTIVITY_ERROR_RECEIVED, event.getId(), errorId, errorCode, parentExecution.getId(),
            parentExecution.getProcessInstanceId(), parentExecution.getProcessDefinitionId()));
    }
  }

  if (event instanceof StartEvent) {
    ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();

    if (currentExecution.getParentId().equals(parentExecution.getId()) == false) {
      Context.getAgenda().planDestroyScopeOperation(currentExecution);
    } else {
      executionEntityManager.deleteExecutionAndRelatedData(currentExecution, null, false);
    }

    ExecutionEntity eventSubProcessExecution = executionEntityManager.createChildExecution(parentExecution);
    eventSubProcessExecution.setCurrentFlowElement(event);
    Context.getAgenda().planContinueProcessOperation(eventSubProcessExecution);

  } else {
    ExecutionEntity boundaryExecution = null;
    List<? extends ExecutionEntity> childExecutions = parentExecution.getExecutions();
    for (ExecutionEntity childExecution : childExecutions) {
      if (childExecution.getActivityId().equals(event.getId())) {
        boundaryExecution = childExecution;
      }
    }

    Context.getAgenda().planTriggerExecutionOperation(boundaryExecution);
  }
}
 
Example 20
Source File: ExclusiveGatewayActivityBehavior.java    From activiti6-boot2 with Apache License 2.0 4 votes vote down vote up
/**
 * The default behaviour of BPMN, taking every outgoing sequence flow (where the condition evaluates to true), is not valid for an exclusive gateway.
 * 
 * Hence, this behaviour is overridden and replaced by the correct behavior: selecting the first sequence flow which condition evaluates to true (or which hasn't got a condition) and leaving the
 * activity through that sequence flow.
 * 
 * If no sequence flow is selected (ie all conditions evaluate to false), then the default sequence flow is taken (if defined).
 */
@Override
public void leave(DelegateExecution execution) {

  if (log.isDebugEnabled()) {
    log.debug("Leaving exclusive gateway '{}'", execution.getCurrentActivityId());
  }

  ExclusiveGateway exclusiveGateway = (ExclusiveGateway) execution.getCurrentFlowElement();
  
  if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
    Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
        ActivitiEventBuilder.createActivityEvent(ActivitiEventType.ACTIVITY_COMPLETED, exclusiveGateway.getId(), exclusiveGateway.getName(), execution.getId(),
            execution.getProcessInstanceId(), execution.getProcessDefinitionId(), exclusiveGateway));
  }

  SequenceFlow outgoingSequenceFlow = null;
  SequenceFlow defaultSequenceFlow = null;
  String defaultSequenceFlowId = exclusiveGateway.getDefaultFlow();

  // Determine sequence flow to take
  Iterator<SequenceFlow> sequenceFlowIterator = exclusiveGateway.getOutgoingFlows().iterator();
  while (outgoingSequenceFlow == null && sequenceFlowIterator.hasNext()) {
    SequenceFlow sequenceFlow = sequenceFlowIterator.next();
    
    String skipExpressionString = sequenceFlow.getSkipExpression();
    if (!SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpressionString)) {
      boolean conditionEvaluatesToTrue = ConditionUtil.hasTrueCondition(sequenceFlow, execution);
      if (conditionEvaluatesToTrue && (defaultSequenceFlowId == null || !defaultSequenceFlowId.equals(sequenceFlow.getId()))) {
        if (log.isDebugEnabled()) {
          log.debug("Sequence flow '{}'selected as outgoing sequence flow.", sequenceFlow.getId());
        }
        outgoingSequenceFlow = sequenceFlow;
      }
    } else if (SkipExpressionUtil.shouldSkipFlowElement(Context.getCommandContext(), execution, skipExpressionString)) {
      outgoingSequenceFlow = sequenceFlow;
    }

    // Already store it, if we would need it later. Saves one for loop.
    if (defaultSequenceFlowId != null && defaultSequenceFlowId.equals(sequenceFlow.getId())) {
      defaultSequenceFlow = sequenceFlow;
    }
    
  }
  
  // We have to record the end here, or else we're already past it
  Context.getCommandContext().getHistoryManager().recordActivityEnd((ExecutionEntity) execution, null);

  // Leave the gateway
  if (outgoingSequenceFlow != null) {
    execution.setCurrentFlowElement(outgoingSequenceFlow);
  } else {
    if (defaultSequenceFlow != null) {
      execution.setCurrentFlowElement(defaultSequenceFlow);
    } else {

      // No sequence flow could be found, not even a default one
      throw new ActivitiException("No outgoing sequence flow of the exclusive gateway '" + exclusiveGateway.getId() + "' could be selected for continuing the process");
    }
  }

  super.leave(execution);
}