Java Code Examples for org.activiti.engine.delegate.DelegateExecution#getCurrentFlowElement()

The following examples show how to use org.activiti.engine.delegate.DelegateExecution#getCurrentFlowElement() . 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
@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
  ExecutionEntity executionEntity = (ExecutionEntity) execution;
  BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();

  if (boundaryEvent.isCancelActivity()) {
    String eventName = null;
    if (signal != null) {
      eventName = signal.getName();
    } else {
      eventName = signalEventDefinition.getSignalRef();
    }

    EventSubscriptionEntityManager eventSubscriptionEntityManager = Context.getCommandContext().getEventSubscriptionEntityManager();
    List<EventSubscriptionEntity> eventSubscriptions = executionEntity.getEventSubscriptions();
    for (EventSubscriptionEntity eventSubscription : eventSubscriptions) {
      if (eventSubscription instanceof SignalEventSubscriptionEntity && eventSubscription.getEventName().equals(eventName)) {

        eventSubscriptionEntityManager.delete(eventSubscription);
      }
    }
  }

  super.trigger(executionEntity, triggerName, triggerData);
}
 
Example 2
protected DelegateExecution findMultiInstanceParentExecution(DelegateExecution execution) {
  DelegateExecution multiInstanceExecution = null;
  DelegateExecution parentExecution = execution.getParent();
  if (parentExecution != null && parentExecution.getCurrentFlowElement() != null) {
    FlowElement flowElement = parentExecution.getCurrentFlowElement();
    if (flowElement instanceof Activity) {
      Activity activity = (Activity) flowElement;
      if (activity.getLoopCharacteristics() != null) {
        multiInstanceExecution = parentExecution;
      }
    }

    if (multiInstanceExecution == null) {
      DelegateExecution potentialMultiInstanceExecution = findMultiInstanceParentExecution(parentExecution);
      if (potentialMultiInstanceExecution != null) {
        multiInstanceExecution = potentialMultiInstanceExecution;
      }
    }
  }

  return multiInstanceExecution;
}
 
Example 3
@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
  ExecutionEntity executionEntity = (ExecutionEntity) execution;
  BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();

  if (boundaryEvent.isCancelActivity()) {
    EventSubscriptionEntityManager eventSubscriptionEntityManager = Context.getCommandContext().getEventSubscriptionEntityManager();
    List<EventSubscriptionEntity> eventSubscriptions = executionEntity.getEventSubscriptions();
    for (EventSubscriptionEntity eventSubscription : eventSubscriptions) {
      if (eventSubscription instanceof CompensateEventSubscriptionEntity && eventSubscription.getActivityId().equals(compensateEventDefinition.getActivityRef())) {
        eventSubscriptionEntityManager.delete(eventSubscription);
      }
    }
  }

  super.trigger(executionEntity, triggerName, triggerData);
}
 
Example 4
@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
  ExecutionEntity executionEntity = (ExecutionEntity) execution;
  BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();

  if (boundaryEvent.isCancelActivity()) {
    EventSubscriptionEntityManager eventSubscriptionEntityManager = Context.getCommandContext().getEventSubscriptionEntityManager();
    List<EventSubscriptionEntity> eventSubscriptions = executionEntity.getEventSubscriptions();
    for (EventSubscriptionEntity eventSubscription : eventSubscriptions) {
      if (eventSubscription instanceof MessageEventSubscriptionEntity && eventSubscription.getEventName().equals(messageEventDefinition.getMessageRef())) {

        eventSubscriptionEntityManager.delete(eventSubscription);
      }
    }
  }

  super.trigger(executionEntity, triggerName, triggerData);
}
 
Example 5
protected EventGateway getPrecedingEventBasedGateway(DelegateExecution execution) {
  FlowElement currentFlowElement = execution.getCurrentFlowElement();
  if (currentFlowElement instanceof IntermediateCatchEvent) {
    IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) currentFlowElement;
    List<SequenceFlow> incomingSequenceFlow = intermediateCatchEvent.getIncomingFlows();
    
    // If behind an event based gateway, there is only one incoming sequence flow that originates from said gateway
    if (incomingSequenceFlow != null && incomingSequenceFlow.size() == 1) {
      SequenceFlow sequenceFlow = incomingSequenceFlow.get(0);
      FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement();
      if (sourceFlowElement instanceof EventGateway) {
        return (EventGateway) sourceFlowElement;
      }
    }
    
  }
  return null;
}
 
