Use BpmnParseListener to parse process and user task

Hi, I set some extensionElements.properties.property in the process element and user task element in bpmn file. In order to parse those properties, I implement the BpmnParseListener interface.
I want to merge the process element properties when parse the user task properties(process property as default value across the all user tasks in this process). The problem is parseProcess and parseUserTask has no relations to indicate they are currently parsing the same BPMN. Is there a way to bind the process element and user task elements which are childen element in the process?
Thanks in advance.

Are you referring to the camunda:property extension element, or to some custom extension?

The camunda:property extension element

Hmm, this is a tricky one. Since parseProcess is called after all parseUserTask invocations, I would go about this the following way: In parseProcess, traverse all user tasks (via ProcessDefinitionEntity#getActivities() - note that this method returns only top-level activities for each scope, so you have to call it repeatedly) and set merge the properties as appropriate.

Not a great solution, but should do the trick.

Cheers,
Thorben

Thanks for you solution.
I want to clarify the steps:
1, parse Element in parseUserTask method to extract extensionElements and set the property extracted from extensionElements through AcitivityImpl#setProperty method
2, parse Element in parseProcess method to extract extensionElements and merge into ActivityImpl#properties
repeatly do ActivityImpl#getActivities() to merge.

Yes, that sounds good. One remark: Note that properties map ActivityImpl has, is used for internal purposes of the process engine, i.e. certain properties are populated by the engine. To be on the safe side, you could write code that ensures that no engine properties are overwritten.

Cheers,
Thorben

One more question:
How can I get the embedded subprocess BMPN element from a UserTask TaskListener#notify which defined in the embedded subprocess.

In a task listener, you can access the BPMN model API that offers rich accessor methods. In particular, something like this should work:

@Override
public void notify(DelegateTask delegateTask) {
  UserTask userTask = delegateTask.getBpmnModelElementInstance();
  ModelElementInstance scope = userTask.getParentElement();

  if (scope instanceof SubProcess) {
    SubProcess subProcess = (SubProcess) scope;

    // TODO: access subProcess element
  }
}

The BPMN model API is much nicer than the elements you can access in a BpmnParseListener. Ideally we would rewrite the BPMN parser to be based on the model API, but that is a big task.

If UserTask#notify is invoked by CallActivity, should I call delegateTask.getExecution().getSuperExecution().getBpmnModelElementInstance() to obtain the CallActivity?