Skip to content

Commit

Permalink
impl, junit tests
Browse files Browse the repository at this point in the history
Issue imixs#227
rsoika committed Apr 5, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 783b35f commit ac642d3
Showing 4 changed files with 224 additions and 18 deletions.
41 changes: 30 additions & 11 deletions open-bpmn.metamodel/src/main/java/org/openbpmn/bpmn/BPMNTypes.java
Original file line number Diff line number Diff line change
@@ -3,8 +3,14 @@
import java.util.Arrays;
import java.util.List;

import org.openbpmn.bpmn.elements.SequenceFlow;
import org.openbpmn.bpmn.elements.core.BPMNElement;
import org.openbpmn.bpmn.elements.core.BPMNElementNode;

/**
* The BPMNTypes provides constants defining the visual elements contained in a BPMNDiagram.
* The BPMNTypes provides constants defining the visual elements contained in a
* BPMNDiagram.
*
* @author rsoika
*
*/
@@ -14,7 +20,7 @@ public class BPMNTypes {
public static final String PROCESS_TYPE_PUBLIC = "Public";
public static final String PROCESS_TYPE_PRIVATE = "Private";
public static final String PROCESS_TYPE_NONE = "None";

// Tasks
public static final String TASK = "task";
public static final String USER_TASK = "userTask";
@@ -24,15 +30,15 @@ public class BPMNTypes {
public static final String MANUAL_TASK = "manualTask";
public static final String BUSINESSRULE_TASK = "businessRuleTask";
public static final String RECEIVE_TASK = "receiveTask";

// Events
public static final String EVENT = "event";
public static final String START_EVENT = "startEvent";
public static final String END_EVENT= "endEvent";
public static final String END_EVENT = "endEvent";
public static final String CATCH_EVENT = "intermediateCatchEvent";
public static final String THROW_EVENT = "intermediateThrowEvent";
public static final String BOUNDARY_EVENT = "boundaryEvent";

// Event Definitions
public static final String EVENT_DEFINITION_CONDITIONAL = "conditionalEventDefinition";
public static final String EVENT_DEFINITION_COMPENSATION = "compensationEventDefinition";
@@ -44,19 +50,19 @@ public class BPMNTypes {
public static final String EVENT_DEFINITION_ERROR = "errorEventDefinition";
public static final String EVENT_DEFINITION_TERMINATE = "terminateEventDefinition";
public static final String EVENT_DEFINITION_CANCEL = "cancelEventDefinition";

// Multiple Event Definitions
public static final String MULTIPLE_EVENT_DEFINITIONS = "multipleEventDefinition";

// Gateways
public static final String GATEWAY = "gateway";
public static final String GATEWAY = "gateway";
public static final String EXCLUSIVE_GATEWAY = "exclusiveGateway";
public static final String INCLUSIVE_GATEWAY = "inclusiveGateway";
public static final String EVENTBASED_GATEWAY = "eventBasedGateway";
public static final String PARALLEL_GATEWAY = "parallelGateway";
public static final String COMPLEX_GATEWAY = "complexGateway";
// Others

// Others
public static final String DATAOBJECT = "dataObject";
public static final String TEXTANNOTATION = "textAnnotation";
public static final String POOL = "pool";
@@ -127,6 +133,20 @@ public class BPMNTypes {

BPMNTypes.SEQUENCE_FLOW);

/**
* Returns true if the given element is a FlowElement,
* which are Events, Gateways , Sequence Flows or Activities
*/
public static boolean isFlowElement(BPMNElement element) {
if (element instanceof SequenceFlow) {
return true;
}
if (element instanceof BPMNElementNode) {
return BPMN_FLOWELEMENTS.contains(((BPMNElementNode) element).getType());
}
return false;
}

public final static List<String> BPMN_NODE_ELEMENTS = Arrays.asList(//
BPMNTypes.TASK, //
BPMNTypes.MANUAL_TASK, //
@@ -180,4 +200,3 @@ public class BPMNTypes {
});

}

Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ public Element getLaneSet() {
}

/**
* This method insets a given BPMNFlowElment to this lane
* This method inserts a given BPMNFlowElement to this lane
* <p>
* {@code
* <bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
@@ -117,12 +117,14 @@ public Element getLaneSet() {
* @param laneId
* @throws BPMNInvalidReferenceException
*/
public void insert(BPMNElementNode bpmnEementNode) throws BPMNInvalidReferenceException {
// append flowNodeRef
Element flowNodeRef = model.createElement(BPMNNS.BPMN2, "flowNodeRef");
Text textNode = this.getDoc().createTextNode(bpmnEementNode.getId());
flowNodeRef.appendChild(textNode);
this.getElementNode().appendChild(flowNodeRef);
public void insert(BPMNElementNode bpmnElementNode) {
// append flowNodeRef if not yet listed
if (!contains(bpmnElementNode)) {
Element flowNodeRef = model.createElement(BPMNNS.BPMN2, "flowNodeRef");
Text textNode = this.getDoc().createTextNode(bpmnElementNode.getId());
flowNodeRef.appendChild(textNode);
this.getElementNode().appendChild(flowNodeRef);
}
}

/**
@@ -143,6 +145,32 @@ public boolean contains(BPMNElementNode bpmnElement) {
return false;
}

/**
* This method removes a given BPMNFlowElement from this lane
* <p>
* {@code
* <bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
<bpmn2:lane id="Lane_1" name="Lane 1">
<bpmn2:flowNodeRef>StartEvent_4</bpmn2:flowNodeRef>
}
*
* @param element
* @param laneId
* @throws BPMNInvalidReferenceException
*/
public void remove(BPMNElementNode bpmnElement) {
// remove flowNodeRef if listed
if (contains(bpmnElement)) {
Set<Element> refs = model.findChildNodesByName(this.getElementNode(), BPMNNS.BPMN2, "flowNodeRef");
for (Element element : refs) {
if (bpmnElement.getId().equals(element.getTextContent())) {
this.elementNode.removeChild(element);
break;
}
}
}
}

/**
* Returns a list of a all BPMNFlowElement IDs contained by this lane
*
@@ -157,6 +185,25 @@ public Set<String> getFlowElementIDs() {
return result;
}

/**
* This method adds a flowElementID to the lane
*
* @param id
*/
/*
* public void addFlowElementID(String id) {
* // test if the id is already listed...
* Set<String> refList = getFlowElementIDs();
* if (refList.contains(id)) {
* // already listed - no op
* return;
* }
* // add id....
* model.createElement(null, id)
*
* }
*/

@Override
public double getDefaultWidth() {
return DEFAULT_WIDTH;
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import org.openbpmn.bpmn.BPMNTypes;
import org.openbpmn.bpmn.elements.Association;
import org.openbpmn.bpmn.elements.BPMNProcess;
import org.openbpmn.bpmn.elements.Lane;
import org.openbpmn.bpmn.elements.Participant;
import org.openbpmn.bpmn.elements.SequenceFlow;
import org.openbpmn.bpmn.exceptions.BPMNInvalidReferenceException;
@@ -104,9 +105,36 @@ public BPMNBounds setBounds(double x, double y, double width, double height) thr
return bounds;
}

/**
* Update the absolute position of a BPMNElementNode.
*
* When BPMNElementNode is part of a participant with lanes, this method
* automatically updates the bpmn2:flowNodeRef of the containing lane.
*
* @param x
* @param y
*/
public void setPosition(double x, double y) {
try {
this.getBounds().setPosition(x, y);

// update lane flowNodeRef if the element is part of a pool with lanes....
if (BPMNTypes.isFlowElement(this)
&& this.getBpmnProcess().getProcessType() == BPMNTypes.PROCESS_TYPE_PRIVATE) {
// get all lanes and test if a lane is the containing lane according to the
// position.
Set<Lane> lanes = this.getBpmnProcess().getLanes();
for (Lane lane : lanes) {
BPMNBounds laneBounds = lane.getBounds();
if (laneBounds.containsPoint(new BPMNPoint(x, y))) {
// found containing lane!
lane.insert(this);
} else {
// remove if listed in this lane....
lane.remove(this);
}
}
}
} catch (BPMNMissingElementException e) {
BPMNModel.error("Failed to update bounds position for element '" + this.getId() + "'");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.openbpmn.metamodel.test.elements;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.util.Set;
import java.util.logging.Logger;

import org.junit.jupiter.api.Test;
import org.openbpmn.bpmn.BPMNModel;
import org.openbpmn.bpmn.BPMNTypes;
import org.openbpmn.bpmn.elements.Activity;
import org.openbpmn.bpmn.elements.BPMNProcess;
import org.openbpmn.bpmn.elements.Lane;
import org.openbpmn.bpmn.elements.Participant;
import org.openbpmn.bpmn.exceptions.BPMNModelException;
import org.openbpmn.bpmn.util.BPMNModelFactory;

/**
* This test class is testing the bpmn2:flowNodeRef element of a Lane within a
* participant.
*
* The flowNodeRef depends on the position of a flow element. If setPosition is
* called on a BPMNElementNode the flowNodeRef of a containing lane is
* automatically updated.
*
* @author rsoika
*
*/
public class TestFlowNodeRef {

private static Logger logger = Logger.getLogger(TestBPMNLanes.class.getName());

static BPMNModel model = null;

/**
* This test class creates a Collaboration model with a 2 BPMNLane and a flow
* element in one lane.
* The test verifies if the flowNodeRef of the lane is updated correctly.
*
* For this reason first a task is crated without a position. So it is not a
* nodeRef of any lane.
* Then the position is changed to become part of lane1 and next the position is
* changed to lane2
*/
@Test
public void testCreateCollaborationModelWithLane() {
String out = "src/test/resources/output/flownode-ref_1.bpmn";

logger.info("...create collaboration model with 2 lanes");

String exporter = "demo";
String version = "1.0.0";
String targetNameSpace = "http://org.openbpmn";
BPMNModel model = BPMNModelFactory.createInstance(exporter, version, targetNameSpace);

try {
assertEquals(1, model.getProcesses().size());

// create participant
Participant participantSales = model.addParticipant("Sales Team");
assertTrue(model.isCollaborationDiagram());
assertEquals(2, model.getProcesses().size());
assertEquals(2, model.getParticipants().size());

BPMNProcess process = participantSales.openProcess();
// add a new Lane
Lane laneA = process.addLane("Team-A");
assertNotNull(laneA);
Lane laneB = process.addLane("Team-B");
assertNotNull(laneB);

// add a task
Activity task = process.addTask("task_1", "Task", BPMNTypes.TASK);

// if the task has not yet a position, than we expect that the lane has no
// nodeRefs
Set<String> flowElementList = laneA.getFlowElementIDs();
assertNotNull(flowElementList);

assertEquals(0, flowElementList.size());

// now we set the position of the task ....
task.setPosition(160, 50);
// now the task should be part of laneA
flowElementList = laneA.getFlowElementIDs();
assertEquals(1, flowElementList.size());
assertEquals("task_1", flowElementList.iterator().next());

// next move the element to the second lane....
task.setPosition(160, 220);
flowElementList = laneA.getFlowElementIDs();
// in laneA no more nodeRefs are expected....
assertEquals(0, flowElementList.size());
// ...but in laneB....
flowElementList = laneB.getFlowElementIDs();
assertEquals(1, flowElementList.size());
assertEquals("task_1", flowElementList.iterator().next());

} catch (BPMNModelException e) {
e.printStackTrace();
fail();
}
assertNotNull(model);

model.save(out);
logger.info("...model created successful: " + out);
}

}

0 comments on commit ac642d3

Please sign in to comment.