Example 6
protected void dispatchExecutionCancelled(DelegateExecution execution, FlowElement terminateEndEvent) {

    ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();

    // subprocesses
    for (DelegateExecution subExecution : executionEntityManager.findChildExecutionsByParentExecutionId(execution.getId())) {
      dispatchExecutionCancelled(subExecution, terminateEndEvent);
    }

    // call activities
    ExecutionEntity subProcessInstance = Context.getCommandContext().getExecutionEntityManager().findSubProcessInstanceBySuperExecutionId(execution.getId());
    if (subProcessInstance != null) {
      dispatchExecutionCancelled(subProcessInstance, terminateEndEvent);
    }

    // activity with message/signal boundary events
    FlowElement currentFlowElement = execution.getCurrentFlowElement();
    if (currentFlowElement instanceof FlowNode) {
      dispatchActivityCancelled(execution, terminateEndEvent);
    }
  }
 
Example 7
public void execute(DelegateExecution execution) {
  StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
  EventSubProcess eventSubProcess = (EventSubProcess) startEvent.getSubProcess();
  execution.setCurrentFlowElement(eventSubProcess);
  execution.setScope(true);

  // initialize the template-defined data objects as variables
  Map<String, Object> dataObjectVars = processDataObjects(eventSubProcess.getDataObjects());
  if (dataObjectVars != null) {
    execution.setVariablesLocal(dataObjectVars);
  }

  ExecutionEntity startSubProcessExecution = Context.getCommandContext()
      .getExecutionEntityManager().createChildExecution((ExecutionEntity) execution);
  startSubProcessExecution.setCurrentFlowElement(startEvent);
  Context.getAgenda().planTakeOutgoingSequenceFlowsOperation(startSubProcessExecution, true);
}
 
Example 8
protected void planTransactionDependentExecutionListener(ListenerFactory listenerFactory, DelegateExecution execution, TransactionDependentExecutionListener executionListener, ActivitiListener activitiListener) {
  Map<String, Object> executionVariablesToUse = execution.getVariables();
  CustomPropertiesResolver customPropertiesResolver = createCustomPropertiesResolver(activitiListener);
  Map<String, Object> customPropertiesMapToUse = invokeCustomPropertiesResolver(execution, customPropertiesResolver);

  TransactionDependentExecutionListenerExecutionScope scope = new TransactionDependentExecutionListenerExecutionScope(
      execution.getProcessInstanceId(), execution.getId(), execution.getCurrentFlowElement(), executionVariablesToUse, customPropertiesMapToUse);
  
  addTransactionListener(activitiListener, new ExecuteExecutionListenerTransactionListener(executionListener, scope));
}
 
Example 9
protected void planTransactionDependentTaskListener(DelegateExecution execution, TransactionDependentTaskListener taskListener, ActivitiListener activitiListener) {
  Map<String, Object> executionVariablesToUse = execution.getVariables();
  CustomPropertiesResolver customPropertiesResolver = createCustomPropertiesResolver(activitiListener);
  Map<String, Object> customPropertiesMapToUse = invokeCustomPropertiesResolver(execution, customPropertiesResolver);
  
  TransactionDependentTaskListenerExecutionScope scope = new TransactionDependentTaskListenerExecutionScope(
      execution.getProcessInstanceId(), execution.getId(), (Task) execution.getCurrentFlowElement(), executionVariablesToUse, customPropertiesMapToUse);
  addTransactionListener(activitiListener, new ExecuteTaskListenerTransactionListener(taskListener, scope));
}
 
Example 10
@Override
public void execute(DelegateExecution execution) {

  ExecutionEntity executionEntity = (ExecutionEntity) execution;
  if (!(execution.getCurrentFlowElement() instanceof BoundaryEvent)) {
    throw new ActivitiException("Programmatic error: " + this.getClass() + " should not be used for anything else than a boundary event");
  }

  JobManager jobManager = Context.getCommandContext().getJobManager();
  TimerJobEntity timerJob = jobManager.createTimerJob(timerEventDefinition, interrupting, executionEntity, TriggerTimerEventJobHandler.TYPE, 
      TimerEventHandler.createConfiguration(execution.getCurrentActivityId(), timerEventDefinition.getEndDate(), timerEventDefinition.getCalendarName()));
  if (timerJob != null) {
    jobManager.scheduleTimerJob(timerJob);
  }
}
 
