From 093017f9166b4ec38580b1d8b6d752c1b7ebcfe0 Mon Sep 17 00:00:00 2001 From: raulmonti Date: Tue, 18 Feb 2025 21:43:18 +0100 Subject: [PATCH 1/3] Sanitize names (remove spaces and some symbols) in the repr function. Should later take a better decision about this symbols. --- .../src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java index acfd117a..69c61e87 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java @@ -596,7 +596,7 @@ protected ArrayList getInputOutputIds(Element elem) { /** - * Fetch the names of components that poses a RUN task. + * Fetch the names of components that contain a RUN task. * @return List with components names */ private ArrayList listSUTcomponents () { @@ -868,7 +868,7 @@ protected String compile(String elId) { */ protected String repr(Element el) { // Logging.logDebug(el.getId()); - return el.getName(); + return sanitize(el.getName()); } private String getOriginDataNode(String id) { From dad3f2824796f70328fa98c3697804567354380c Mon Sep 17 00:00:00 2001 From: raulmonti Date: Tue, 18 Feb 2025 22:25:35 +0100 Subject: [PATCH 2/3] Added support to define fully qualified names for bpmn4s elements. Using this f-q-names to name actions in the generated pspec for the test generation mode. --- .../src/nl/asml/matala/bpmn4s/Main.java | 30 +++++++++++++++++-- .../matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java | 12 ++++---- .../nl/asml/matala/bpmn4s/bpmn4s/Element.java | 20 +++++++++---- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java index 95f342cb..afe8ed01 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java @@ -115,7 +115,11 @@ public static void compile(String inputModel, boolean simulation, String outputF @Override protected String repr(Element el) { return el.getId(); - } + } + @Override + protected String getFullyQualifiedName(Element el) { + return repr(el); + } @Override protected String getCompiledXorName(String xorId) { return repr(model.getElementById(xorId)); @@ -277,7 +281,8 @@ static void makeDataNode(BpmnModelInstance modelInst, ItemAwareElement elem, Ele String origin = getOriginDataReference(elem); node.setOriginDataNodeId(origin != null ? origin : id); node.setParent(getParentId(elem)); - node.setComponent(getParentComponents(elem)); + node.setFullyQualifiedName(getFullyQualifiedName(elem)); + node.setParentComponent(getParentComponents(elem)); String datatyperef = elem.getAttributeValueNs("http://bpmn4s", "dataTypeRef"); DataType dt = getExtensionElementById(modelInst, DataType.class, datatyperef); String dtname = dt != null? dt.getAttributeValue("name"): datatyperef; @@ -475,7 +480,8 @@ public static void makeActionNode(BpmnModelInstance modelInst, BaseElement elem, node.setId(id); if (elem instanceof FlowNode) { node.setParent(getParentId(elem)); - node.setComponent(getParentComponents(elem)); + node.setFullyQualifiedName(getFullyQualifiedName(elem)); + node.setParentComponent(getParentComponents(elem)); node.setGuard(elem.getAttributeValueNs("http://bpmn4s", "guard")); node.setStepType(elem.getAttributeValueNs("http://bpmn4s", "stepType")); } @@ -555,6 +561,24 @@ static ArrayList getParentComponents (ModelElementInstance elem) { return result; } + /* + * Note that we use the separator <@> which is not allowed + * in the editor ids but is a allowed in pspec ids. + */ + static String getFullyQualifiedName (ModelElementInstance elem) { + ArrayList parentsList = new ArrayList(); + ModelElementInstance parent = elem.getParentElement(); + while(parent != null) { + String parentType = parent.getElementType().getTypeName(); + if(parentType.equals("process") || isComponent(parent)) { + parentsList.add(0, getName(parent)); + } + parent = parent.getParentElement(); + } + String result = ""; + result = String.join("@", parentsList) + "@" + getName(elem); + return result; + } static String getParentId(ModelElementInstance elem) { ModelElementInstance parent = elem.getParentElement(); diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java index 69c61e87..15882a15 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java @@ -448,6 +448,9 @@ public static E getOrDefault(List list, int index,E defaultValue) { return index <= list.size() - 1 ? list.get(index) : defaultValue; } + protected String getFullyQualifiedName(Element el) { + return sanitize(el.getFullyQualifiedName()); + } private String fabSpecDescription(String cId) { ArrayList desc = new ArrayList(); @@ -459,7 +462,7 @@ private String fabSpecDescription(String cId) { String task = ""; // Name of context as defined by user at front end: String compCtxName = model.getElementById(cId).getContextName(); - task += "action\t\t\t" + sanitize(repr(node)) + "\n"; + task += "action\t\t\t" + getFullyQualifiedName(node) + "\n"; // STEP TYPE String stepConf = ""; if (model.isComposeTask(node.getId())) { @@ -809,7 +812,7 @@ void writeToFile (Path filename, String text) { * but PSpec is more restrictive so we replace them. */ protected String sanitize(String str) { - String result = str.replaceAll("\\p{Zs}+", "").replace(".", ""); + String result = str.replaceAll("\\p{Zs}+", "").replace(".", "").replace("-",""); return result; } @@ -863,11 +866,10 @@ protected String compile(String elId) { /** * Get the identifier of a bpmn4s Element - * While the compiler for test generation (this) returns the name of the element, - * the compiler for simulation will return the element's id. + * Return a sanitized version of the elemnt's name chosen by the modeler. + * The compiler for simulation overrides this method and returns the element's id. */ protected String repr(Element el) { -// Logging.logDebug(el.getId()); return sanitize(el.getName()); } diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java index d61fc260..166b755b 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java @@ -30,7 +30,8 @@ class Context { List flowInputs = new ArrayList(); List flowOutputs = new ArrayList(); String parent = ""; - ArrayList components = new ArrayList(); + String fqname = ""; + ArrayList parentComponents = new ArrayList(); String init = ""; String stepType; @@ -133,12 +134,12 @@ public String getParent () { return parent; } - public void setComponent (ArrayList cname) { - components = cname; + public void setParentComponent (ArrayList cname) { + parentComponents = cname; } public ArrayList getParentComponents () { - return components; + return parentComponents; } public void setContext(String name, String dataType, String init) { @@ -259,8 +260,7 @@ public boolean isReferenceData() { public String toString() { return String.format("Element named %s with id %s and type %s", this.name, this.id, this.type); } - - + private static List listConcat(List list1, List list2) { return Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList()); } @@ -272,5 +272,13 @@ public List getAllInputs() { public List getAllOutputs() { return listConcat(flowOutputs, dataOutputs); } + + public void setFullyQualifiedName(String name) { + this.fqname = name; + } + + public String getFullyQualifiedName () { + return fqname; + } } \ No newline at end of file From 48d4bac9476b2039149146b3f5d40cc949e27c3f Mon Sep 17 00:00:00 2001 From: raulmonti Date: Tue, 18 Feb 2025 23:24:16 +0100 Subject: [PATCH 3/3] Fix to include activities in fully qualified name and to remove the definitions element from it. --- .../src/nl/asml/matala/bpmn4s/Main.java | 21 ++++++++----------- .../matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java | 2 +- .../nl/asml/matala/bpmn4s/bpmn4s/Element.java | 2 +- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java index afe8ed01..2e1ee712 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/Main.java @@ -165,8 +165,7 @@ protected List getFlowActions(String component) { Element c = model.getElementById(component); ArrayList result = new ArrayList(); for (Element source: model.elements.values()) { - if ((isAPlace(source.getId()) || model.isActivity(source.getId())) - && isParentComponent( c, source)) { + if (isAPlace(source.getId()) && isParentComponent( c, source)) { for(Edge e: source.getAllOutputs()) { String sourceId = e.getSrc(); String targetId = e.getTar(); @@ -282,7 +281,7 @@ static void makeDataNode(BpmnModelInstance modelInst, ItemAwareElement elem, Ele node.setOriginDataNodeId(origin != null ? origin : id); node.setParent(getParentId(elem)); node.setFullyQualifiedName(getFullyQualifiedName(elem)); - node.setParentComponent(getParentComponents(elem)); + node.setParentComponents(getParentComponents(elem)); String datatyperef = elem.getAttributeValueNs("http://bpmn4s", "dataTypeRef"); DataType dt = getExtensionElementById(modelInst, DataType.class, datatyperef); String dtname = dt != null? dt.getAttributeValue("name"): datatyperef; @@ -481,7 +480,7 @@ public static void makeActionNode(BpmnModelInstance modelInst, BaseElement elem, if (elem instanceof FlowNode) { node.setParent(getParentId(elem)); node.setFullyQualifiedName(getFullyQualifiedName(elem)); - node.setParentComponent(getParentComponents(elem)); + node.setParentComponents(getParentComponents(elem)); node.setGuard(elem.getAttributeValueNs("http://bpmn4s", "guard")); node.setStepType(elem.getAttributeValueNs("http://bpmn4s", "stepType")); } @@ -497,9 +496,6 @@ public static void makeActionNode(BpmnModelInstance modelInst, BaseElement elem, contextTypeName = contextTypeId; } } - if(contextInit != null && contextInit.strip().startsWith("=")) { - contextInit = contextInit.substring(1); // FIXME due to issues with bpmn4s editor lsp integration - } node.setContext(contextName != null ? contextName : "", contextTypeName != null ? contextTypeName : "", contextInit != null ? contextInit : ""); @@ -568,11 +564,12 @@ static ArrayList getParentComponents (ModelElementInstance elem) { static String getFullyQualifiedName (ModelElementInstance elem) { ArrayList parentsList = new ArrayList(); ModelElementInstance parent = elem.getParentElement(); - while(parent != null) { - String parentType = parent.getElementType().getTypeName(); - if(parentType.equals("process") || isComponent(parent)) { - parentsList.add(0, getName(parent)); - } + // FIXME: there must be a more robust way to check the type of an element than comparing to a string + while(parent != null && + ("subProcess".equals(parent.getElementType().getTypeName()) || + "process".equals(parent.getElementType().getTypeName()))) + { + parentsList.add(0, getName(parent)); parent = parent.getParentElement(); } String result = ""; diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java index 15882a15..cfee7f89 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Bpmn4sCompiler.java @@ -574,7 +574,7 @@ protected Map buildReplaceMap (Element transition) { /** * In simulation mode, some flows between bpmn4s elements introduce transitions in the CPN. - * Imagine a flow between to XOR gates for instance. In general, if two elements are connected with a flow + * Imagine a flow between two XOR gates for instance. In general, if two elements are connected with a flow * and their CPN semantics is a place, then a transition needs to be added. For test generation, we optimize * the model such that this flows do not exist anymore, so that we reduce spurious non-determinism. */ diff --git a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java index 166b755b..04ed2139 100644 --- a/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java +++ b/bundles/nl.asml.matala.bpmn4s/src/nl/asml/matala/bpmn4s/bpmn4s/Element.java @@ -134,7 +134,7 @@ public String getParent () { return parent; } - public void setParentComponent (ArrayList cname) { + public void setParentComponents (ArrayList cname) { parentComponents = cname; }