Skip to content

Commit

Permalink
implementation
Browse files Browse the repository at this point in the history
Issue #650
  • Loading branch information
rsoika committed Mar 10, 2020
1 parent 1376dc6 commit 69e775f
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -829,12 +829,12 @@ private List<ItemCollection> findSourceTasks(String eventID) throws ModelExcepti
/**
* This method computes the target for an event and adds the event to a source
* task. The method call recursive if the target is a followUp Event.
*
* <p>
* If a event has no target the method throws an exception
*
* <p>
* If a event has more than one targets (task or event elements) then the event
* is handled as a loop event.
*
* <p>
* If a event is already assigned to the sourceTask, the method returns without
* adding the event.
*
Expand Down Expand Up @@ -866,7 +866,7 @@ private void addImixsEvent(String eventID, ItemCollection sourceTask) throws Mod
try {
if (model.getEvent(sourceTask.getItemValueInteger("numProcessID"),
event.getItemValueInteger("numactivityid")) != null) {
logger.finest("......Imixs BPMN Event '" + eventName + "' is already assigned tosource task!");
logger.finest("......Imixs BPMN Event '" + eventName + "' is already assigned to a source task!");
return;
}
} catch (ModelException me1) {
Expand All @@ -889,7 +889,8 @@ private void addImixsEvent(String eventID, ItemCollection sourceTask) throws Mod
targetList = new ElementResolver().findAllImixsTargetIDs(outgoingFlow, targetList);
}
if (targetList.size() > 1) {
// we have a multi event which need to be handled like a loop event
// MULTI target - the event has MANY outgoing targets

event.removeItem("keyFollowUp");
event.replaceItemValue("numNextProcessID", sourceTask.getItemValue("numProcessID"));

Expand Down Expand Up @@ -1002,14 +1003,11 @@ private void addImixsEvent(String eventID, ItemCollection sourceTask) throws Mod
}

} else {
// normal case - the event has one outgoing target and we test the
// target element now

// SINGLE target - the event has only ONE outgoing target
// test target element....
// SequenceFlow outgoingFlow = outFlows.get(0);
String followUpEventID = null;
for (SequenceFlow outgoingFlow : outFlows) {
// is this Event connected to a followUp Activity?
// is this Event connected to a followUp Event?
followUpEventID = new ElementResolver().findImixsTargetEventID(outgoingFlow);
if (followUpEventID != null) {
break;
Expand All @@ -1022,7 +1020,6 @@ private void addImixsEvent(String eventID, ItemCollection sourceTask) throws Mod
ItemCollection followUpEvent = eventCache.get(followUpEventID);
event.replaceItemValue("keyFollowUp", "1");
event.replaceItemValue("numNextActivityID", followUpEvent.getItemValue("numactivityid"));

} else {
// test if we found a target task.
ItemCollection targetTask = null;
Expand All @@ -1039,9 +1036,24 @@ private void addImixsEvent(String eventID, ItemCollection sourceTask) throws Mod
}
}
if (targetTask == null) {
// invalid model!! - no target task
throw new ModelException(ModelException.INVALID_MODEL,
"Imixs BPMN Event '" + eventName + "' has no target task element!");
// test if the event is associated with a LinkThrowEvent
String outgoingLink =null;
List<SequenceFlow> outLinkFlows = findOutgoingFlows(eventID);
for (SequenceFlow _outLink: outLinkFlows) {
if (linkThrowEventCache.containsKey(_outLink.target)) {
outgoingLink=_outLink.target;
logger.fine("...event is associated with link event: " + outgoingLink);
}
}
if (outgoingLink!=null) {
// accept this as a valid situation - e.g. linking into another model
event.removeItem("keyFollowUp");
event.replaceItemValue("numNextProcessID", sourceTask.getItemValue("numProcessID"));
} else {
// we found no target task or link event !
throw new ModelException(ModelException.INVALID_MODEL,
"Imixs BPMN Event '" + eventName + "' has no target task or link element!");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,74 @@ public void testLinkEventFollowup() throws ParseException, ParserConfigurationEx




/**
* This test test intermediate link events within an exit situation (e.g. model switch)
* @throws ParseException
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
* @throws ModelException
*/
@Test
public void testLinkEventExit() throws ParseException, ParserConfigurationException, SAXException, IOException, ModelException {

String VERSION = "1.0.0";

InputStream inputStream = getClass().getResourceAsStream("/bpmn/link-event_exit.bpmn");

BPMNModel model = null;
try {
model = BPMNParser.parseModel(inputStream, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Assert.fail();
} catch (ModelException e) {
e.printStackTrace();
Assert.fail();
}
Assert.assertNotNull(model);

// Test Environment
ItemCollection profile = model.getDefinition();
Assert.assertNotNull(profile);
Assert.assertEquals("environment.profile", profile.getItemValueString("txtname"));
Assert.assertEquals("WorkflowEnvironmentEntity", profile.getItemValueString("type"));
Assert.assertEquals(VERSION, profile.getItemValueString("$ModelVersion"));

Assert.assertTrue(model.getGroups().contains("Simple"));

// test count of elements
Assert.assertEquals(2, model.findAllTasks().size());

// test task 1000
ItemCollection task = model.getTask(1000 );
Assert.assertNotNull(task);
Assert.assertEquals("1.0.0", task.getItemValueString("$ModelVersion"));
Assert.assertEquals("Simple", task.getItemValueString("txtworkflowgroup"));

// test activity for task 1000
List<ItemCollection> events = model.findAllEventsByTask(1000 );
Assert.assertEquals(2, events.size());


/* Test confirm1 Event 1000.20 with link event */
ItemCollection activity = model.getEvent(1000, 20 );
Assert.assertNotNull(activity);
Assert.assertEquals("1.0.0",
activity.getItemValueString("$ModelVersion"));

// the event is still connected to the source task 1000
Assert.assertEquals("confirm2", activity.getItemValueString("txtName"));
Assert.assertEquals("1000", activity.getItemValueString("numNextProcessID"));


}





@Test
public void testComplexParserTest() throws ParseException,
ParserConfigurationException, SAXException, IOException {
Expand Down
162 changes: 162 additions & 0 deletions imixs-workflow-core/src/test/resources/bpmn/link-event_exit.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- origin at X=0.0 Y=0.0 -->
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:ext="http://org.eclipse.bpmn2/ext" xmlns:imixs="http://www.imixs.org/bpmn2" xmlns:xs="http://www.w3.org/2001/XMLSchema" id="Definitions_1" exporter="org.eclipse.bpmn2.modeler.core" exporterVersion="1.5.1.Final-v20190425-2005-B1" targetNamespace="http://www.imixs.org/bpmn2">
<bpmn2:extensionElements>
<imixs:item name="txtworkflowmodelversion" type="xs:string">
<imixs:value><![CDATA[1.0.0]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements>
<bpmn2:process id="simple" name="Simple" isExecutable="false">
<bpmn2:startEvent id="StartEvent_1" name="Start">
<bpmn2:outgoing>SequenceFlow_9</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:endEvent id="EndEvent_1" name="End">
<bpmn2:incoming>SequenceFlow_8</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:task id="Task_2" imixs:processid="1000" name="Task 2">
<bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_13</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_14</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="StartEvent_1" targetRef="Task_2"/>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_2" imixs:activityid="10" name="confirm1">
<bpmn2:incoming>SequenceFlow_13</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="SequenceFlow_6" sourceRef="IntermediateCatchEvent_2" targetRef="Task_1"/>
<bpmn2:task id="Task_1" imixs:processid="1100" name="Task 1">
<bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_8</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="Task_1" targetRef="EndEvent_1"/>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_1" imixs:activityid="20" name="confirm2">
<bpmn2:incoming>SequenceFlow_14</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_12</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:intermediateThrowEvent id="IntermediateThrowEvent_1" name="LINK1">
<bpmn2:incoming>SequenceFlow_12</bpmn2:incoming>
<bpmn2:linkEventDefinition id="LinkEventDefinition_1" name="Link Event Definition 1"/>
</bpmn2:intermediateThrowEvent>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_6" imixs:activityid="10" name="save">
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="SequenceFlow_2" sourceRef="IntermediateCatchEvent_6" targetRef="Task_1"/>
<bpmn2:sequenceFlow id="SequenceFlow_12" sourceRef="IntermediateCatchEvent_1" targetRef="IntermediateThrowEvent_1"/>
<bpmn2:sequenceFlow id="SequenceFlow_13" sourceRef="Task_2" targetRef="IntermediateCatchEvent_2"/>
<bpmn2:sequenceFlow id="SequenceFlow_14" sourceRef="Task_2" targetRef="IntermediateCatchEvent_1"/>
<bpmn2:textAnnotation id="TextAnnotation_1">
<bpmn2:text>This situation can be used to switch the model version. The target task in this case did not change.</bpmn2:text>
</bpmn2:textAnnotation>
<bpmn2:association id="Association_1" sourceRef="TextAnnotation_1" targetRef="IntermediateThrowEvent_1"/>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1" name="Default Process Diagram">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="simple">
<bpmndi:BPMNShape id="BPMNShape_1" bpmnElement="StartEvent_1">
<dc:Bounds height="36.0" width="36.0" x="50.0" y="120.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_1" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="14.0" width="25.0" x="55.0" y="156.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_2" bpmnElement="EndEvent_1">
<dc:Bounds height="36.0" width="36.0" x="660.0" y="120.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_2" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="14.0" width="22.0" x="667.0" y="156.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_Task_2" bpmnElement="Task_2">
<dc:Bounds height="50.0" width="110.0" x="160.0" y="113.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_20" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="14.0" width="36.0" x="197.0" y="131.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_IntermediateCatchEvent_2" bpmnElement="IntermediateCatchEvent_2">
<dc:Bounds height="36.0" width="36.0" x="350.0" y="120.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_11">
<dc:Bounds height="14.0" width="48.0" x="344.0" y="156.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_Task_1" bpmnElement="Task_1">
<dc:Bounds height="50.0" width="110.0" x="470.0" y="113.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_17">
<dc:Bounds height="14.0" width="36.0" x="507.0" y="131.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_IntermediateCatchEvent_1" bpmnElement="IntermediateCatchEvent_1">
<dc:Bounds height="36.0" width="36.0" x="197.0" y="200.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_3">
<dc:Bounds height="14.0" width="48.0" x="191.0" y="236.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_IntermediateThrowEvent_1" bpmnElement="IntermediateThrowEvent_1">
<dc:Bounds height="36.0" width="36.0" x="280.0" y="200.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_8">
<dc:Bounds height="14.0" width="34.0" x="281.0" y="236.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_IntermediateCatchEvent_6" bpmnElement="IntermediateCatchEvent_6">
<dc:Bounds height="36.0" width="36.0" x="507.0" y="38.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_29">
<dc:Bounds height="14.0" width="26.0" x="512.0" y="74.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_TextAnnotation_1" bpmnElement="TextAnnotation_1">
<dc:Bounds height="71.0" width="226.0" x="365.0" y="182.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_10">
<dc:Bounds height="65.0" width="214.0" x="371.0" y="182.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_9" bpmnElement="SequenceFlow_9" sourceElement="BPMNShape_1" targetElement="BPMNShape_Task_2">
<di:waypoint xsi:type="dc:Point" x="86.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="123.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="160.0" y="138.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_21" labelStyle="BPMNLabelStyle_1"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_6" bpmnElement="SequenceFlow_6" sourceElement="BPMNShape_IntermediateCatchEvent_2" targetElement="BPMNShape_Task_1">
<di:waypoint xsi:type="dc:Point" x="386.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="442.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="470.0" y="138.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_13"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_8" bpmnElement="SequenceFlow_8" sourceElement="BPMNShape_Task_1" targetElement="BPMNShape_2">
<di:waypoint xsi:type="dc:Point" x="580.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="625.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="660.0" y="138.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_18"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="BPMNShape_IntermediateCatchEvent_6" targetElement="BPMNShape_Task_1">
<di:waypoint xsi:type="dc:Point" x="525.0" y="74.0"/>
<di:waypoint xsi:type="dc:Point" x="525.0" y="88.0"/>
<di:waypoint xsi:type="dc:Point" x="525.0" y="113.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_5"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_12" bpmnElement="SequenceFlow_12" sourceElement="BPMNShape_IntermediateCatchEvent_1" targetElement="BPMNShape_IntermediateThrowEvent_1">
<di:waypoint xsi:type="dc:Point" x="233.0" y="218.0"/>
<di:waypoint xsi:type="dc:Point" x="270.0" y="218.0"/>
<di:waypoint xsi:type="dc:Point" x="280.0" y="218.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_16"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_13" bpmnElement="SequenceFlow_13" sourceElement="BPMNShape_Task_2" targetElement="BPMNShape_IntermediateCatchEvent_2">
<di:waypoint xsi:type="dc:Point" x="270.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="318.0" y="138.0"/>
<di:waypoint xsi:type="dc:Point" x="350.0" y="138.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_22"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_14" bpmnElement="SequenceFlow_14" sourceElement="BPMNShape_Task_2" targetElement="BPMNShape_IntermediateCatchEvent_1">
<di:waypoint xsi:type="dc:Point" x="215.0" y="163.0"/>
<di:waypoint xsi:type="dc:Point" x="215.0" y="181.0"/>
<di:waypoint xsi:type="dc:Point" x="215.0" y="200.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_23"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_Association_1" bpmnElement="Association_1" sourceElement="BPMNShape_TextAnnotation_1" targetElement="BPMNShape_IntermediateThrowEvent_1">
<di:waypoint xsi:type="dc:Point" x="365.0" y="217.0"/>
<di:waypoint xsi:type="dc:Point" x="341.0" y="217.0"/>
<di:waypoint xsi:type="dc:Point" x="316.0" y="218.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_12"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
<dc:Font name="arial" size="9.0"/>
</bpmndi:BPMNLabelStyle>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>

0 comments on commit 69e775f

Please sign in to comment.