Example 11
protected void deleteOtherEventsRelatedToEventBasedGateway(DelegateExecution execution, EventGateway eventGateway) {
  
  // To clean up the other events behind the event based gateway, we must gather the 
  // activity ids of said events and check the _sibling_ executions of the incoming execution.
  // Note that it can happen that there are multiple such execution in those activity ids,
  // (for example a parallel gw going twice to the event based gateway, kinda silly, but valid)
  // so we only take _one_ result of such a query for deletion.
  
  // Gather all activity ids for the events after the event based gateway that need to be destroyed
  List<SequenceFlow> outgoingSequenceFlows = eventGateway.getOutgoingFlows();
  Set<String> eventActivityIds = new HashSet<String>(outgoingSequenceFlows.size() - 1); // -1, the event being triggered does not need to be deleted
  for (SequenceFlow outgoingSequenceFlow : outgoingSequenceFlows) {
    if (outgoingSequenceFlow.getTargetFlowElement() != null
        && !outgoingSequenceFlow.getTargetFlowElement().getId().equals(execution.getCurrentActivityId())) {
      eventActivityIds.add(outgoingSequenceFlow.getTargetFlowElement().getId());
    }
  }
  
  CommandContext commandContext = Context.getCommandContext();
  ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
  
  // Find the executions
  List<ExecutionEntity> executionEntities = executionEntityManager
      .findExecutionsByParentExecutionAndActivityIds(execution.getParentId(), eventActivityIds);
  
  // Execute the cancel behaviour of the IntermediateCatchEvent
  for (ExecutionEntity executionEntity : executionEntities) {
    if (eventActivityIds.contains(executionEntity.getActivityId()) && execution.getCurrentFlowElement() instanceof IntermediateCatchEvent) {
      IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) execution.getCurrentFlowElement();
      if (intermediateCatchEvent.getBehavior() instanceof IntermediateCatchEventActivityBehavior) {
        ((IntermediateCatchEventActivityBehavior) intermediateCatchEvent.getBehavior()).eventCancelledByEventGateway(executionEntity);
        eventActivityIds.remove(executionEntity.getActivityId()); // We only need to delete ONE execution at the event.
      }
    }
  }
}
 
Example 12
/**
 * Subclasses that call leave() will first pass through this method, before the regular {@link FlowNodeActivityBehavior#leave(ActivityExecution)} is called. This way, we can check if the activity
 * has loop characteristics, and delegate to the behavior if this is the case.
 */
public void leave(DelegateExecution execution) {
  FlowElement currentFlowElement = execution.getCurrentFlowElement();
  Collection<BoundaryEvent> boundaryEvents = findBoundaryEventsForFlowNode(execution.getProcessDefinitionId(), currentFlowElement);
  if (CollectionUtil.isNotEmpty(boundaryEvents)) {
    executeCompensateBoundaryEvents(boundaryEvents, execution);
  }
  if (!hasLoopCharacteristics()) {
    super.leave(execution);
  } else if (hasMultiInstanceCharacteristics()) {
    multiInstanceActivityBehavior.leave(execution);
  }
}
 
Example 13
public void execute(DelegateExecution execution) {
  StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
  EventSubProcess eventSubProcess = (EventSubProcess) startEvent.getSubProcess();

  execution.setScope(true);

  // initialize the template-defined data objects as variables
  Map<String, Object> dataObjectVars = processDataObjects(eventSubProcess.getDataObjects());
  if (dataObjectVars != null) {
    execution.setVariablesLocal(dataObjectVars);
  }
}
 
