Can't create nested tags in Timer Event ExtensionElements


#1

Hi, everybody! I’m having some trouble on creating my structure.

Basically, since I want to give several options to user about Timer Events, I need a structure like this one.

<bpmn2:boundaryEvent id="BoundaryEvent_09ua9ym" attachedToRef="Task_063ak5a">
  <bpmn:ExtensionElements>
    <timerExtension>
        <TimerExtension_Occurrence>
            <TimerExtension_Occurrence_DayOfWeek>1</TimerExtension_Occurrence_DayOfWeek>
            <TimerExtension_Occurrence_DayOfWeek>3</TimerExtension_Occurrence_DayOfWeek>
            <TimerExtension_Occurrence_TimeOfDay>13:00</TimerExtension_Occurrence_TimeOfDay>
            <TimerExtension_Occurrence_TimeOfDay>23:00</TimerExtension_Occurrence_TimeOfDay>
        </TimerExtension_Occurrence>
     </timerExtension>
  </bpmn:ExtensionElements>
</bpmn2:boundaryEvent>

Because of this, I used my set() function to create the Element (using elementHelper) then passing the newly created element to the command array. And so on for the nested elements. Basically, what I got is this:

var command = [];

				const bo = getBusinessObject(element);
				var extensions = elementHelper.createElement("bpmn:ExtensionElements", { values: [] }, bo, bpmnFactory);

				// I prefer to recreate the ExtensionElements element instead of updating it
				command.push(
					cmdHelper.updateProperties(element, {
						extensionElements: extensions,
					})
				);

					const timerExtension = elementHelper.createElement(
						TIMER_EXTENSION,
						{
							occurrence: [],
						},
						extensions,
						bpmnFactory
					);
					command.push(cmdHelper.addElementsTolist(element, extensions, "values", [timerExtension]));

					const timerExtensionOccurence = elementHelper.createElement(
						TIMER_EXTENSION_OCCURRENCE,
						{},
						timerExtension,
						bpmnFactory
					);

					command.push(
						cmdHelper.addElementsTolist(element, timerExtension, "occurrence", [timerExtensionOccurence])
					);

					const timeActions = _.map(result.timeOfDay, timeOfDay =>
						elementHelper.createElement(
							TIMER_EXTENSION_OCCURRENCE_TIME,
							{ values: timeOfDay },
							timerExtensionOccurence,
							bpmnFactory
						)
					);
					command.push(
						cmdHelper.addElementsTolist(element, timerExtensionOccurence, "timeOfDay", timeActions)
					);

					if (!_.isEmpty(result.date)) {
						const dateActions = _.map(result.date, date =>
							elementHelper.createElement(
								TIMER_EXTENSION_OCCURRENCE_DATE,
								{ values: date },
								timerExtensionOccurence,
								bpmnFactory
							)
						);
						command.push(
							cmdHelper.addElementsTolist(element, timerExtensionOccurence, "date", dateActions)
						);
					} else if (!_.isEmpty(result.dayOfMonth)) {
						const dayOfMonthActions = _.map(result.dayOfMonth, dayOfMonth =>
							elementHelper.createElement(
								TIMER_EXTENSION_OCCURRENCE_DAY_OF_MONTH,
								{ values: dayOfMonth },
								timerExtensionOccurence,
								bpmnFactory
							)
						);
						command.push(
							cmdHelper.addElementsTolist(
								element,
								timerExtensionOccurence,
								"dayOfMonth",
								dayOfMonthActions
							)
						);
					} else if (!_.isEmpty(result.dayOfWeek)) {
						const dayOfWeekActions = _.map(result.dayOfWeek, dayOfWeek =>
							elementHelper.createElement(
								TIMER_EXTENSION_OCCURRENCE_DAY_OF_WEEK,
								{ values: dayOfWeek },
								timerExtensionOccurence,
								bpmnFactory
							)
						);
						command.push(
							cmdHelper.addElementsTolist(element, timerExtensionOccurence, "dayOfWeek", dayOfWeekActions)
						);
					}
return command;

Please, consider terms in caps (such as TIMER_EXTENSION) as a constant stored with the value TimerExtension as string, in order to avoid to repeat string here and there.

I’m doing my best, but all I got is this XML structure:

<bpmn2:boundaryEvent id="BoundaryEvent_09ua9ym" attachedToRef="Task_063ak5a">
   <bpmn2:extensionElements>
      <nu:timerExtension>[object Object]</nu:timerExtension>
   </bpmn2:extensionElements>
   <bpmn2:outgoing>SequenceFlow_0onu3hb</bpmn2:outgoing>
   <bpmn2:timerEventDefinition />
</bpmn2:boundaryEvent>

And no matter what I do, I cant’ get anything better than this.

But, there is a fun fact: the element structure get created. When the get() function of my EntryFactory get created, chrome debugger catches this:
image
The example has a Occurrence on day monday (1) and wednesday (3) at times 13:00 and 23:00 of the day.

Is anybody with experience with this topic that can help me? Thanks in advance.


#2

I’ll answer this by myself (I did it once, I’m doing it again).

I found out that it wasn’t working because my moddle had this structure:

{
      "name": "TimerExtension",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "occurrence",
          "isBody": true, <-- *** THIS WAS MY PROBLEM ***
          "type": "TimerExtension_Occurrence"
        },
        {
          "name": "timeSpan",
          "isAttr": true,
          "type": "string"
        },
        {
          "name": "dataPath",
          "isAttr": true,
          "type": "string"
        }
      ]
    },

Basically, it returned [Object object] because this extension was instructed to be saved as body of the element. I couldn’t figured it out because this moddle was given to me, but also because the ModdleElement structure tricked me to believe that the structure was correct.

I could resolve this problem changing isBody: true with isMany: true. I need only one occurrence, but this is something I can easily manage by limiting options to the user.


#3

I’ll answer this by myself (I did it once, I’m doing it again).

Always happy to see people sharing their solutions.