use of org.activiti.engine.impl.pvm.runtime.OutgoingExecution in project Activiti by Activiti.
the class ExecutionEntity method takeAll.
@SuppressWarnings({ "unchecked", "rawtypes" })
public void takeAll(List<PvmTransition> transitions, List<ActivityExecution> recyclableExecutions) {
fireActivityCompletedEvent();
transitions = new ArrayList<PvmTransition>(transitions);
recyclableExecutions = (recyclableExecutions != null ? new ArrayList<ActivityExecution>(recyclableExecutions) : new ArrayList<ActivityExecution>());
if (recyclableExecutions.size() > 1) {
for (ActivityExecution recyclableExecution : recyclableExecutions) {
if (((ExecutionEntity) recyclableExecution).isScope()) {
throw new PvmException("joining scope executions is not allowed");
}
}
}
ExecutionEntity concurrentRoot = ((isConcurrent && !isScope) ? getParent() : this);
List<ExecutionEntity> concurrentActiveExecutions = new ArrayList<ExecutionEntity>();
List<ExecutionEntity> concurrentInActiveExecutions = new ArrayList<ExecutionEntity>();
for (ExecutionEntity execution : concurrentRoot.getExecutions()) {
if (execution.isActive()) {
concurrentActiveExecutions.add(execution);
} else {
concurrentInActiveExecutions.add(execution);
}
}
if (log.isDebugEnabled()) {
log.debug("transitions to take concurrent: {}", transitions);
log.debug("active concurrent executions: {}", concurrentActiveExecutions);
}
if ((transitions.size() == 1) && (concurrentActiveExecutions.isEmpty()) && allExecutionsInSameActivity(concurrentInActiveExecutions)) {
List<ExecutionEntity> recyclableExecutionImpls = (List) recyclableExecutions;
recyclableExecutions.remove(concurrentRoot);
for (ExecutionEntity prunedExecution : recyclableExecutionImpls) {
// End the pruned executions if necessary.
// Some recyclable executions are inactivated (joined executions)
// Others are already ended (end activities)
// Need to call the activity end here. If we would do it later,
// the executions are removed and the historic activity instances are
// never ended as the combination of {activityId,executionId} is not valid anymor
Context.getCommandContext().getHistoryManager().recordActivityEnd(prunedExecution);
log.debug("pruning execution {}", prunedExecution);
prunedExecution.remove();
}
log.debug("activating the concurrent root {} as the single path of execution going forward", concurrentRoot);
concurrentRoot.setActive(true);
concurrentRoot.setActivity(activity);
concurrentRoot.setConcurrent(false);
concurrentRoot.take(transitions.get(0), false);
} else {
List<OutgoingExecution> outgoingExecutions = new ArrayList<OutgoingExecution>();
recyclableExecutions.remove(concurrentRoot);
log.debug("recyclable executions for reuse: {}", recyclableExecutions);
// first create the concurrent executions
while (!transitions.isEmpty()) {
PvmTransition outgoingTransition = transitions.remove(0);
ExecutionEntity outgoingExecution = null;
if (recyclableExecutions.isEmpty()) {
outgoingExecution = concurrentRoot.createExecution();
log.debug("new {} with parent {} created to take transition {}", outgoingExecution, outgoingExecution.getParent(), outgoingTransition);
} else {
outgoingExecution = (ExecutionEntity) recyclableExecutions.remove(0);
log.debug("recycled {} to take transition {}", outgoingExecution, outgoingTransition);
}
outgoingExecution.setActive(true);
outgoingExecution.setScope(false);
outgoingExecution.setConcurrent(true);
outgoingExecution.setTransitionBeingTaken((TransitionImpl) outgoingTransition);
outgoingExecutions.add(new OutgoingExecution(outgoingExecution, outgoingTransition, true));
}
// prune the executions that are not recycled
for (ActivityExecution prunedExecution : recyclableExecutions) {
log.debug("pruning execution {}", prunedExecution);
prunedExecution.end();
}
// then launch all the concurrent executions
for (OutgoingExecution outgoingExecution : outgoingExecutions) {
outgoingExecution.take(false);
}
}
}
Aggregations