This is an automated email from the ASF dual-hosted git repository.

thiagoelg pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git


The following commit(s) were added to refs/heads/main by this push:
     new 832fe8172ad [incubator-kie-issues#2298] Duplicate datatypes for BPMN 
files of kie examples (#3575)
832fe8172ad is described below

commit 832fe8172adef7215ccb1ae1c466e0c61b1e4881
Author: Abhiram Gundala <[email protected]>
AuthorDate: Tue May 26 08:24:27 2026 -0400

    [incubator-kie-issues#2298] Duplicate datatypes for BPMN files of kie 
examples (#3575)
---
 .../bpmn-editor/src/normalization/normalize.ts     | 142 +++++++++++++++++++++
 .../propertiesManager/PropertiesManager.tsx        |   9 ++
 2 files changed, 151 insertions(+)

diff --git a/packages/bpmn-editor/src/normalization/normalize.ts 
b/packages/bpmn-editor/src/normalization/normalize.ts
index 8ff4da49116..4ac61a9dac3 100644
--- a/packages/bpmn-editor/src/normalization/normalize.ts
+++ b/packages/bpmn-editor/src/normalization/normalize.ts
@@ -18,6 +18,7 @@
  */
 
 import { BpmnLatestModel } from "@kie-tools/bpmn-marshaller";
+import { BPMN20__tProcess } from 
"@kie-tools/bpmn-marshaller/dist/schemas/bpmn-2_0/ts-gen/types";
 import { getNewBpmnIdRandomizer } from "../idRandomizer/bpmnIdRandomizer";
 import { State } from "../store/Store";
 
@@ -31,6 +32,83 @@ type WithRequiredDeep<T, K extends keyof any> = T extends 
undefined
         ? { [P in K]-?: NonNullable<WithRequiredDeep<T[P], K>> }
         : T);
 
+function remapDataItems(
+  itemDefinitionIdsToRemap: Map<string, string>,
+  items: Array<{ "@_itemSubjectRef"?: string }> | undefined
+) {
+  if (!items) {
+    return;
+  }
+  for (const item of items) {
+    if (item["@_itemSubjectRef"] !== undefined) {
+      item["@_itemSubjectRef"] = 
itemDefinitionIdsToRemap.get(item["@_itemSubjectRef"]) ?? 
item["@_itemSubjectRef"];
+    }
+  }
+}
+
+function remapProperties(
+  itemDefinitionIdsToRemap: Map<string, string>,
+  properties: Array<{ "@_itemSubjectRef"?: string }> | undefined
+) {
+  if (!properties) {
+    return;
+  }
+  for (const p of properties) {
+    if (p["@_itemSubjectRef"]) {
+      p["@_itemSubjectRef"] = 
itemDefinitionIdsToRemap.get(p["@_itemSubjectRef"]) ?? p["@_itemSubjectRef"];
+    }
+  }
+}
+
+function remapFlowElements(
+  itemDefinitionIdsToRemap: Map<string, string>,
+  flowElements: NonNullable<BPMN20__tProcess["flowElement"]>
+) {
+  for (const el of flowElements) {
+    if (
+      el.__$$element === "dataObject" ||
+      el.__$$element === "dataObjectReference" ||
+      el.__$$element === "dataStoreReference"
+    ) {
+      if (el["@_itemSubjectRef"] !== undefined) {
+        el["@_itemSubjectRef"] = 
itemDefinitionIdsToRemap.get(el["@_itemSubjectRef"]) ?? el["@_itemSubjectRef"];
+      }
+    } else if (
+      el.__$$element === "businessRuleTask" ||
+      el.__$$element === "callActivity" ||
+      el.__$$element === "serviceTask" ||
+      el.__$$element === "userTask"
+    ) {
+      remapDataItems(itemDefinitionIdsToRemap, el.ioSpecification?.dataInput);
+      remapDataItems(itemDefinitionIdsToRemap, el.ioSpecification?.dataOutput);
+      remapProperties(itemDefinitionIdsToRemap, el.property);
+    } else if (el.__$$element === "endEvent" || el.__$$element === 
"intermediateThrowEvent") {
+      remapDataItems(itemDefinitionIdsToRemap, el.dataInput);
+      remapProperties(itemDefinitionIdsToRemap, el.property);
+    } else if (
+      el.__$$element === "startEvent" ||
+      el.__$$element === "intermediateCatchEvent" ||
+      el.__$$element === "boundaryEvent"
+    ) {
+      remapDataItems(itemDefinitionIdsToRemap, el.dataOutput);
+      remapProperties(itemDefinitionIdsToRemap, el.property);
+    } else if (
+      el.__$$element === "subProcess" ||
+      el.__$$element === "adHocSubProcess" ||
+      el.__$$element === "transaction"
+    ) {
+      remapDataItems(itemDefinitionIdsToRemap, el.ioSpecification?.dataInput);
+      remapDataItems(itemDefinitionIdsToRemap, el.ioSpecification?.dataOutput);
+      remapProperties(itemDefinitionIdsToRemap, el.property);
+      if (el.flowElement) {
+        remapFlowElements(itemDefinitionIdsToRemap, el.flowElement);
+      }
+    } else {
+      // Other flow elements do not reference itemDefinitions.
+    }
+  }
+}
+
 export function normalize(model: BpmnLatestModel): State["bpmn"]["model"] {
   getNewBpmnIdRandomizer()
     .ack({
@@ -91,5 +169,69 @@ export function normalize(model: BpmnLatestModel): 
State["bpmn"]["model"] {
 
   const normalizedModel = model as Normalized<BpmnLatestModel>;
 
+  // Merge itemDefinitions that share the same structureRef.
+  deduplicateItemDefinitions(normalizedModel.definitions);
+
   return normalizedModel;
 }
+
+// Keep one itemDefinition per structureRef and update references to point to 
it.
+export function deduplicateItemDefinitions(definitions: 
Normalized<BpmnLatestModel["definitions"]>): void {
+  const itemDefinitionsGroupedStructureRef = new Map<string, Array<string>>();
+  for (const rootElement of definitions.rootElement ?? []) {
+    if (rootElement.__$$element === "itemDefinition") {
+      const itemDefinitionStructureRef = rootElement["@_structureRef"] ?? "";
+      itemDefinitionsGroupedStructureRef.set(itemDefinitionStructureRef, [
+        ...(itemDefinitionsGroupedStructureRef.get(itemDefinitionStructureRef) 
?? []),
+        rootElement["@_id"],
+      ]);
+    }
+  }
+
+  // Map each duplicate id to the id of the first occurrence we keep.
+  const itemDefinitionIdsToRemap = new Map<string, string>();
+  for (const itemDefinitionsGroup of 
itemDefinitionsGroupedStructureRef.values()) {
+    if (itemDefinitionsGroup.length <= 1) {
+      continue;
+    }
+    const survivorId = itemDefinitionsGroup[0];
+    for (let i = 1; i < itemDefinitionsGroup.length; i++) {
+      itemDefinitionIdsToRemap.set(itemDefinitionsGroup[i], survivorId);
+    }
+  }
+
+  if (itemDefinitionIdsToRemap.size === 0) {
+    return;
+  }
+
+  // Remove the duplicate itemDefinitions and update every reference to them.
+  definitions.rootElement = definitions.rootElement?.filter(
+    (e) => !(e.__$$element === "itemDefinition" && 
itemDefinitionIdsToRemap.has(e["@_id"]))
+  );
+
+  for (const rootElement of definitions.rootElement ?? []) {
+    if (rootElement.__$$element === "dataStore") {
+      if (rootElement["@_itemSubjectRef"] !== undefined) {
+        rootElement["@_itemSubjectRef"] =
+          itemDefinitionIdsToRemap.get(rootElement["@_itemSubjectRef"]) ?? 
rootElement["@_itemSubjectRef"];
+      }
+    } else if (rootElement.__$$element === "message") {
+      if (rootElement["@_itemRef"] !== undefined) {
+        rootElement["@_itemRef"] = 
itemDefinitionIdsToRemap.get(rootElement["@_itemRef"]) ?? 
rootElement["@_itemRef"];
+      }
+    } else if (rootElement.__$$element === "correlationProperty") {
+      if (rootElement["@_type"] !== undefined) {
+        rootElement["@_type"] = 
itemDefinitionIdsToRemap.get(rootElement["@_type"]) ?? rootElement["@_type"];
+      }
+    } else if (rootElement.__$$element === "process") {
+      remapDataItems(itemDefinitionIdsToRemap, 
rootElement.ioSpecification?.dataInput);
+      remapDataItems(itemDefinitionIdsToRemap, 
rootElement.ioSpecification?.dataOutput);
+      remapProperties(itemDefinitionIdsToRemap, rootElement.property);
+      if (rootElement.flowElement) {
+        remapFlowElements(itemDefinitionIdsToRemap, rootElement.flowElement);
+      }
+    } else {
+      // Other rootElement types do not reference itemDefinitions.
+    }
+  }
+}
diff --git 
a/packages/bpmn-editor/src/propertiesPanel/propertiesManager/PropertiesManager.tsx
 
b/packages/bpmn-editor/src/propertiesPanel/propertiesManager/PropertiesManager.tsx
index 4110b935cc0..7e38a36bf14 100644
--- 
a/packages/bpmn-editor/src/propertiesPanel/propertiesManager/PropertiesManager.tsx
+++ 
b/packages/bpmn-editor/src/propertiesPanel/propertiesManager/PropertiesManager.tsx
@@ -49,6 +49,7 @@ import {
 import { addOrGetItemDefinitions, DEFAULT_DATA_TYPES } from 
"../../mutations/addOrGetItemDefinitions";
 import { deleteItemDefinition } from "../../mutations/deleteItemDefinition";
 import { renameItemDefinition } from "../../mutations/renameItemDefinition";
+import { deduplicateItemDefinitions } from "../../normalization/normalize";
 import { addOrGetMessages } from "../../mutations/addOrGetMessages";
 import { renameMessage } from "../../mutations/renameMessage";
 import { deleteMessage } from "../../mutations/deleteMessage";
@@ -174,6 +175,14 @@ export function PropertiesManager({ p }: { p: undefined | 
WithVariables }) {
                             });
                           });
                         }}
+                        onBlur={() => {
+                          if (!entry["@_structureRef"]) {
+                            return;
+                          }
+                          bpmnEditorStoreApi.setState((s) => {
+                            
deduplicateItemDefinitions(s.bpmn.model.definitions);
+                          });
+                        }}
                       />
                     </GridItem>
                     <GridItem span={1} style={{ textAlign: "right" }}>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to