Example 14
@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
  CommandContext commandContext = Context.getCommandContext();
  ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
  ExecutionEntity executionEntity = (ExecutionEntity) execution;
  
  StartEvent startEvent = (StartEvent) execution.getCurrentFlowElement();
  if (startEvent.isInterrupting()) {  
    List<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(executionEntity.getParentId());
    for (ExecutionEntity childExecution : childExecutions) {
      if (childExecution.getId().equals(executionEntity.getId()) == false) {
        executionEntityManager.deleteExecutionAndRelatedData(childExecution, 
            DeleteReason.EVENT_SUBPROCESS_INTERRUPTING + "(" + startEvent.getId() + ")", false);
      }
    }
  }
  
  EventSubscriptionEntityManager eventSubscriptionEntityManager = Context.getCommandContext().getEventSubscriptionEntityManager();
  List<EventSubscriptionEntity> eventSubscriptions = executionEntity.getEventSubscriptions();
  for (EventSubscriptionEntity eventSubscription : eventSubscriptions) {
    if (eventSubscription instanceof MessageEventSubscriptionEntity && eventSubscription.getEventName().equals(messageEventDefinition.getMessageRef())) {

      eventSubscriptionEntityManager.delete(eventSubscription);
    }
  }
  
  executionEntity.setCurrentFlowElement((SubProcess) executionEntity.getCurrentFlowElement().getParentContainer());
  executionEntity.setScope(true);
  
  ExecutionEntity outgoingFlowExecution = executionEntityManager.createChildExecution(executionEntity);
  outgoingFlowExecution.setCurrentFlowElement(startEvent);
  
  leave(outgoingFlowExecution);
}
 
Example 15
@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
  BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();
  
  CommandContext commandContext = Context.getCommandContext();
  ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
  
  ExecutionEntity subProcessExecution = null;
  // TODO: this can be optimized. A full search in the all executions shouldn't be needed
  List<ExecutionEntity> processInstanceExecutions = executionEntityManager.findChildExecutionsByProcessInstanceId(execution.getProcessInstanceId());
  for (ExecutionEntity childExecution : processInstanceExecutions) {
    if (childExecution.getCurrentFlowElement() != null 
        && childExecution.getCurrentFlowElement().getId().equals(boundaryEvent.getAttachedToRefId())) {
      subProcessExecution = childExecution;
      break;
    }
  }
  
  if (subProcessExecution == null) {
    throw new ActivitiException("No execution found for sub process of boundary cancel event " + boundaryEvent.getId());
  }
  
  EventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.getEventSubscriptionEntityManager();
  List<CompensateEventSubscriptionEntity> eventSubscriptions = eventSubscriptionEntityManager.findCompensateEventSubscriptionsByExecutionId(subProcessExecution.getParentId());

  if (eventSubscriptions.isEmpty()) {
    leave(execution);
  } else {
    
    String deleteReason = DeleteReason.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.getId() + ")";
    
    // cancel boundary is always sync
    ScopeUtil.throwCompensationEvent(eventSubscriptions, execution, false);
    executionEntityManager.deleteExecutionAndRelatedData(subProcessExecution, deleteReason, false);
    if (subProcessExecution.getCurrentFlowElement() instanceof Activity) {
      Activity activity = (Activity) subProcessExecution.getCurrentFlowElement();
      if (activity.getLoopCharacteristics() != null) {
        ExecutionEntity miExecution = subProcessExecution.getParent();
        List<ExecutionEntity> miChildExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(miExecution.getId());
        for (ExecutionEntity miChildExecution : miChildExecutions) {
          if (subProcessExecution.getId().equals(miChildExecution.getId()) == false && activity.getId().equals(miChildExecution.getCurrentActivityId())) {
            executionEntityManager.deleteExecutionAndRelatedData(miChildExecution, deleteReason, false);
          }
        }
      }
    }
    leave(execution);
  }
}
 
