use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.
the class TakeOutgoingSequenceFlowsOperation method leaveFlowNode.
protected void leaveFlowNode(FlowNode flowNode) {
logger.debug("Leaving flow node {} with id '{}' by following it's {} outgoing sequenceflow", flowNode.getClass(), flowNode.getId(), flowNode.getOutgoingFlows().size());
// Get default sequence flow (if set)
String defaultSequenceFlowId = null;
if (flowNode instanceof Activity) {
defaultSequenceFlowId = ((Activity) flowNode).getDefaultFlow();
} else if (flowNode instanceof Gateway) {
defaultSequenceFlowId = ((Gateway) flowNode).getDefaultFlow();
}
// Determine which sequence flows can be used for leaving
List<SequenceFlow> outgoingSequenceFlows = new ArrayList<SequenceFlow>();
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
String skipExpressionString = sequenceFlow.getSkipExpression();
if (!SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpressionString)) {
if (!evaluateConditions || (evaluateConditions && ConditionUtil.hasTrueCondition(sequenceFlow, execution) && (defaultSequenceFlowId == null || !defaultSequenceFlowId.equals(sequenceFlow.getId())))) {
outgoingSequenceFlows.add(sequenceFlow);
}
} else if (flowNode.getOutgoingFlows().size() == 1 || SkipExpressionUtil.shouldSkipFlowElement(commandContext, execution, skipExpressionString)) {
// The 'skip' for a sequence flow means that we skip the condition, not the sequence flow.
outgoingSequenceFlows.add(sequenceFlow);
}
}
// Check if there is a default sequence flow
if (outgoingSequenceFlows.size() == 0 && evaluateConditions) {
// The elements that set this to false also have no support for default sequence flow
if (defaultSequenceFlowId != null) {
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
if (defaultSequenceFlowId.equals(sequenceFlow.getId())) {
outgoingSequenceFlows.add(sequenceFlow);
break;
}
}
}
}
// No outgoing found. Ending the execution
if (outgoingSequenceFlows.size() == 0) {
if (flowNode.getOutgoingFlows() == null || flowNode.getOutgoingFlows().size() == 0) {
logger.debug("No outgoing sequence flow found for flow node '{}'.", flowNode.getId());
Context.getAgenda().planEndExecutionOperation(execution);
} else {
throw new ActivitiException("No outgoing sequence flow of element '" + flowNode.getId() + "' could be selected for continuing the process");
}
} else {
// Leave, and reuse the incoming sequence flow, make executions for all the others (if applicable)
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
List<ExecutionEntity> outgoingExecutions = new ArrayList<ExecutionEntity>(flowNode.getOutgoingFlows().size());
SequenceFlow sequenceFlow = outgoingSequenceFlows.get(0);
// Reuse existing one
execution.setCurrentFlowElement(sequenceFlow);
execution.setActive(true);
outgoingExecutions.add((ExecutionEntity) execution);
// Executions for all the other one
if (outgoingSequenceFlows.size() > 1) {
for (int i = 1; i < outgoingSequenceFlows.size(); i++) {
ExecutionEntity parent = execution.getParentId() != null ? execution.getParent() : execution;
ExecutionEntity outgoingExecutionEntity = commandContext.getExecutionEntityManager().createChildExecution(parent);
SequenceFlow outgoingSequenceFlow = outgoingSequenceFlows.get(i);
outgoingExecutionEntity.setCurrentFlowElement(outgoingSequenceFlow);
executionEntityManager.insert(outgoingExecutionEntity);
outgoingExecutions.add(outgoingExecutionEntity);
}
}
// Leave (only done when all executions have been made, since some queries depend on this)
for (ExecutionEntity outgoingExecution : outgoingExecutions) {
Context.getAgenda().planContinueProcessOperation(outgoingExecution);
}
}
}
use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.
the class IntermediateCatchEventActivityBehavior method deleteOtherEventsRelatedToEventBasedGateway.
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();
// -1, the event being triggered does not need to be deleted
Set<String> eventActivityIds = new HashSet<String>(outgoingSequenceFlows.size() - 1);
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);
// We only need to delete ONE execution at the event.
eventActivityIds.remove(executionEntity.getActivityId());
}
}
}
}
use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.
the class ParallelGatewayActivityBehavior method execute.
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);
}
}
}
// TODO: potential optimization here: reuse more then 1 execution, only 1 currently
// false -> ignoring conditions on parallel gw
Context.getAgenda().planTakeOutgoingSequenceFlowsOperation((ExecutionEntity) execution, false);
} else if (log.isDebugEnabled()) {
log.debug("parallel gateway '{}' does not activate: {} of {} joined", execution.getCurrentActivityId(), nbrOfExecutionsCurrentlyJoined, nbrOfExecutionsToJoin);
}
}
use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.
the class BoundaryCancelEventActivityBehavior method trigger.
@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);
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);
}
}
}
}
leave(execution);
}
}
use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.
the class BoundaryEventActivityBehavior method executeNonInterruptingBehavior.
protected void executeNonInterruptingBehavior(ExecutionEntity executionEntity, CommandContext commandContext) {
// Non-interrupting: the current execution is given the first parent
// scope (which isn't its direct parent)
//
// Why? Because this execution does NOT have anything to do with
// the current parent execution (the one where the boundary event is on): when it is deleted or whatever,
// this does not impact this new execution at all, it is completely independent in that regard.
// Note: if the parent of the parent does not exists, this becomes a concurrent execution in the process instance!
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
ExecutionEntity parentExecutionEntity = executionEntityManager.findById(executionEntity.getParentId());
ExecutionEntity scopeExecution = null;
ExecutionEntity currentlyExaminedExecution = executionEntityManager.findById(parentExecutionEntity.getParentId());
while (currentlyExaminedExecution != null && scopeExecution == null) {
if (currentlyExaminedExecution.isScope()) {
scopeExecution = currentlyExaminedExecution;
} else {
currentlyExaminedExecution = executionEntityManager.findById(currentlyExaminedExecution.getParentId());
}
}
if (scopeExecution == null) {
throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event");
}
ExecutionEntity nonInterruptingExecution = executionEntityManager.createChildExecution(scopeExecution);
nonInterruptingExecution.setCurrentFlowElement(executionEntity.getCurrentFlowElement());
Context.getAgenda().planTakeOutgoingSequenceFlowsOperation(nonInterruptingExecution, true);
}
Aggregations