Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/subprocess handling with QRM #61

Merged
merged 20 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c36a350
expand/collapse subprocess based on replacement in QRM
LaviniaStiliadou Jun 4, 2023
d51f165
remove isExpanded attribute from shapes
LaviniaStiliadou Jun 4, 2023
4428ab0
Merge remote-tracking branch 'origin/master' into fix/subprocess-hand…
wederbn Jun 15, 2023
3f283b7
handle different namespace
LaviniaStiliadou Jun 20, 2023
77a6208
Merge branch 'master' of https://github.com/PlanQK/workflow-modeler i…
LaviniaStiliadou Jun 20, 2023
b74f7dc
Update package-lock.json
LaviniaStiliadou Jun 20, 2023
cdea7b2
Merge branch 'master' of https://github.com/PlanQK/workflow-modeler i…
LaviniaStiliadou Jun 23, 2023
1ad15b6
set isExpanded of nested subprocess
LaviniaStiliadou Jun 23, 2023
5d2b535
remove isExpand attribute also from nested subprocess,
LaviniaStiliadou Jun 24, 2023
c2e9d56
fix test
LaviniaStiliadou Jun 24, 2023
aaea091
remove isexpanded from nested subprocess
LaviniaStiliadou Jul 13, 2023
42c954f
fix collapsed subprocess
LaviniaStiliadou Jul 23, 2023
b73fee4
change repo for maxcut qrm
LaviniaStiliadou Jul 25, 2023
fd24add
Merge remote-tracking branch 'origin/master' into fix/subprocess-hand…
wederbn Jul 25, 2023
744f05f
fix replacement of collapsed subprocess
LaviniaStiliadou Aug 22, 2023
944eb57
enable setting camunda_endpoint via env_vars
mbeisel Aug 22, 2023
7578d34
remove top-level isexpanded attribute
LaviniaStiliadou Aug 22, 2023
1fb0e4a
Merge branch 'master' into fix/subprocess-handling
wederbn Aug 25, 2023
cd65db0
Remove unused method and fix method comment
wederbn Aug 25, 2023
14a209a
Fix typo in method name
wederbn Aug 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {isFlowLikeElement} from './ModellingUtilities';
import {getDi, is} from 'bpmn-js/lib/util/ModelUtil';
import { isFlowLikeElement } from './ModellingUtilities';
import { getDi, is } from 'bpmn-js/lib/util/ModelUtil';

/**
* Insert the given element and all child elements into the diagram
Expand Down Expand Up @@ -30,18 +30,18 @@ export function insertShape(definitions, parent, newElement, idMap, replace, mod
if (replace) {

// replace old element to retain attached sequence flow, associations, data objects, ...
element = bpmnReplace.replaceElement(elementRegistry.get(oldElement.id), {type: newElement.$type});
element = bpmnReplace.replaceElement(elementRegistry.get(oldElement.id), { type: newElement.$type });
} else {

// create new shape for this element
element = modeling.createShape({type: newElement.$type}, {x: 50, y: 50}, parent, {});
element = modeling.createShape({ type: newElement.$type }, { x: 50, y: 50 }, parent, {});
}
} else {

// create connection between two previously created elements
let sourceElement = elementRegistry.get(idMap[newElement.sourceRef.id]);
let targetElement = elementRegistry.get(idMap[newElement.targetRef.id]);
element = modeling.connect(sourceElement, targetElement, {type: newElement.$type});
element = modeling.connect(sourceElement, targetElement, { type: newElement.$type });
}

// store id to create sequence flows
Expand All @@ -52,13 +52,11 @@ export function insertShape(definitions, parent, newElement, idMap, replace, mod

// get the shape element related to the subprocess
let shape = getDi(element);
shape.isExpanded = true;

// TODO: fix the following if, as the access to the DI of the new element is not possible with the current BPMN-JS version
/*if (shape && shape.isExpanded) {
// expand the new element
elementRegistry.get(element.id).businessObject.di.isExpanded = true;
}*/
// expand the replacement subprocess if the detector subprocess was expanded
if (shape && (newElement.isExpanded === 'true')) {
shape.isExpanded = true;
}

