@SuppressWarnings("unchecked") protected boolean isExecutionAloneInParent(InterpretableExecution execution) { ScopeImpl parentScope = (ScopeImpl) execution.getActivity().getParent(); for (InterpretableExecution other : (List<InterpretableExecution>) execution.getParent().getExecutions()) { if (other != execution && parentScope.contains((ActivityImpl) other.getActivity())) { return false; } } return true; }
@SuppressWarnings("unchecked") @Override protected void eventNotificationsCompleted(InterpretableExecution execution) { ActivityImpl activity = (ActivityImpl) execution.getActivity(); ActivityImpl parentActivity = activity.getParentActivity(); // if the execution is a single path of execution inside the process definition scope if ((parentActivity != null) && (!parentActivity.isScope())) { execution.setActivity(parentActivity); execution.performOperation(ACTIVITY_END); } else if (execution.isProcessInstance()) { execution.performOperation(PROCESS_END); } else if (execution.isScope()) { ActivityBehavior parentActivityBehavior = (parentActivity != null ? parentActivity.getActivityBehavior() : null); if (parentActivityBehavior instanceof CompositeActivityBehavior) { CompositeActivityBehavior compositeActivityBehavior = (CompositeActivityBehavior) parentActivity.getActivityBehavior(); if (activity.isScope() && activity.getOutgoingTransitions().isEmpty()) { // there is no transition destroying the scope InterpretableExecution parentScopeExecution = (InterpretableExecution) execution.getParent(); execution.destroy(); execution.remove(); parentScopeExecution.setActivity(parentActivity); compositeActivityBehavior.lastExecutionEnded(parentScopeExecution); } else { execution.setActivity(parentActivity); compositeActivityBehavior.lastExecutionEnded(execution); } } else { // default destroy scope behavior InterpretableExecution parentScopeExecution = (InterpretableExecution) execution.getParent(); execution.destroy(); execution.remove(); // if we are a scope under the process instance // and have no outgoing transitions: end the process instance here if (activity.getParent() == activity.getProcessDefinition() && activity.getOutgoingTransitions().isEmpty()) { parentScopeExecution.setActivity(activity); // we call end() because it sets isEnded on the execution parentScopeExecution.end(); } else { parentScopeExecution.setActivity(parentActivity); parentScopeExecution.performOperation(ACTIVITY_END); } } } else { // execution.isConcurrent() && !execution.isScope() execution.remove(); // prune if necessary InterpretableExecution concurrentRoot = (InterpretableExecution) execution.getParent(); if (concurrentRoot.getExecutions().size() == 1) { InterpretableExecution lastConcurrent = (InterpretableExecution) concurrentRoot.getExecutions().get(0); if (!lastConcurrent.isScope()) { concurrentRoot.setActivity((ActivityImpl) lastConcurrent.getActivity()); lastConcurrent.setReplacedBy(concurrentRoot); // Move children of lastConcurrent one level up if (lastConcurrent.getExecutions().size() > 0) { concurrentRoot.getExecutions().clear(); for (ActivityExecution childExecution : lastConcurrent.getExecutions()) { InterpretableExecution childInterpretableExecution = (InterpretableExecution) childExecution; ((List) concurrentRoot.getExecutions()) .add(childExecution); // casting ... damn generics childInterpretableExecution.setParent(concurrentRoot); } lastConcurrent.getExecutions().clear(); } // Copy execution-local variables of lastConcurrent concurrentRoot.setVariablesLocal(lastConcurrent.getVariablesLocal()); lastConcurrent.remove(); } else { lastConcurrent.setConcurrent(false); } } } }