use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class GetActivityInstanceCmd method createActivityInstance.
protected ActivityInstanceImpl createActivityInstance(PvmExecutionImpl scopeExecution, ScopeImpl scope, String activityInstanceId, String parentActivityInstanceId) {
ActivityInstanceImpl actInst = new ActivityInstanceImpl();
actInst.setId(activityInstanceId);
actInst.setParentActivityInstanceId(parentActivityInstanceId);
actInst.setProcessInstanceId(scopeExecution.getProcessInstanceId());
actInst.setProcessDefinitionId(scopeExecution.getProcessDefinitionId());
actInst.setBusinessKey(scopeExecution.getBusinessKey());
actInst.setActivityId(scope.getId());
String name = scope.getName();
if (name == null) {
name = (String) scope.getProperty("name");
}
actInst.setActivityName(name);
if (scope.getId().equals(scopeExecution.getProcessDefinition().getId())) {
actInst.setActivityType("processDefinition");
} else {
actInst.setActivityType((String) scope.getProperty("type"));
}
List<String> executionIds = new ArrayList<String>();
executionIds.add(scopeExecution.getId());
for (PvmExecutionImpl childExecution : scopeExecution.getNonEventScopeExecutions()) {
// add all concurrent children that are not in an activity
if (childExecution.isConcurrent() && (childExecution.getActivityId() == null)) {
executionIds.add(childExecution.getId());
}
}
actInst.setExecutionIds(executionIds.toArray(new String[executionIds.size()]));
return actInst;
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class GetActivityInstanceCmd method execute.
public ActivityInstance execute(CommandContext commandContext) {
ensureNotNull("processInstanceId", processInstanceId);
List<ExecutionEntity> executionList = loadProcessInstance(processInstanceId, commandContext);
if (executionList.isEmpty()) {
return null;
}
checkGetActivityInstance(processInstanceId, commandContext);
List<ExecutionEntity> nonEventScopeExecutions = filterNonEventScopeExecutions(executionList);
List<ExecutionEntity> leaves = filterLeaves(nonEventScopeExecutions);
// Leaves must be ordered in a predictable way (e.g. by ID)
// in order to return a stable execution tree with every repeated invocation of this command.
// For legacy process instances, there may miss scope executions for activities that are now a scope.
// In this situation, there may be multiple scope candidates for the same instance id; which one
// can depend on the order the leaves are iterated.
orderById(leaves);
ExecutionEntity processInstance = filterProcessInstance(executionList);
if (processInstance.isEnded()) {
return null;
}
// create act instance for process instance
ActivityInstanceImpl processActInst = createActivityInstance(processInstance, processInstance.getProcessDefinition(), processInstanceId, null);
Map<String, ActivityInstanceImpl> activityInstances = new HashMap<String, ActivityInstanceImpl>();
activityInstances.put(processInstanceId, processActInst);
Map<String, TransitionInstanceImpl> transitionInstances = new HashMap<String, TransitionInstanceImpl>();
for (ExecutionEntity leaf : leaves) {
// it will not have an activity set
if (leaf.getActivity() == null) {
continue;
}
Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping = leaf.createActivityExecutionMapping();
Map<ScopeImpl, PvmExecutionImpl> scopeInstancesToCreate = new HashMap<ScopeImpl, PvmExecutionImpl>(activityExecutionMapping);
// and does not throw compensation
if (leaf.getActivityInstanceId() != null) {
if (!CompensationBehavior.isCompensationThrowing(leaf) || LegacyBehavior.isCompensationThrowing(leaf, activityExecutionMapping)) {
String parentActivityInstanceId = null;
parentActivityInstanceId = activityExecutionMapping.get(leaf.getActivity().getFlowScope()).getParentActivityInstanceId();
ActivityInstanceImpl leafInstance = createActivityInstance(leaf, leaf.getActivity(), leaf.getActivityInstanceId(), parentActivityInstanceId);
activityInstances.put(leafInstance.getId(), leafInstance);
scopeInstancesToCreate.remove(leaf.getActivity());
}
} else {
TransitionInstanceImpl transitionInstance = createTransitionInstance(leaf);
transitionInstances.put(transitionInstance.getId(), transitionInstance);
scopeInstancesToCreate.remove(leaf.getActivity());
}
LegacyBehavior.removeLegacyNonScopesFromMapping(scopeInstancesToCreate);
scopeInstancesToCreate.remove(leaf.getProcessDefinition());
// create an activity instance for each scope (including compensation throwing executions)
for (Map.Entry<ScopeImpl, PvmExecutionImpl> scopeExecutionEntry : scopeInstancesToCreate.entrySet()) {
ScopeImpl scope = scopeExecutionEntry.getKey();
PvmExecutionImpl scopeExecution = scopeExecutionEntry.getValue();
String activityInstanceId = null;
String parentActivityInstanceId = null;
activityInstanceId = scopeExecution.getParentActivityInstanceId();
parentActivityInstanceId = activityExecutionMapping.get(scope.getFlowScope()).getParentActivityInstanceId();
if (activityInstances.containsKey(activityInstanceId)) {
continue;
} else {
// regardless of the tree structure (compacted or not), the scope's activity instance id
// is the activity instance id of the parent execution and the parent activity instance id
// of that is the actual parent activity instance id
ActivityInstanceImpl scopeInstance = createActivityInstance(scopeExecution, scope, activityInstanceId, parentActivityInstanceId);
activityInstances.put(activityInstanceId, scopeInstance);
}
}
}
LegacyBehavior.repairParentRelationships(activityInstances.values(), processInstanceId);
populateChildInstances(activityInstances, transitionInstances);
return processActInst;
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class ParallelMultiInstanceActivityBehavior method concurrentChildExecutionEnded.
@Override
public void concurrentChildExecutionEnded(ActivityExecution scopeExecution, ActivityExecution endedExecution) {
int nrOfCompletedInstances = getLoopVariable(scopeExecution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
setLoopVariable(scopeExecution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
int nrOfActiveInstances = getLoopVariable(scopeExecution, NUMBER_OF_ACTIVE_INSTANCES) - 1;
setLoopVariable(scopeExecution, NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances);
// inactivate the concurrent execution
endedExecution.inactivate();
endedExecution.setActivityInstanceId(null);
// join
scopeExecution.forceUpdate();
// TODO: should the completion condition be evaluated on the scopeExecution or on the endedExecution?
if (completionConditionSatisfied(endedExecution) || allExecutionsEnded(scopeExecution, endedExecution)) {
ArrayList<ActivityExecution> childExecutions = new ArrayList<ActivityExecution>(((PvmExecutionImpl) scopeExecution).getNonEventScopeExecutions());
for (ActivityExecution childExecution : childExecutions) {
// delete all not-ended instances; these are either active (for non-scope tasks) or inactive but have no activity id (for subprocesses, etc.)
if (childExecution.isActive() || childExecution.getActivity() == null) {
((PvmExecutionImpl) childExecution).deleteCascade("Multi instance completion condition satisfied.");
} else {
childExecution.remove();
}
}
scopeExecution.setActivity((PvmActivity) endedExecution.getActivity().getFlowScope());
scopeExecution.setActive(true);
leave(scopeExecution);
} else {
((ExecutionEntity) scopeExecution).dispatchDelayedEventsAndPerformOperation((Callback<PvmExecutionImpl, Void>) null);
}
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class ActivityExecutionTreeMapping method mergeScopeExecutions.
protected void mergeScopeExecutions(ExecutionEntity leaf) {
Map<ScopeImpl, PvmExecutionImpl> mapping = leaf.createActivityExecutionMapping();
for (Map.Entry<ScopeImpl, PvmExecutionImpl> mappingEntry : mapping.entrySet()) {
ScopeImpl scope = mappingEntry.getKey();
ExecutionEntity scopeExecution = (ExecutionEntity) mappingEntry.getValue();
submitExecution(scopeExecution, scope);
}
}
use of org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl in project camunda-bpm-platform by camunda.
the class AbstractInstanceCancellationCmd method handleChildRemovalInScope.
protected void handleChildRemovalInScope(ExecutionEntity removedExecution) {
// TODO: the following should be closer to PvmAtomicOperationDeleteCascadeFireActivityEnd
// (note though that e.g. boundary events expect concurrent executions to be preserved)
//
// Idea: attempting to prune and synchronize on the parent is the default behavior when
// a concurrent child is removed, but scope activities implementing ModificationObserverBehavior
// override this default (and therefore *must* take care of reorganization themselves)
// notify the behavior that a concurrent execution has been removed
// must be set due to deleteCascade behavior
ActivityImpl activity = removedExecution.getActivity();
if (activity == null) {
return;
}
ScopeImpl flowScope = activity.getFlowScope();
PvmExecutionImpl scopeExecution = removedExecution.getParentScopeExecution(false);
PvmExecutionImpl executionInParentScope = removedExecution.isConcurrent() ? removedExecution : removedExecution.getParent();
if (flowScope.getActivityBehavior() != null && flowScope.getActivityBehavior() instanceof ModificationObserverBehavior) {
// let child removal be handled by the scope itself
ModificationObserverBehavior behavior = (ModificationObserverBehavior) flowScope.getActivityBehavior();
behavior.destroyInnerInstance(executionInParentScope);
} else {
if (executionInParentScope.isConcurrent()) {
executionInParentScope.remove();
scopeExecution.tryPruneLastConcurrentChild();
scopeExecution.forceUpdate();
}
}
}
Aggregations