// preserve messages defined in ReceiveTasks
} else if (newElement.$type === 'bpmn:ReceiveTask' && newElement.messageRef) {
Expand All @@ -71,21 +69,21 @@ export function insertShape(definitions, parent, newElement, idMap, replace, mod
let message = bpmnFactory.create('bpmn:Message');
message.name = oldMessage.name;
definitions.rootElements.push(message);
modeling.updateProperties(element, {'messageRef': message});
modeling.updateProperties(element, { 'messageRef': message });

// store id if other receive tasks reference the same message
idMap[oldMessage.id] = message.id;
} else {

// reuse already created message and add it to receive task
modeling.updateProperties(element, {'messageRef': idMap[oldMessage.id]});
modeling.updateProperties(element, { 'messageRef': idMap[oldMessage.id] });
}
}

// add element to which a boundary event is attached
if (newElement.$type === 'bpmn:BoundaryEvent') {
let hostElement = elementRegistry.get(idMap[newElement.attachedToRef.id]);
modeling.updateProperties(element, {'attachedToRef': hostElement.businessObject});
modeling.updateProperties(element, { 'attachedToRef': hostElement.businessObject });
element.host = hostElement;
}

Expand All @@ -109,7 +107,7 @@ export function insertShape(definitions, parent, newElement, idMap, replace, mod
}

// return success flag and idMap with id mappings of this element and all children
return {success: success, idMap: idMap, element: element};
return { success: success, idMap: idMap, element: element };
}

