Model Generator
This commit is contained in:
parent
627ff7c199
commit
3ea9767dac
9 changed files with 2855 additions and 187 deletions
|
|
@ -1,88 +0,0 @@
|
|||
package ai.dynamixs.api;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.File;
|
||||
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.Event;
|
||||
import org.openbpmn.bpmn.elements.core.BPMNPoint;
|
||||
import org.openbpmn.bpmn.exceptions.BPMNModelException;
|
||||
import org.openbpmn.bpmn.util.BPMNModelFactory;
|
||||
|
||||
/**
|
||||
* This class loads a BPMN 2.0 template and generates a model from a textual
|
||||
* process description.
|
||||
*
|
||||
* @author rsoika
|
||||
*
|
||||
*/
|
||||
public class GenerateModel {
|
||||
|
||||
private static Logger logger = Logger.getLogger(GenerateModel.class.getName());
|
||||
|
||||
static BPMNModel model = null;
|
||||
|
||||
/**
|
||||
* This test reads a bpmn file containing a DataObject
|
||||
*/
|
||||
@Test
|
||||
public void buildModel() {
|
||||
try {
|
||||
String out = "src/test/resources/process-example-en-0.0.1.bpmn";
|
||||
|
||||
logger.info("...read model");
|
||||
model = BPMNModelFactory.read("/template-en-0.0.0.bpmn");
|
||||
|
||||
BPMNProcess process = model.findProcessByName("Example");
|
||||
assertNotNull(process);
|
||||
assertEquals(BPMNTypes.PROCESS_TYPE_PRIVATE, process.getProcessType());
|
||||
|
||||
assertEquals(1, process.getActivities().size());
|
||||
Activity referenceTask = process.getActivities().iterator().next();
|
||||
Event referenceEvent = (Event) process.findElementById("event_vIjHLQ"); // .getEvents().iterator().next();
|
||||
|
||||
// add 2 Tasks and connect these Tasks with an event....
|
||||
// Create a Task1
|
||||
BPMNPoint position = new BPMNPoint(150, 200);
|
||||
int taskID = 1000;
|
||||
|
||||
Activity task1 = (Activity) process.cloneBPMNElementNode(referenceTask);
|
||||
task1.setName("Task-1");
|
||||
task1.setPosition(position);
|
||||
task1.setAttribute("imixs:processid", "" + taskID);
|
||||
taskID = taskID + 100;
|
||||
|
||||
// add a event
|
||||
Event event = (Event) process.cloneBPMNElementNode(referenceEvent);
|
||||
event.setName("Event-1");
|
||||
position.setX(position.getX() + 200);
|
||||
event.setPosition(position);
|
||||
|
||||
Activity task2 = (Activity) process.cloneBPMNElementNode(referenceTask);
|
||||
task1.setName("Task-2");
|
||||
position.setX(position.getX() + 100);
|
||||
task2.setPosition(position);
|
||||
task2.setAttribute("imixs:processid", "" + taskID);
|
||||
|
||||
process.addSequenceFlow("sequence-flow-1", task1.getId(), event.getId());
|
||||
process.addSequenceFlow("sequence-flow-2", event.getId(), task2.getId());
|
||||
|
||||
File file = new File(out);
|
||||
model.save(file);
|
||||
logger.info("...model created successful: " + out);
|
||||
} catch (BPMNModelException e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
logger.info("...model read successful: ");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package ai.dynamixs.model.builder;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.File;
|
||||
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.Event;
|
||||
import org.openbpmn.bpmn.exceptions.BPMNModelException;
|
||||
import org.openbpmn.bpmn.util.BPMNModelFactory;
|
||||
|
||||
/**
|
||||
* This class loads a BPMN 2.0 template and generates a model from a textual
|
||||
* process description.
|
||||
*/
|
||||
public class GenerateModel {
|
||||
|
||||
private static Logger logger = Logger.getLogger(GenerateModel.class.getName());
|
||||
|
||||
/**
|
||||
* Generates a BPMN model from a process description file.
|
||||
*/
|
||||
@Test
|
||||
public void buildModel() {
|
||||
try {
|
||||
String out = "src/test/resources/supplier-compliance-process.bpmn";
|
||||
String descriptionFile = "src/test/resources/process-description.txt";
|
||||
|
||||
logger.info("...read template");
|
||||
BPMNModel model = BPMNModelFactory.read("/template-en-0.0.0.bpmn");
|
||||
|
||||
BPMNProcess process = model.findProcessByName("Example");
|
||||
assertNotNull(process);
|
||||
assertEquals(BPMNTypes.PROCESS_TYPE_PRIVATE, process.getProcessType());
|
||||
assertEquals(1, process.getActivities().size());
|
||||
|
||||
Activity referenceTask = process.getActivities().iterator().next();
|
||||
Event referenceEvent = (Event) process.findElementById("event_vIjHLQ");
|
||||
|
||||
// Parse description and generate BPMN elements
|
||||
ProcessDescriptionParser parser = new ProcessDescriptionParser();
|
||||
parser.getLayoutCalculator().setStartPosition(300, 300);
|
||||
parser.parseAndGenerate(descriptionFile, process, referenceTask, referenceEvent);
|
||||
|
||||
// Save model
|
||||
File file = new File(out);
|
||||
model.save(file);
|
||||
|
||||
logger.info("...model created successful: " + out);
|
||||
|
||||
} catch (BPMNModelException e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package ai.dynamixs.api;
|
||||
package ai.dynamixs.model.builder;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
|
@ -42,6 +42,8 @@ public class GenerateModelDemo {
|
|||
model = BPMNModelFactory.read("/template-en-0.0.0.bpmn");
|
||||
|
||||
BPMNProcess process = model.findProcessByName("Example");
|
||||
process.addLane("Accounting");
|
||||
process.addLane("Sales Team");
|
||||
assertNotNull(process);
|
||||
assertEquals(BPMNTypes.PROCESS_TYPE_PRIVATE, process.getProcessType());
|
||||
|
||||
|
|
@ -63,6 +65,7 @@ public class GenerateModelDemo {
|
|||
// add a event
|
||||
Event event = (Event) process.cloneBPMNElementNode(referenceEvent);
|
||||
event.setName("Event-1");
|
||||
event.setAttribute("imixs:activityid", "" + 10);
|
||||
position.setX(position.getX() + 200);
|
||||
event.setPosition(position);
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package ai.dynamixs.model.builder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Calculates grid positions for BPMN elements (tasks, events, lanes).
|
||||
*/
|
||||
public class LayoutCalculator {
|
||||
|
||||
// Element dimensions
|
||||
public static final int TASK_WIDTH = 110;
|
||||
public static final int TASK_HEIGHT = 50;
|
||||
public static final int EVENT_SIZE = 36;
|
||||
public static final int LANE_HEIGHT = 230;
|
||||
|
||||
// Layout configuration
|
||||
private int startX = 100;
|
||||
private int startY = 100;
|
||||
private int taskSpacingX = 200;
|
||||
private int eventSpacingX = 50;
|
||||
|
||||
// Calculated positions
|
||||
private Map<Integer, double[]> taskPositions = new HashMap<>(); // taskId -> [x, y]
|
||||
private Map<String, double[]> eventPositions = new HashMap<>(); // "taskId_eventId" -> [x, y]
|
||||
private Map<String, Integer> laneIndexMap = new HashMap<>(); // teamName -> laneIndex (0-based)
|
||||
|
||||
/**
|
||||
* Registers lanes and calculates their order.
|
||||
*
|
||||
* @param laneNames List of lane names in order
|
||||
*/
|
||||
public void calculateLanePositions(List<String> laneNames) {
|
||||
laneIndexMap.clear();
|
||||
int index = 0;
|
||||
for (String laneName : laneNames) {
|
||||
if (!laneIndexMap.containsKey(laneName)) {
|
||||
laneIndexMap.put(laneName, index++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Y position for a lane.
|
||||
*/
|
||||
public double getLaneY(String laneName) {
|
||||
Integer index = laneIndexMap.get(laneName);
|
||||
if (index == null)
|
||||
return startY;
|
||||
return startY + (index * LANE_HEIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates positions for all tasks.
|
||||
*
|
||||
* @param taskIds List of task IDs in order
|
||||
* @param taskLanes Map of task ID to lane name
|
||||
*/
|
||||
public void calculateTaskPositions(List<Integer> taskIds, Map<Integer, String> taskLanes) {
|
||||
taskPositions.clear();
|
||||
double currentX = startX;
|
||||
|
||||
for (Integer taskId : taskIds) {
|
||||
String lane = taskLanes.get(taskId);
|
||||
double y = getLaneY(lane) + (LANE_HEIGHT / 2.0) - (TASK_HEIGHT / 2.0); // Center in lane
|
||||
taskPositions.put(taskId, new double[] { currentX, y });
|
||||
currentX += TASK_WIDTH + taskSpacingX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates position for an event.
|
||||
*
|
||||
* @param sourceTaskId The source task ID
|
||||
* @param eventId The event ID
|
||||
* @param eventIndex Index of this event among all events of the source task
|
||||
* (0-based)
|
||||
* @param laneName The lane name where the event should be placed
|
||||
*/
|
||||
public void calculateEventPosition(int sourceTaskId, int eventId, int eventIndex, String laneName) {
|
||||
double[] taskPos = taskPositions.get(sourceTaskId);
|
||||
if (taskPos == null)
|
||||
return;
|
||||
|
||||
double eventX = taskPos[0] + (TASK_WIDTH / 2.0) - (EVENT_SIZE / 2.0) + (eventIndex * eventSpacingX);
|
||||
double eventY = getLaneY(laneName) + (LANE_HEIGHT / 2.0) + (TASK_HEIGHT / 2.0) + 20; // Below task in same lane
|
||||
|
||||
eventPositions.put(sourceTaskId + "_" + eventId, new double[] { eventX, eventY });
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of a task.
|
||||
*/
|
||||
public double[] getTaskPosition(int taskId) {
|
||||
return taskPositions.get(taskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of an event.
|
||||
*/
|
||||
public double[] getEventPosition(int sourceTaskId, int eventId) {
|
||||
return eventPositions.get(sourceTaskId + "_" + eventId);
|
||||
}
|
||||
|
||||
// Configuration setters
|
||||
public void setStartPosition(int x, int y) {
|
||||
this.startX = x;
|
||||
this.startY = y;
|
||||
}
|
||||
|
||||
public void setTaskSpacingX(int spacing) {
|
||||
this.taskSpacingX = spacing;
|
||||
}
|
||||
|
||||
public void setEventSpacingX(int spacing) {
|
||||
this.eventSpacingX = spacing;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
package ai.dynamixs.model.builder;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openbpmn.bpmn.elements.Activity;
|
||||
import org.openbpmn.bpmn.elements.BPMNProcess;
|
||||
import org.openbpmn.bpmn.elements.Event;
|
||||
import org.openbpmn.bpmn.elements.core.BPMNPoint;
|
||||
import org.openbpmn.bpmn.exceptions.BPMNModelException;
|
||||
|
||||
/**
|
||||
* Parses a process description file and generates BPMN elements. Uses
|
||||
* LayoutCalculator for positioning of elements.
|
||||
*/
|
||||
public class ProcessDescriptionParser {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ProcessDescriptionParser.class.getName());
|
||||
|
||||
// Regex patterns
|
||||
private static final Pattern TASK_PATTERN = Pattern.compile(
|
||||
"\\|-\\s*\\[Task:\\s*(\\d+)\\]\\s*(.+)$");
|
||||
private static final Pattern EVENT_PATTERN = Pattern.compile(
|
||||
"\\|--\\s*\\[Event:\\s*(\\d+)\\]\\s*([^(]+)\\s*\\([^)]*\\)\\s*-->\\s*\\[Task:\\s*(\\d+)\\]");
|
||||
|
||||
// Layout calculator
|
||||
private LayoutCalculator layoutCalculator = new LayoutCalculator();
|
||||
|
||||
// Storage for created elements
|
||||
private Map<Integer, Activity> tasks = new HashMap<>();
|
||||
private List<EventData> events = new ArrayList<>();
|
||||
private Map<Integer, String> taskLanes = new HashMap<>();
|
||||
private int sequenceFlowCounter = 1;
|
||||
|
||||
/**
|
||||
* Internal class to hold event data before creating BPMN elements.
|
||||
*/
|
||||
private static class EventData {
|
||||
int eventId;
|
||||
String name;
|
||||
int sourceTaskId;
|
||||
int targetTaskId;
|
||||
|
||||
EventData(int eventId, String name, int sourceTaskId, int targetTaskId) {
|
||||
this.eventId = eventId;
|
||||
this.name = name;
|
||||
this.sourceTaskId = sourceTaskId;
|
||||
this.targetTaskId = targetTaskId;
|
||||
}
|
||||
|
||||
String getKey() {
|
||||
return sourceTaskId + "_" + eventId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple data holder for tasks during parsing.
|
||||
*/
|
||||
private static class TaskData {
|
||||
int id;
|
||||
String name;
|
||||
String description;
|
||||
String team;
|
||||
|
||||
TaskData(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the description file and creates all BPMN elements in the process.
|
||||
*/
|
||||
public void parseAndGenerate(String filePath, BPMNProcess process,
|
||||
Activity referenceTask, Event referenceEvent) throws IOException, BPMNModelException {
|
||||
|
||||
tasks.clear();
|
||||
events.clear();
|
||||
taskLanes.clear();
|
||||
|
||||
// Parse file and collect task/event data
|
||||
List<TaskData> taskDataList = parseFile(filePath);
|
||||
|
||||
// Collect unique lanes (in order of first appearance)
|
||||
List<String> laneNames = new ArrayList<>();
|
||||
for (TaskData taskData : taskDataList) {
|
||||
if (taskData.team != null && !laneNames.contains(taskData.team)) {
|
||||
laneNames.add(taskData.team);
|
||||
}
|
||||
taskLanes.put(taskData.id, taskData.team);
|
||||
}
|
||||
|
||||
// Create BPMN lanes
|
||||
for (String laneName : laneNames) {
|
||||
process.addLane(laneName);
|
||||
logger.info("Created lane: " + laneName);
|
||||
}
|
||||
|
||||
// Calculate layout
|
||||
layoutCalculator.calculateLanePositions(laneNames);
|
||||
|
||||
List<Integer> taskIds = taskDataList.stream().map(t -> t.id).toList();
|
||||
layoutCalculator.calculateTaskPositions(taskIds, taskLanes);
|
||||
|
||||
// Calculate layout for all events
|
||||
for (EventData eventData : events) {
|
||||
int eventIndex = getEventIndex(eventData.sourceTaskId, eventData.eventId);
|
||||
String laneName = taskLanes.get(eventData.sourceTaskId);
|
||||
layoutCalculator.calculateEventPosition(eventData.sourceTaskId, eventData.eventId, eventIndex, laneName);
|
||||
}
|
||||
|
||||
// Create BPMN tasks
|
||||
createTasks(taskDataList, process, referenceTask);
|
||||
|
||||
// Create BPMN events
|
||||
Map<String, Event> createdEvents = createEvents(process, referenceEvent);
|
||||
|
||||
// Create sequence flows
|
||||
createSequenceFlows(process, createdEvents);
|
||||
|
||||
logger.info("Generated " + tasks.size() + " tasks, " + createdEvents.size() + " events, " + laneNames.size()
|
||||
+ " lanes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the file and returns task data list. Also populates events list.
|
||||
*/
|
||||
private List<TaskData> parseFile(String filePath) throws IOException {
|
||||
List<TaskData> taskDataList = new ArrayList<>();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
|
||||
String line;
|
||||
TaskData currentTask = null;
|
||||
StringBuilder descBuilder = new StringBuilder();
|
||||
boolean readingDesc = false;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String trimmed = line.trim();
|
||||
|
||||
// Match task
|
||||
Matcher taskMatcher = TASK_PATTERN.matcher(trimmed);
|
||||
if (taskMatcher.find()) {
|
||||
if (currentTask != null) {
|
||||
currentTask.description = descBuilder.toString().trim();
|
||||
}
|
||||
currentTask = new TaskData(
|
||||
Integer.parseInt(taskMatcher.group(1)),
|
||||
taskMatcher.group(2).trim());
|
||||
taskDataList.add(currentTask);
|
||||
descBuilder = new StringBuilder();
|
||||
readingDesc = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Match team
|
||||
if (trimmed.contains("Team:") && currentTask != null) {
|
||||
int teamIndex = trimmed.indexOf("Team:");
|
||||
currentTask.team = trimmed.substring(teamIndex + 5).trim();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Match event
|
||||
Matcher eventMatcher = EVENT_PATTERN.matcher(trimmed);
|
||||
if (eventMatcher.find() && currentTask != null) {
|
||||
readingDesc = false;
|
||||
events.add(new EventData(
|
||||
Integer.parseInt(eventMatcher.group(1)),
|
||||
eventMatcher.group(2).trim(),
|
||||
currentTask.id,
|
||||
Integer.parseInt(eventMatcher.group(3))));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Description handling
|
||||
if (trimmed.contains("Description:")) {
|
||||
readingDesc = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (readingDesc && currentTask != null && !trimmed.startsWith("|--")) {
|
||||
String descLine = trimmed.replaceAll("^\\|\\s*", "").trim();
|
||||
if (!descLine.isEmpty()) {
|
||||
if (descBuilder.length() > 0)
|
||||
descBuilder.append(" ");
|
||||
descBuilder.append(descLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentTask != null) {
|
||||
currentTask.description = descBuilder.toString().trim();
|
||||
}
|
||||
}
|
||||
|
||||
return taskDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates BPMN task elements.
|
||||
*/
|
||||
private void createTasks(List<TaskData> taskDataList, BPMNProcess process,
|
||||
Activity referenceTask) throws BPMNModelException {
|
||||
|
||||
for (TaskData taskData : taskDataList) {
|
||||
double[] pos = layoutCalculator.getTaskPosition(taskData.id);
|
||||
|
||||
Activity task = (Activity) process.cloneBPMNElementNode(referenceTask);
|
||||
task.setName(taskData.name);
|
||||
task.setPosition(new BPMNPoint(pos[0], pos[1]));
|
||||
task.setAttribute("imixs:processid", String.valueOf(taskData.id));
|
||||
|
||||
if (taskData.description != null && !taskData.description.isEmpty()) {
|
||||
task.setDocumentation(taskData.description);
|
||||
}
|
||||
|
||||
tasks.put(taskData.id, task);
|
||||
logger.info("Created task: " + taskData.id + " - " + taskData.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates BPMN event elements.
|
||||
*/
|
||||
private Map<String, Event> createEvents(BPMNProcess process,
|
||||
Event referenceEvent) throws BPMNModelException {
|
||||
|
||||
Map<String, Event> createdEvents = new HashMap<>();
|
||||
|
||||
for (EventData eventData : events) {
|
||||
double[] pos = layoutCalculator.getEventPosition(eventData.sourceTaskId, eventData.eventId);
|
||||
if (pos == null)
|
||||
continue;
|
||||
|
||||
Event event = (Event) process.cloneBPMNElementNode(referenceEvent);
|
||||
event.setName(eventData.name);
|
||||
event.setPosition(new BPMNPoint(pos[0], pos[1]));
|
||||
// Calculate activity ID: first event = 10, second = 20, etc. (per task)
|
||||
int eventIndex = getEventIndex(eventData.sourceTaskId, eventData.eventId);
|
||||
int activityId = (eventIndex + 1) * 10;
|
||||
event.setAttribute("imixs:activityid", String.valueOf(activityId));
|
||||
|
||||
createdEvents.put(eventData.getKey(), event);
|
||||
logger.info("Created event: " + eventData.getKey() + " - " + eventData.name);
|
||||
}
|
||||
|
||||
return createdEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates sequence flows between tasks and events.
|
||||
*/
|
||||
private void createSequenceFlows(BPMNProcess process,
|
||||
Map<String, Event> createdEvents) throws BPMNModelException {
|
||||
|
||||
for (EventData eventData : events) {
|
||||
Activity sourceTask = tasks.get(eventData.sourceTaskId);
|
||||
Event event = createdEvents.get(eventData.getKey());
|
||||
Activity targetTask = tasks.get(eventData.targetTaskId);
|
||||
|
||||
if (sourceTask == null || event == null || targetTask == null)
|
||||
continue;
|
||||
|
||||
if (eventData.sourceTaskId == eventData.targetTaskId) {
|
||||
// Self-loop (CatchEvent): only sequence flow from event to task
|
||||
process.addSequenceFlow("sf-" + sequenceFlowCounter++, event.getId(), targetTask.getId());
|
||||
} else {
|
||||
// Normal flow: task -> event -> target task
|
||||
process.addSequenceFlow("sf-" + sequenceFlowCounter++, sourceTask.getId(), event.getId());
|
||||
process.addSequenceFlow("sf-" + sequenceFlowCounter++, event.getId(), targetTask.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of an event among all events of a source task.
|
||||
*/
|
||||
private int getEventIndex(int taskId, int eventId) {
|
||||
int index = 0;
|
||||
for (EventData e : events) {
|
||||
if (e.sourceTaskId == taskId) {
|
||||
if (e.eventId == eventId)
|
||||
return index;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout calculator for configuration.
|
||||
*/
|
||||
public LayoutCalculator getLayoutCalculator() {
|
||||
return layoutCalculator;
|
||||
}
|
||||
}
|
||||
|
|
@ -53,10 +53,12 @@
|
|||
<bpmn2:flowNodeRef>StartEvent_1</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>EndEvent_2</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>event_vIjHLQ</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>task_4bAwfw</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>task_2sKNSg</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>event_rprNxA</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>task_HQd8AQ</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>event_6HJvNQ</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>task_HQ9VcQ</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
<bpmn2:lane id="lane_EQOgOg" name="Accounting"/>
|
||||
<bpmn2:lane id="lane_2tdU0Q" name="Sales Team"/>
|
||||
</bpmn2:laneSet>
|
||||
<bpmn2:startEvent id="StartEvent_1" name="Start">
|
||||
<bpmn2:documentation id="documentation_IUTaAQ"/>
|
||||
|
|
@ -123,13 +125,7 @@
|
|||
<bpmn2:sequenceFlow id="sequenceFlow_khuDtw" sourceRef="event_vIjHLQ" targetRef="Task_2">
|
||||
<bpmn2:documentation id="documentation_d1EdlQ"/>
|
||||
</bpmn2:sequenceFlow>
|
||||
<bpmn2:sequenceFlow id="sequence-flow-1" sourceRef="task_4bAwfw" targetRef="event_rprNxA">
|
||||
<bpmn2:documentation id="documentation_exwr0g"/>
|
||||
</bpmn2:sequenceFlow>
|
||||
<bpmn2:sequenceFlow id="sequence-flow-2" sourceRef="event_rprNxA" targetRef="task_2sKNSg">
|
||||
<bpmn2:documentation id="documentation_MtemGg"/>
|
||||
</bpmn2:sequenceFlow>
|
||||
<bpmn2:task id="task_4bAwfw" imixs:processid="1000" name="Task-2">
|
||||
<bpmn2:task id="task_HQd8AQ" imixs:processid="1000" name="Task-2">
|
||||
<bpmn2:extensionElements>
|
||||
<imixs:item name="txteditorid" type="xs:string">
|
||||
<imixs:value><![CDATA[form_basic]]></imixs:value>
|
||||
|
|
@ -168,56 +164,58 @@
|
|||
<imixs:value><![CDATA[process.manager]]></imixs:value>
|
||||
</imixs:item>
|
||||
</bpmn2:extensionElements>
|
||||
<bpmn2:documentation id="documentation_yBXHfg"/>
|
||||
<bpmn2:documentation id="documentation_z6PPww"/>
|
||||
<bpmn2:outgoing>sequence-flow-1</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:task id="task_2sKNSg" imixs:processid="1100" name="Import">
|
||||
<bpmn2:extensionElements>
|
||||
<imixs:item name="txteditorid" type="xs:string">
|
||||
<imixs:value><![CDATA[form_basic]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtname" type="xs:string">
|
||||
<imixs:value><![CDATA[Rechnung erhalten]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtimageurl" type="xs:string">
|
||||
<imixs:value><![CDATA[typcn-business-card]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtworkflowsummary" type="xs:string">
|
||||
<imixs:value><![CDATA[<itemvalue>request.subject</itemvalue>]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyupdateacl" type="xs:string">
|
||||
<imixs:value><![CDATA[true]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txttype" type="xs:string">
|
||||
<imixs:value><![CDATA[workitem]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="namownershipnames" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="namaddreadaccess" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="namaddwriteaccess" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyownershipfields" type="xs:string">
|
||||
<imixs:value><![CDATA[$Editor]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.assist]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyaddwritefields" type="xs:string">
|
||||
<imixs:value><![CDATA[process.assist]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.team]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.manager]]></imixs:value>
|
||||
</imixs:item>
|
||||
</bpmn2:extensionElements>
|
||||
<bpmn2:documentation id="documentation_5oRV2g"/>
|
||||
<bpmn2:incoming>sequence-flow-2</bpmn2:incoming>
|
||||
</bpmn2:task>
|
||||
<bpmn2:intermediateCatchEvent id="event_rprNxA" imixs:activityid="10" name="Event-1">
|
||||
<bpmn2:documentation id="documentation_OeRSQQ"/>
|
||||
<bpmn2:intermediateCatchEvent id="event_6HJvNQ" imixs:activityid="10" name="Event-1">
|
||||
<bpmn2:documentation id="documentation_PoRwdg"/>
|
||||
<bpmn2:incoming>sequence-flow-1</bpmn2:incoming>
|
||||
<bpmn2:outgoing>sequence-flow-2</bpmn2:outgoing>
|
||||
</bpmn2:intermediateCatchEvent>
|
||||
<bpmn2:task id="task_HQ9VcQ" imixs:processid="1100" name="Import">
|
||||
<bpmn2:extensionElements>
|
||||
<imixs:item name="txteditorid" type="xs:string">
|
||||
<imixs:value><![CDATA[form_basic]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtname" type="xs:string">
|
||||
<imixs:value><![CDATA[Rechnung erhalten]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtimageurl" type="xs:string">
|
||||
<imixs:value><![CDATA[typcn-business-card]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txtworkflowsummary" type="xs:string">
|
||||
<imixs:value><![CDATA[<itemvalue>request.subject</itemvalue>]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyupdateacl" type="xs:string">
|
||||
<imixs:value><![CDATA[true]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="txttype" type="xs:string">
|
||||
<imixs:value><![CDATA[workitem]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="namownershipnames" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="namaddreadaccess" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="namaddwriteaccess" type="xs:string">
|
||||
<imixs:value/>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyownershipfields" type="xs:string">
|
||||
<imixs:value><![CDATA[$Editor]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.assist]]></imixs:value>
|
||||
</imixs:item>
|
||||
<imixs:item name="keyaddwritefields" type="xs:string">
|
||||
<imixs:value><![CDATA[process.assist]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.team]]></imixs:value>
|
||||
<imixs:value><![CDATA[process.manager]]></imixs:value>
|
||||
</imixs:item>
|
||||
</bpmn2:extensionElements>
|
||||
<bpmn2:documentation id="documentation_CdXjvg"/>
|
||||
<bpmn2:incoming>sequence-flow-2</bpmn2:incoming>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="sequence-flow-1" sourceRef="task_HQd8AQ" targetRef="event_6HJvNQ"/>
|
||||
<bpmn2:sequenceFlow id="sequence-flow-2" sourceRef="event_6HJvNQ" targetRef="task_HQ9VcQ"/>
|
||||
</bpmn2:process>
|
||||
<bpmn2:process id="process_2" name="Default Process" processType="Public">
|
||||
<bpmn2:documentation id="documentation_imRbaw"/>
|
||||
|
|
@ -234,15 +232,15 @@
|
|||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane bpmnElement="Collaboration_1" id="BPMNPlane_Process_1">
|
||||
<bpmndi:BPMNShape bpmnElement="Participant_1" id="BPMNShape_Participant_1" isHorizontal="true">
|
||||
<dc:Bounds height="1150.0" width="4530.0" x="20.0" y="90.0"/>
|
||||
<dc:Bounds height="690.0" width="4430.0" x="130.0" y="90.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="Lane_1" id="BPMNShape_Lane_1" isHorizontal="true">
|
||||
<dc:Bounds height="1150.0" width="4500.0" x="50.0" y="90.0"/>
|
||||
<dc:Bounds height="230.0" width="4400.0" x="160.0" y="90.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="StartEvent_1" id="BPMNShape_StartEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="137.0" y="337.0"/>
|
||||
<dc:Bounds height="36.0" width="36.0" x="237.0" y="137.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_1" labelStyle="BPMNLabelStyle_1">
|
||||
<dc:Bounds height="20.0" width="100.0" x="109.5" y="374.10797119140625"/>
|
||||
<dc:Bounds height="20.0" width="100.0" x="209.5" y="174.10797119140625"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="BPMNShape_TextAnnotation_1">
|
||||
|
|
@ -252,12 +250,12 @@
|
|||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="Task_2" id="BPMNShape_Task_5">
|
||||
<dc:Bounds height="50.0" width="110.0" x="380.0" y="330.0"/>
|
||||
<dc:Bounds height="50.0" width="110.0" x="490.0" y="130.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="EndEvent_2" id="BPMNShape_EndEvent_2">
|
||||
<dc:Bounds height="36.0" width="36.0" x="597.0" y="337.0"/>
|
||||
<dc:Bounds height="36.0" width="36.0" x="697.0" y="137.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_110" labelStyle="BPMNLabelStyle_1">
|
||||
<dc:Bounds height="20.0" width="100.0" x="571.138671875" y="375.10791015625"/>
|
||||
<dc:Bounds height="20.0" width="100.0" x="671.138671875" y="175.10791015625"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="participant_hnZfjA" id="BPMNShape_iHhp5Q">
|
||||
|
|
@ -270,42 +268,48 @@
|
|||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="event_vIjHLQ" id="BPMNShape_U2OU0Q">
|
||||
<dc:Bounds height="36.0" width="36.0" x="267.0" y="337.0"/>
|
||||
<dc:Bounds height="36.0" width="36.0" x="367.0" y="137.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_vd0n1w">
|
||||
<dc:Bounds height="20.0" width="100.0" x="235.0" y="376.0"/>
|
||||
<dc:Bounds height="20.0" width="100.0" x="335.0" y="176.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_8NDJxA" id="BPMNEdge_5jeXwQ" sourceElement="BPMNShape_StartEvent_1" targetElement="BPMNShape_U2OU0Q">
|
||||
<di:waypoint x="173.0" y="355.0"/>
|
||||
<di:waypoint x="267.0" y="355.0"/>
|
||||
<di:waypoint x="273.0" y="155.0"/>
|
||||
<di:waypoint x="367.0" y="155.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_Gj9mmA" id="BPMNEdge_D8ZZAw" sourceElement="BPMNShape_Task_5" targetElement="BPMNShape_EndEvent_2">
|
||||
<di:waypoint x="490.0" y="355.0"/>
|
||||
<di:waypoint x="597.0" y="355.0"/>
|
||||
<di:waypoint x="600.0" y="155.0"/>
|
||||
<di:waypoint x="697.0" y="155.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_khuDtw" id="BPMNEdge_vHtmSA" sourceElement="BPMNShape_U2OU0Q" targetElement="BPMNShape_Task_5">
|
||||
<di:waypoint x="303.0" y="355.0"/>
|
||||
<di:waypoint x="380.0" y="355.0"/>
|
||||
<di:waypoint x="403.0" y="155.0"/>
|
||||
<di:waypoint x="490.0" y="155.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape bpmnElement="task_4bAwfw" id="BPMNShape_2rc7nw">
|
||||
<bpmndi:BPMNShape bpmnElement="lane_EQOgOg" id="BPMNShape_Lane_vbFCIg">
|
||||
<dc:Bounds height="230.0" width="4400.0" x="160.0" y="320.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="lane_2tdU0Q" id="BPMNShape_Lane_AJQqiw">
|
||||
<dc:Bounds height="230.0" width="4400.0" x="160.0" y="550.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="task_HQd8AQ" id="BPMNShape_SWNkXw">
|
||||
<dc:Bounds height="50.0" width="110.0" x="150.0" y="200.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="event_rprNxA" id="BPMNShape_LvX3vQ">
|
||||
<dc:Bounds height="36.0" width="36.0" x="337.0" y="207.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_MoU59Q">
|
||||
<dc:Bounds height="20.0" width="100.0" x="308.0" y="249.0"/>
|
||||
<bpmndi:BPMNShape bpmnElement="event_6HJvNQ" id="BPMNShape_GCOCOA">
|
||||
<dc:Bounds height="36.0" width="36.0" x="350.0" y="200.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_K3GzxA">
|
||||
<dc:Bounds x="0.0" y="0.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="task_2sKNSg" id="BPMNShape_g0YqGA">
|
||||
<dc:Bounds height="50.0" width="110.0" x="500.0" y="200.0"/>
|
||||
<bpmndi:BPMNShape bpmnElement="task_HQ9VcQ" id="BPMNShape_0vb1vw">
|
||||
<dc:Bounds height="50.0" width="110.0" x="450.0" y="200.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequence-flow-1" id="BPMNEdge_Y0ARBQ" sourceElement="BPMNShape_2rc7nw" targetElement="BPMNShape_LvX3vQ">
|
||||
<di:waypoint x="260.0" y="225.0"/>
|
||||
<di:waypoint x="337.0" y="225.0"/>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequence-flow-1" id="BPMNEdge_nhNbcg" sourceElement="BPMNShape_SWNkXw" targetElement="BPMNShape_GCOCOA">
|
||||
<di:waypoint x="205.0" y="225.0"/>
|
||||
<di:waypoint x="368.0" y="218.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequence-flow-2" id="BPMNEdge_TVjsMg" sourceElement="BPMNShape_LvX3vQ" targetElement="BPMNShape_g0YqGA">
|
||||
<di:waypoint x="373.0" y="225.0"/>
|
||||
<di:waypoint x="500.0" y="225.0"/>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequence-flow-2" id="BPMNEdge_NLlZ5g" sourceElement="BPMNShape_GCOCOA" targetElement="BPMNShape_0vb1vw">
|
||||
<di:waypoint x="368.0" y="218.0"/>
|
||||
<di:waypoint x="505.0" y="225.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1109
dynamixs-ai-app/src/test/resources/supplier-compliance-process.bpmn
Normal file
1109
dynamixs-ai-app/src/test/resources/supplier-compliance-process.bpmn
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -136,15 +136,15 @@
|
|||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane bpmnElement="Collaboration_1" id="BPMNPlane_Process_1">
|
||||
<bpmndi:BPMNShape bpmnElement="Participant_1" id="BPMNShape_Participant_1" isHorizontal="true">
|
||||
<dc:Bounds height="1150.0" width="4530.0" x="20.0" y="90.0"/>
|
||||
<dc:Bounds height="230.0" width="4430.0" x="130.0" y="90.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="Lane_1" id="BPMNShape_Lane_1" isHorizontal="true">
|
||||
<dc:Bounds height="1150.0" width="4500.0" x="50.0" y="90.0"/>
|
||||
<dc:Bounds height="230.0" width="4400.0" x="160.0" y="90.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="StartEvent_1" id="BPMNShape_StartEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="137.0" y="337.0"/>
|
||||
<dc:Bounds height="36.0" width="36.0" x="237.0" y="137.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_1" labelStyle="BPMNLabelStyle_1">
|
||||
<dc:Bounds height="20.0" width="100.0" x="109.5" y="374.10797119140625"/>
|
||||
<dc:Bounds height="20.0" width="100.0" x="209.5" y="174.10797119140625"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="BPMNShape_TextAnnotation_1">
|
||||
|
|
@ -154,12 +154,12 @@
|
|||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="Task_2" id="BPMNShape_Task_5">
|
||||
<dc:Bounds height="50.0" width="110.0" x="380.0" y="330.0"/>
|
||||
<dc:Bounds height="50.0" width="110.0" x="490.0" y="130.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="EndEvent_2" id="BPMNShape_EndEvent_2">
|
||||
<dc:Bounds height="36.0" width="36.0" x="597.0" y="337.0"/>
|
||||
<dc:Bounds height="36.0" width="36.0" x="697.0" y="137.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_110" labelStyle="BPMNLabelStyle_1">
|
||||
<dc:Bounds height="20.0" width="100.0" x="571.138671875" y="375.10791015625"/>
|
||||
<dc:Bounds height="20.0" width="100.0" x="671.138671875" y="175.10791015625"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="participant_hnZfjA" id="BPMNShape_iHhp5Q">
|
||||
|
|
@ -172,22 +172,22 @@
|
|||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="event_vIjHLQ" id="BPMNShape_U2OU0Q">
|
||||
<dc:Bounds height="36.0" width="36.0" x="267.0" y="337.0"/>
|
||||
<dc:Bounds height="36.0" width="36.0" x="367.0" y="137.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_vd0n1w">
|
||||
<dc:Bounds height="20.0" width="100.0" x="235.0" y="376.0"/>
|
||||
<dc:Bounds height="20.0" width="100.0" x="335.0" y="176.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_8NDJxA" id="BPMNEdge_5jeXwQ" sourceElement="BPMNShape_StartEvent_1" targetElement="BPMNShape_U2OU0Q">
|
||||
<di:waypoint x="173.0" y="355.0"/>
|
||||
<di:waypoint x="267.0" y="355.0"/>
|
||||
<di:waypoint x="273.0" y="155.0"/>
|
||||
<di:waypoint x="367.0" y="155.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_Gj9mmA" id="BPMNEdge_D8ZZAw" sourceElement="BPMNShape_Task_5" targetElement="BPMNShape_EndEvent_2">
|
||||
<di:waypoint x="490.0" y="355.0"/>
|
||||
<di:waypoint x="597.0" y="355.0"/>
|
||||
<di:waypoint x="600.0" y="155.0"/>
|
||||
<di:waypoint x="697.0" y="155.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_khuDtw" id="BPMNEdge_vHtmSA" sourceElement="BPMNShape_U2OU0Q" targetElement="BPMNShape_Task_5">
|
||||
<di:waypoint x="303.0" y="355.0"/>
|
||||
<di:waypoint x="380.0" y="355.0"/>
|
||||
<di:waypoint x="403.0" y="155.0"/>
|
||||
<di:waypoint x="490.0" y="155.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
|
||||
|
|
|
|||
Loading…
Reference in a new issue