AnsweredAssumed Answered

compatibility with Signavio / BPMN 2.0 Diagram Interchange

Question asked by sebastian.s on Feb 22, 2012
Latest reply on Feb 28, 2012 by sebastian.s
Hello Activiti Community,

I have a question regarding the compatibility between the Signavio Process Modeler and the Activiti Engine related to BPMN 2.0 Diagram Interchange. I am using Activiti 5.8. Let me describe my use-case at first.

I use the Signavio Process Modeler (signavio.com) to model processes. Pools and lanes are used in these processes. Afterwards I export the process definition using the BPMN 2.0 export function which generates a BPMN 2.0 XML-File. This file includes the actual process definition plus the diagram interchange part which is used to visualize the process definition.

I am only able to deploy the process definition to the Activiti Engine if I remove the diagram interchange portion before the deployment. If I leave the diagram interchange information in place I receive the following error message:


org.activiti.engine.ActivitiException: Invalid reference in 'bpmnElement' attribute, process sid-1052faca-c25f-445b-be83-7db3c0da2fa7 not found | meinprozess.bpmn20.xml | line 106 | column 126

        at org.activiti.engine.impl.util.xml.Parse.throwActivitiExceptionForErrors(Parse.java:186)
        at org.activiti.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:201)
        at org.activiti.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:81)
        at org.activiti.engine.impl.persistence.deploy.DeploymentCache.deploy(DeploymentCache.java:37)
        at org.activiti.engine.impl.persistence.entity.DeploymentManager.insertDeployment(DeploymentManager.java:39)
        at org.activiti.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:58)
        at org.activiti.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:30)
        at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
        at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:42)
        at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
        at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
        at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
        at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
        at org.activiti.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:43)
        at org.activiti.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:106)
        ..

I could track down my problem in the class called BpmnParse. When a file is parsed the process definitions themselves are parsed at first (parseProcessDefinitions()) and afterwards the diagram interchange information (parseDiagramInterchangeElements()) is parsed. The later one relies on the previous since references are made from the elements in the diagram interchange part to the elements in the process definition part.


  /**
   * Parses the 'definitions' root element
   */
  protected void parseRootElement() {
    parseDefinitionsAttributes();
    parseImports();
    parseItemDefinitions();
    parseMessages();
    parseInterfaces();
    parseErrors();
    parseProcessDefinitions();

    // Diagram interchange parsing must be after parseProcessDefinitions,
    // since it depends and sets values on existing process definition objects
    parseDiagramInterchangeElements();
   
    for (BpmnParseListener parseListener : parseListeners) {
      parseListener.parseRootElement(rootElement, getProcessDefinitions());
    }
  }

Later on when the diagram interchange information is parsed Activiti tries to resolve the references made to the process definition part. This is done by use of the method getProcessDefinition().


public void parseBPMNPlane(Element bpmnPlaneElement) {
    String processId = bpmnPlaneElement.attribute("bpmnElement");
    if (processId != null && !"".equals(processId)) {
      ProcessDefinitionEntity processDefinition = getProcessDefinition(processId);
      if (processDefinition != null) {
        processDefinition.setGraphicalNotationDefined(true);

        List<Element> shapes = bpmnPlaneElement.elementsNS(BpmnParser.BPMN_DI_NS, "BPMNShape");
        for (Element shape : shapes) {
          parseBPMNShape(shape, processDefinition);
        }

        List<Element> edges = bpmnPlaneElement.elementsNS(BpmnParser.BPMN_DI_NS, "BPMNEdge");
        for (Element edge : edges) {
          parseBPMNEdge(edge, processDefinition);
        }

      } else {
        addError("Invalid reference in 'bpmnElement' attribute, process " + processId + " not found", bpmnPlaneElement);
      }
    } else {
      addError("'bpmnElement' attribute is required on BPMNPlane ", bpmnPlaneElement);
    }
  }

The diagram interchange information part does not only reference elements within the <process>-element (including itself) but also further elements like the <collaboration>-element. When the bpmnPlaneElement for the <collaboration>-element is reached it is being processed as if the referenced bpmnElement was a <process>-element which means getProcessDefinition() is called. This of course fails since there is not <process>-element with the given id - but a <collaboration>-element.

What can I do if I want to keep the diagram interchange part when deploying process definitions to the Engine? The Activiti Eclipse Designer is capable of handling the information. I can import the given XML-file without a problem.

Any hints are welcome!

Cheers
Sebastian

Outcomes