Model Generator

This commit is contained in:
Ralph Soika 2026-01-07 21:25:58 +01:00
parent 627ff7c199
commit 3ea9767dac
9 changed files with 2855 additions and 187 deletions

View file

@ -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: ");
}
}

View file

@ -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();
}
}
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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">