Example 16
@Override
public void execute(DelegateExecution execution) {
  ThrowEvent throwEvent = (ThrowEvent) execution.getCurrentFlowElement();
  
  /*
   * From the BPMN 2.0 spec:
   * 
   * The Activity to be compensated MAY be supplied.
   *  
   * If an Activity is not supplied, then the compensation is broadcast to all completed Activities in 
   * the current Sub- Process (if present), or the entire Process instance (if at the global level). This “throws” the compensation.
   */
  final String activityRef = compensateEventDefinition.getActivityRef();
  
  CommandContext commandContext = Context.getCommandContext();
  EventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.getEventSubscriptionEntityManager();
  
  List<CompensateEventSubscriptionEntity> eventSubscriptions = new ArrayList<CompensateEventSubscriptionEntity>();
  if (StringUtils.isNotEmpty(activityRef)) {
    
    // If an activity ref is provided, only that activity is compensated
    eventSubscriptions.addAll(eventSubscriptionEntityManager
        .findCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.getProcessInstanceId(), activityRef));
    
  } else {
    
    // If no activity ref is provided, it is broadcast to the current sub process / process instance
    Process process = ProcessDefinitionUtil.getProcess(execution.getProcessDefinitionId());
    
    FlowElementsContainer flowElementsContainer = null;
    if (throwEvent.getSubProcess() == null) {
      flowElementsContainer = process;
    } else {
      flowElementsContainer = throwEvent.getSubProcess();
    }
    
    for (FlowElement flowElement : flowElementsContainer.getFlowElements()) {
      if (flowElement instanceof Activity) {
        eventSubscriptions.addAll(eventSubscriptionEntityManager
            .findCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.getProcessInstanceId(), flowElement.getId()));
      }
    }
    
  }
  
  if (eventSubscriptions.isEmpty()) {
    leave(execution);
  } else {
    // TODO: implement async (waitForCompletion=false in bpmn)
    ScopeUtil.throwCompensationEvent(eventSubscriptions, execution, false);
    leave(execution);
  }
}
 
Example 17
public void execute(DelegateExecution execution) {

    // First off all, deactivate the execution
    execution.inactivate();

    // Join
    FlowElement flowElement = execution.getCurrentFlowElement();
    ParallelGateway parallelGateway = null;
    if (flowElement instanceof ParallelGateway) {
      parallelGateway = (ParallelGateway) flowElement;
    } else {
      throw new ActivitiException("Programmatic error: parallel gateway behaviour can only be applied" + " to a ParallelGateway instance, but got an instance of " + flowElement);
    }

    lockFirstParentScope(execution);

    DelegateExecution multiInstanceExecution = null;
    if (hasMultiInstanceParent(parallelGateway)) {
      multiInstanceExecution = findMultiInstanceParentExecution(execution);
    }

    ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
    Collection<ExecutionEntity> joinedExecutions = executionEntityManager.findInactiveExecutionsByActivityIdAndProcessInstanceId(execution.getCurrentActivityId(), execution.getProcessInstanceId());
    if (multiInstanceExecution != null) {
      joinedExecutions = cleanJoinedExecutions(joinedExecutions, multiInstanceExecution);
    }

    int nbrOfExecutionsToJoin = parallelGateway.getIncomingFlows().size();
    int nbrOfExecutionsCurrentlyJoined = joinedExecutions.size();

    // Fork

    // Is needed to set the endTime for all historic activity joins
    Context.getCommandContext().getHistoryManager().recordActivityEnd((ExecutionEntity) execution, null);

    if (nbrOfExecutionsCurrentlyJoined == nbrOfExecutionsToJoin) {

      // Fork
      if (log.isDebugEnabled()) {
        log.debug("parallel gateway '{}' activates: {} of {} joined", execution.getCurrentActivityId(), nbrOfExecutionsCurrentlyJoined, nbrOfExecutionsToJoin);
      }

      if (parallelGateway.getIncomingFlows().size() > 1) {

        // All (now inactive) children are deleted.
        for (ExecutionEntity joinedExecution : joinedExecutions) {

          // The current execution will be reused and not deleted
          if (!joinedExecution.getId().equals(execution.getId())) {
            executionEntityManager.deleteExecutionAndRelatedData(joinedExecution, null, false);
          }

        }
      }

      // TODO: potential optimization here: reuse more then 1 execution, only 1 currently
      Context.getAgenda().planTakeOutgoingSequenceFlowsOperation((ExecutionEntity) execution, false); // false -> ignoring conditions on parallel gw

    } else if (log.isDebugEnabled()) {
      log.debug("parallel gateway '{}' does not activate: {} of {} joined", execution.getCurrentActivityId(), nbrOfExecutionsCurrentlyJoined, nbrOfExecutionsToJoin);
    }

  }
 
