Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "BPMN2-Modeler/DeveloperTutorials/AddingCDATA"

(Created page with "== Introduction == There have been a lot questions on the [https://www.eclipse.org/forums/index.php/f/226/ddf71c892847b96912ebdb3c19ce41f5/ BPMN2 Modeler Forum] lately about s...")
 
m
Line 3: Line 3:
  
 
This tutorial deals more with the implementation details in EMF, rather than focusing on a specific BPMN2 Modeler extension API feature. This functionality has already been added to the [https://git.eclipse.org/c/bpmn2-modeler/org.eclipse.bpmn2-modeler.git/tree/examples/plugins/org.eclipse.bpmn2.modeler.examples.customtask Custom Task example plugin], so this tutorial will show how it was done.
 
This tutorial deals more with the implementation details in EMF, rather than focusing on a specific BPMN2 Modeler extension API feature. This functionality has already been added to the [https://git.eclipse.org/c/bpmn2-modeler/org.eclipse.bpmn2-modeler.git/tree/examples/plugins/org.eclipse.bpmn2.modeler.examples.customtask Custom Task example plugin], so this tutorial will show how it was done.
 +
 +
For our CustomTask target runtime we wanted the ability to add an optional extension element, named "metaData" to any BaseElement type. Recall that the schema for BaseElement looks like this:
 +
 +
<pre>
 +
<xsd:element name="baseElement" type="tBaseElement"/>
 +
<xsd:complexType name="tBaseElement" abstract="true">
 +
  <xsd:sequence>
 +
    <xsd:element ref="documentation" minOccurs="0" maxOccurs="unbounded"/>
 +
    <xsd:element ref="extensionElements" minOccurs="0" maxOccurs="1"/>
 +
  </xsd:sequence>
 +
  <xsd:attribute name="id" type="xsd:ID" use="optional"/>
 +
  <xsd:anyAttribute namespace="##other" processContents="lax"/>
 +
</xsd:complexType>
 +
</pre>
 +
 +
Our requirement is to be able to add an element called "metaData" into the <extensionElements> list. This "metaData" element should have a "name" attribute and a text "value", which should be serialized as CDATA. Something like this for example:
 +
 +
<pre>
 +
    <bpmn2:extensionElements>
 +
      <mm:metaData name="info"><![CDATA[Here's some information about this process.]]></mm:metaData>
 +
    </bpmn2:extensionElements>
 +
</pre>
 +
 +
== Start With The Ecore ==
 +
 +
Open the MyModel.ecore with the EMF Ecore editor and create a new EClass called MetaData.
 +
 +
[[File:BPMN2-Modeler-AddingCData-MyModel-ecore.jpg]]
 +
 +
Add an EAnnotation child to this EClass and set the "Source" to "http:///org/eclipse/emf/ecore/util/ExtendedMetaData".
 +
 +
[[File:BPMN2-Modeler-AddingCData-ExtendedMetaData-properties.jpg]]
 +
 +
Add a new Details Entry to this ExtendedMetaData element and set the "Key" to "kind" and "Value" to "mixed"
 +
 +
[[File:BPMN2-Modeler-AddingCData-ExtendedMetaData-details.png]]
 +
 +
This will define the "metaData" element as having [http://www.w3.org/TR/REC-xml/#sec-mixed-content mixed content]. Add another Details entry and set Key="namespace" and Value="##targetNamespace". This declares that the "metaData" element belongs to the same namespace as that defined by the model.
 +
 +
Add an EAttribute named "mixed" to the MetaData class. This will represent the mixed contents of the serialized element and will hold the content for the "value" attribute. Create an ExtendedMetaData entry for "mixed" and add Details entries as shown in the MyModel.ecore above. Set the EType for "mixed" to "FeatureMap$Entry" and set its upper bound to "unbounded" (-1). The Properties for "mixed" should look like this:
 +
 +
[[File:BPMN2-Modeler-AddingCData-ExtendedMetaData-mixed.png]]
 +
 +
Add a EString attribute to MetaData and call it "name". Add another EString attribute called "value", but set the "Volatile" and "Transient" flags "true". The first will generate code that, when invoked from Java, will throw an UnsupportedOperationException. This will remind you that the bodies for MetaData#getValue() and setValue() must be implemented (more about this later.) The "Transient=true" condition will ensure that the "value" attribute itself will not be serialized as an attribute, but it will appear as CDATA. In other words, if we had "Transient=false" the generated XML would look like this:
 +
 +
<pre>
 +
    <bpmn2:extensionElements>
 +
      <mm:metaData name="info" value="Here's some information about this process."><![CDATA[Here's some information about this process.]]></mm:metaData>
 +
    </bpmn2:extensionElements>
 +
</pre>
 +
 +
The "value" properties should look like this:
 +
 +
[[File:BPMN2-Modeler-AddingCData-ExtendedMetaData-value.png]]
 +
 +
Save the ecore file, open your genmodel and generate the model code.

Revision as of 18:37, 10 March 2015

Introduction

There have been a lot questions on the BPMN2 Modeler Forum lately about serialization of BPMN2 extension elements, specifically concerning the serialization of text values in a CDATA block instead of an attribute value.

This tutorial deals more with the implementation details in EMF, rather than focusing on a specific BPMN2 Modeler extension API feature. This functionality has already been added to the Custom Task example plugin, so this tutorial will show how it was done.

For our CustomTask target runtime we wanted the ability to add an optional extension element, named "metaData" to any BaseElement type. Recall that the schema for BaseElement looks like this:

<xsd:element name="baseElement" type="tBaseElement"/>
<xsd:complexType name="tBaseElement" abstract="true">
  <xsd:sequence>
    <xsd:element ref="documentation" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="extensionElements" minOccurs="0" maxOccurs="1"/>
  </xsd:sequence>
  <xsd:attribute name="id" type="xsd:ID" use="optional"/>
  <xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>

Our requirement is to be able to add an element called "metaData" into the <extensionElements> list. This "metaData" element should have a "name" attribute and a text "value", which should be serialized as CDATA. Something like this for example:

    <bpmn2:extensionElements>
      <mm:metaData name="info"><![CDATA[Here's some information about this process.]]></mm:metaData>
    </bpmn2:extensionElements>

Start With The Ecore

Open the MyModel.ecore with the EMF Ecore editor and create a new EClass called MetaData.

BPMN2-Modeler-AddingCData-MyModel-ecore.jpg

Add an EAnnotation child to this EClass and set the "Source" to "http:///org/eclipse/emf/ecore/util/ExtendedMetaData".

BPMN2-Modeler-AddingCData-ExtendedMetaData-properties.jpg

Add a new Details Entry to this ExtendedMetaData element and set the "Key" to "kind" and "Value" to "mixed"

BPMN2-Modeler-AddingCData-ExtendedMetaData-details.png

This will define the "metaData" element as having mixed content. Add another Details entry and set Key="namespace" and Value="##targetNamespace". This declares that the "metaData" element belongs to the same namespace as that defined by the model.

Add an EAttribute named "mixed" to the MetaData class. This will represent the mixed contents of the serialized element and will hold the content for the "value" attribute. Create an ExtendedMetaData entry for "mixed" and add Details entries as shown in the MyModel.ecore above. Set the EType for "mixed" to "FeatureMap$Entry" and set its upper bound to "unbounded" (-1). The Properties for "mixed" should look like this:

BPMN2-Modeler-AddingCData-ExtendedMetaData-mixed.png

Add a EString attribute to MetaData and call it "name". Add another EString attribute called "value", but set the "Volatile" and "Transient" flags "true". The first will generate code that, when invoked from Java, will throw an UnsupportedOperationException. This will remind you that the bodies for MetaData#getValue() and setValue() must be implemented (more about this later.) The "Transient=true" condition will ensure that the "value" attribute itself will not be serialized as an attribute, but it will appear as CDATA. In other words, if we had "Transient=false" the generated XML would look like this:

    <bpmn2:extensionElements>
      <mm:metaData name="info" value="Here's some information about this process."><![CDATA[Here's some information about this process.]]></mm:metaData>
    </bpmn2:extensionElements>

The "value" properties should look like this:

BPMN2-Modeler-AddingCData-ExtendedMetaData-value.png

Save the ecore file, open your genmodel and generate the model code.

Back to the top