diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationActivityEnd.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationActivityEnd.java index aa4cc3108430ba567a94b5f853dc426235e044a1..15a8405be3f4ce28887254697f25f423cf61bef2 100644 --- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationActivityEnd.java +++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationActivityEnd.java @@ -74,9 +74,18 @@ public class AtomicOperationActivityEnd extends AbstractEventAtomicOperation { // default destroy scope behavior InterpretableExecution parentScopeExecution = (InterpretableExecution) execution.getParent(); execution.destroy(); - execution.remove(); - parentScopeExecution.setActivity(parentActivity); - parentScopeExecution.performOperation(ACTIVITY_END); + 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() diff --git a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/subprocess/SubProcessTest.java b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/subprocess/SubProcessTest.java index 487a26ce0a8044dca62ce32c5c46efe176514028..a61de3cf5431d57730f960ddca7c7836ed42cdf7 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/subprocess/SubProcessTest.java +++ b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/subprocess/SubProcessTest.java @@ -340,7 +340,7 @@ public class SubProcessTest extends PluggableActivitiTestCase { * @see http://jira.codehaus.org/browse/ACT-1072 */ @Deployment - public void FAILING_testSimpleSubProcessWithoutEndEvent() { + public void testSimpleSubProcessWithoutEndEvent() { ProcessInstance pi = runtimeService.startProcessInstanceByKey("testSimpleSubProcessWithoutEndEvent"); assertProcessEnded(pi.getId()); } @@ -349,7 +349,7 @@ public class SubProcessTest extends PluggableActivitiTestCase { * @see http://jira.codehaus.org/browse/ACT-1072 */ @Deployment - public void FAILING_testNestedSubProcessesWithoutEndEvents() { + public void testNestedSubProcessesWithoutEndEvents() { ProcessInstance pi = runtimeService.startProcessInstanceByKey("testNestedSubProcessesWithoutEndEvents"); assertProcessEnded(pi.getId()); } diff --git a/modules/activiti-engine/src/test/java/org/activiti/engine/test/pvm/PvmEmbeddedSubProcessTest.java b/modules/activiti-engine/src/test/java/org/activiti/engine/test/pvm/PvmEmbeddedSubProcessTest.java index e28148b79455227677e78ce64f172b6068a87a98..912f1c3b909bb3f87230760b25da164d97235ecb 100644 --- a/modules/activiti-engine/src/test/java/org/activiti/engine/test/pvm/PvmEmbeddedSubProcessTest.java +++ b/modules/activiti-engine/src/test/java/org/activiti/engine/test/pvm/PvmEmbeddedSubProcessTest.java @@ -249,14 +249,44 @@ public class PvmEmbeddedSubProcessTest extends PvmTestCase { assertEquals(expectedActiveActivityIds, processInstance.findActiveActivityIds()); } + /** + * +------------------------------+ + * | embedded subprocess | + * +-----+ | +-----------+ | + * |start|-->| |startInside| | + * +-----+ | +-----------+ | + * +------------------------------+ + */ + public void testEmbeddedSubProcessWithoutEndEvents() { + PvmProcessDefinition processDefinition = new ProcessDefinitionBuilder() + .createActivity("start") + .initial() + .behavior(new Automatic()) + .transition("embeddedsubprocess") + .endActivity() + .createActivity("embeddedsubprocess") + .scope() + .behavior(new EmbeddedSubProcess()) + .createActivity("startInside") + .behavior(new Automatic()) + .endActivity() + .endActivity() + .buildProcessDefinition(); + + PvmProcessInstance processInstance = processDefinition.createProcessInstance(); + processInstance.start(); + + assertTrue(processInstance.isEnded()); + } + /** * +-------------------------------------------------------+ * | embedded subprocess | * | +--------------------------------+ | * | | nested embedded subprocess | | - * +-----+ | +-----------+ | +-----------+ | | +---+ - * |start|-->| |startInside|--> | |startInside| | |-->|end| - * +-----+ | +-----------+ | +-----------+ | | +---+ + * +-----+ | +-----------+ | +-----------+ | | + * |start|-->| |startInside|--> | |startInside| | | + * +-----+ | +-----------+ | +-----------+ | | * | +--------------------------------+ | * | | * +-------------------------------------------------------+ @@ -282,20 +312,48 @@ public class PvmEmbeddedSubProcessTest extends PvmTestCase { .behavior(new Automatic()) .endActivity() .endActivity() - .transition("end") - .endActivity() - .createActivity("end") - .behavior(new WaitState()) + .endActivity() + .buildProcessDefinition(); + + PvmProcessInstance processInstance = processDefinition.createProcessInstance(); + processInstance.start(); + + assertTrue(processInstance.isEnded()); + } + + + /** + * +------------------------------+ + * | embedded subprocess | + * +-----+ | +-----------+ +---------+ | + * |start|-->| |startInside|-->|endInside| | + * +-----+ | +-----------+ +---------+ | + * +------------------------------+ + */ + public void testEmbeddedSubProcessNoEnd() { + PvmProcessDefinition processDefinition = new ProcessDefinitionBuilder() + .createActivity("start") + .initial() + .behavior(new Automatic()) + .transition("embeddedsubprocess") .endActivity() + .createActivity("embeddedsubprocess") + .scope() + .behavior(new EmbeddedSubProcess()) + .createActivity("startInside") + .behavior(new Automatic()) + .transition("endInside") + .endActivity() + .createActivity("endInside") + .behavior(new End()) + .endActivity() + .endActivity() .buildProcessDefinition(); PvmProcessInstance processInstance = processDefinition.createProcessInstance(); processInstance.start(); - List expectedActiveActivityIds = new ArrayList(); - expectedActiveActivityIds.add("end"); - - assertEquals(expectedActiveActivityIds, processInstance.findActiveActivityIds()); + assertTrue(processInstance.isEnded()); } }