Example 18
@Override
public void execute(DelegateExecution execution) {
  ExecutionEntity executionEntity = (ExecutionEntity) execution;
  BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();
  
  Process process = ProcessDefinitionUtil.getProcess(execution.getProcessDefinitionId());
  if (process == null) {
    throw new ActivitiException("Process model (id = " + execution.getId() + ") could not be found");
  }
  
  Activity compensationActivity = null;
  List<Association> associations = process.findAssociationsWithSourceRefRecursive(boundaryEvent.getId());
  for (Association association : associations) {
    FlowElement targetElement = process.getFlowElement(association.getTargetRef(), true);
    if (targetElement instanceof Activity) {
      Activity activity = (Activity) targetElement;
      if (activity.isForCompensation()) {
        compensationActivity = activity;
        break;
      }
    }
  }
  
  if (compensationActivity == null) {
    throw new ActivitiException("Compensation activity could not be found (or it is missing 'isForCompensation=\"true\"'");
  }
  
  // find SubProcess or Process instance execution
  ExecutionEntity scopeExecution = null;
  ExecutionEntity parentExecution = executionEntity.getParent();
  while (scopeExecution == null && parentExecution != null) {
    if (parentExecution.getCurrentFlowElement() instanceof SubProcess) {
      scopeExecution = parentExecution;
      
    } else if (parentExecution.isProcessInstanceType()) {
      scopeExecution = parentExecution;
    } else {
      parentExecution = parentExecution.getParent();
    }
  }
  
  if (scopeExecution == null) {
    throw new ActivitiException("Could not find a scope execution for compensation boundary event " + boundaryEvent.getId());
  }
  
  Context.getCommandContext().getEventSubscriptionEntityManager().insertCompensationEvent(
      scopeExecution, compensationActivity.getId());
}
 
Example 19
/**
 * Called when the wrapped {@link ActivityBehavior} calls the {@link AbstractBpmnActivityBehavior#leave(ActivityExecution)} method. Handles the completion of one instance, and executes the logic for
 * the sequential behavior.
 */
public void leave(DelegateExecution childExecution) {
  DelegateExecution multiInstanceRootExecution = getMultiInstanceRootExecution(childExecution);
  int nrOfInstances = getLoopVariable(multiInstanceRootExecution, NUMBER_OF_INSTANCES);
  int loopCounter = getLoopVariable(childExecution, getCollectionElementIndexVariable()) + 1;
  int nrOfCompletedInstances = getLoopVariable(multiInstanceRootExecution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
  int nrOfActiveInstances = getLoopVariable(multiInstanceRootExecution, NUMBER_OF_ACTIVE_INSTANCES);

  setLoopVariable(multiInstanceRootExecution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
  setLoopVariable(childExecution, getCollectionElementIndexVariable(), loopCounter);
  logLoopDetails(childExecution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances, nrOfInstances);
  
  Context.getCommandContext().getHistoryManager().recordActivityEnd((ExecutionEntity) childExecution, null);
  callActivityEndListeners(childExecution);
  
  //executeCompensationBoundaryEvents(execution.getCurrentFlowElement(), execution);

  if (loopCounter >= nrOfInstances || completionConditionSatisfied(multiInstanceRootExecution)) {
    removeLocalLoopVariable(childExecution, getCollectionElementIndexVariable());
    multiInstanceRootExecution.setMultiInstanceRoot(false);
    multiInstanceRootExecution.setScope(false);
    multiInstanceRootExecution.setCurrentFlowElement(childExecution.getCurrentFlowElement());
    Context.getCommandContext().getExecutionEntityManager().deleteChildExecutions((ExecutionEntity) multiInstanceRootExecution, "MI_END", false);
    super.leave(multiInstanceRootExecution);
    
  } else {
    try {
      
      if (childExecution.getCurrentFlowElement() instanceof SubProcess) {
        ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
        ExecutionEntity executionToContinue = executionEntityManager.createChildExecution((ExecutionEntity) multiInstanceRootExecution);
        executionToContinue.setCurrentFlowElement(childExecution.getCurrentFlowElement());
        executionToContinue.setScope(true);
        setLoopVariable(executionToContinue, getCollectionElementIndexVariable(), loopCounter);
        executeOriginalBehavior(executionToContinue, loopCounter);
      } else {
        executeOriginalBehavior(childExecution, loopCounter);
      }
      
    } 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
      throw error;
    } catch (Exception e) {
      throw new ActivitiException("Could not execute inner activity behavior of multi instance behavior", e);
    }
  }
}
 
Example 20
/**
 * 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);
}