/**
Expand Down Expand Up @@ -162,7 +160,7 @@ export function insertChildElements(definitions, parent, newElement, idMap, mode
}
}

return {success: success, idMap: idMap, element: parent};
return { success: success, idMap: idMap, element: parent };
}

/**
Expand Down Expand Up @@ -229,7 +227,7 @@ export function getAllElementsInProcess(processBo, elementRegistry, elementType)
for (let i = 0; i < flowElementBos.length; i++) {
let flowElementBo = flowElementBos[i];
if (flowElementBo.$type && flowElementBo.$type === elementType) {
elements.push({element: flowElementBo, parent: processElement});
elements.push({ element: flowElementBo, parent: processElement });
}

// recursively retrieve service tasks if subprocess is found
Expand Down Expand Up @@ -258,7 +256,7 @@ export function getAllElementsForProcess(processBo, elementRegistry, elementType
for (let i = 0; i < flowElements.length; i++) {
let flowElement = flowElements[i];
if (is(flowElement, elementType)) {
elements.push({element: flowElement, parent: processElement});
elements.push({ element: flowElement, parent: processElement });
}
}
return elements;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,24 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {layout} from './layouter/Layouter';
import {matchesQRM} from './QuantMEMatcher';
import {addQuantMEInputParameters} from './InputOutputHandler';
import { layout } from './layouter/Layouter';
import { matchesQRM } from './QuantMEMatcher';
import { addQuantMEInputParameters } from './InputOutputHandler';
import * as Constants from '../Constants';
import {replaceHardwareSelectionSubprocess} from './hardware-selection/QuantMEHardwareSelectionHandler';
import {replaceCuttingSubprocess} from './circuit-cutting/QuantMECuttingHandler';
import {insertShape} from '../../../editor/util/TransformationUtilities';
import {createTempModelerFromXml} from '../../../editor/ModelerHandler';
import { replaceHardwareSelectionSubprocess } from './hardware-selection/QuantMEHardwareSelectionHandler';
import { replaceCuttingSubprocess } from './circuit-cutting/QuantMECuttingHandler';
import { insertShape } from '../../../editor/util/TransformationUtilities';
import { createTempModelerFromXml } from '../../../editor/ModelerHandler';
import {
getCamundaInputOutput,
getDefinitionsFromXml,
getRootProcess,
getSingleFlowElement
} from '../../../editor/util/ModellingUtilities';
import {getXml} from '../../../editor/util/IoUtilities';
import { getXml } from '../../../editor/util/IoUtilities';

const { DOMParser } = require('xmldom');
const xmlParser = require('xml-js');
/**
* Initiate the replacement process for the QuantME tasks that are contained in the current process model
*
Expand All @@ -43,14 +45,14 @@ export async function startQuantmeReplacementProcess(xml, currentQRMs, endpointC
console.log(rootElement);
if (typeof rootElement === 'undefined') {
console.log('Unable to retrieve root process element from definitions!');
return {status: 'failed', cause: 'Unable to retrieve root process element from definitions!'};
return { status: 'failed', cause: 'Unable to retrieve root process element from definitions!' };
}

// get all QuantME modeling constructs from the process
let replacementConstructs = getQuantMETasks(rootElement, elementRegistry);
console.log('Process contains ' + replacementConstructs.length + ' QuantME modeling constructs to replace...');
if (!replacementConstructs || !replacementConstructs.length) {
return {status: 'transformed', xml: xml};
return { status: 'transformed', xml: xml };
}

// check for available replacement models for all QuantME modeling constructs
Expand Down Expand Up @@ -113,8 +115,34 @@ export async function startQuantmeReplacementProcess(xml, currentQRMs, endpointC
// layout diagram after successful transformation
layout(modeling, elementRegistry, rootElement);
let updated_xml = await getXml(modeler);
console.log(updated_xml);
return {status: 'transformed', xml: updated_xml};

// Parse the XML string into a JavaScript object
let xmlDoc = xmlParser.xml2js(updated_xml, { compact: true });

// Get all bpmndi:BPMNDiagram elements
let bpmnDiagrams = xmlDoc['bpmn:definitions']['bpmndi:BPMNDiagram'];

let subprocesses = xmlDoc['bpmn:definitions']['bpmn:process']['bpmn:subProcess'];

// Remove all bpmndi:BPMNDiagram elements except the first one
if (Array.isArray(bpmnDiagrams)) {
if (bpmnDiagrams.length > 1) {
xmlDoc['bpmn:definitions']['bpmndi:BPMNDiagram'] = bpmnDiagrams.slice(0, 1);
}
}

// Remove the isExpanded attribute from the shapes
if (Array.isArray(subprocesses)) {
for (let i = 0; i < subprocesses.length; i++) {
let subprocessAttributes = subprocesses[i]['_attributes'];
delete subprocessAttributes.isExpanded;
}
}

// Serialize the modified JavaScript object back to XML string
let modifiedXmlString = xmlParser.js2xml(xmlDoc, { compact: true });

return { status: 'transformed', xml: modifiedXmlString };
}

/**
Expand All @@ -130,7 +158,7 @@ export function getQuantMETasks(process, elementRegistry) {
for (let i = 0; i < flowElements.length; i++) {
let flowElement = flowElements[i];
if (flowElement.$type && flowElement.$type.startsWith('quantme:')) {
quantmeTasks.push({task: flowElement, parent: processBo});
quantmeTasks.push({ task: flowElement, parent: processBo });
}

// recursively retrieve QuantME tasks if subprocess is found
Expand Down Expand Up @@ -160,7 +188,6 @@ async function getMatchingQRM(task, currentQRMs) {
*/
async function replaceByFragment(definitions, task, parent, replacement, modeler) {
let bpmnFactory = modeler.get('bpmnFactory');

if (!replacement) {
console.log('Replacement fragment is undefined. Aborting replacement!');
return false;
Expand All @@ -175,6 +202,31 @@ async function replaceByFragment(definitions, task, parent, replacement, modeler
}

console.log('Replacement element: ', replacementElement);

if (['bpmn:SubProcess', 'quantme:QuantumHardwareSelectionSubprocess', 'quantme:CircuitCuttingSubprocess'].includes(replacementElement.$type)) {

// Create a DOM parser
const parser = new DOMParser();

// Parse the XML string
const xmlDoc = parser.parseFromString(replacement, 'text/xml');

const bpmndiNamespace = 'http://www.omg.org/spec/BPMN/20100524/DI';
const bpmndiShapes = xmlDoc.getElementsByTagNameNS(bpmndiNamespace, 'BPMNShape');

let isExpanded = null;

for (let i = 0; i < bpmndiShapes.length; i++) {
const bpmnElement = bpmndiShapes[i].getAttribute('bpmnElement');
if (bpmnElement === replacementElement.id) {
isExpanded = bpmndiShapes[i].getAttribute('isExpanded');
replacementElement.isExpanded = isExpanded;
break;
}
}
}


let result = insertShape(definitions, parent, replacementElement, {}, true, modeler, task);

// add all attributes of the replaced QuantME task to the input parameters of the replacement fragment
Expand Down
46 changes: 39 additions & 7 deletions components/bpmn-q/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading