BPMN Extensions
BPMN 2.0 introduces an extensibility mechanism that allows extending standard BPMN elements with additional properties and behavior. It can be used by modeling tools to add non-standard elements or Artifacts to satisfy a specific need, such as the unique requirements of a vertical domain, and still have a valid BPMN Core.
A BPMN 2.0 Extension defines a ExtensionDefinition
and a ExtensionAttributeDefinition
. The latter defines a list of attributes that can be attached to any BPMN element. The attribute list defines the name and type of the new attribute. This allows BPMN adopters to integrate any meta model into the BPMN meta model and reuse already existing model elements.
The Open-BPMN Meta model
The Open-BPMN meta model provides convenience methods to operate on the BPMN 2.0 extension. To access the bpmn2:extensionElements
node of a BPMN element you can call the the method findExtensionsElement
. In the following example we access the extensions for a bpmn task element ‘myTask’:
Element extensionElement = myModel.findBPMN2Extensions(myTask);
To access an extension element directly you can call the method findExtensionsElement
. This method expects the root BPMN element and a namespace and extension name. The following example returns the Open-BPMN auto-align extension element from the bpmn2: definitions
:
Element extensionElement = myModel.findExtensionElement(myModel.getDefinitions(), BPMNModelFactory.OPEN_BPMN_NAMESPACE, "auto-align");
Here you can see the corresponding BPMN file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bpmn2:definitions ...>
<bpmn2:extensionElements>
<open-bpmn:auto-align>true</open-bpmn:auto-align>
</bpmn2:extensionElements>
....
</bpmn2:definitions>
Open-BPMN Extension Points
Open-BPMN supports the extensibility mechanism of BPMN 2.0 by so called “BPMNExtension Points”. An extension point allows adopters to add custom properties to any BPMN Element managed within the Open BPMN modeling tool. This extension mechanism is also used by Open-BPMN to support the BPMN Process Modeling Conformance level. In the following section you will learn how to implement custom BPMN Extensions and to extend the Open-BPMN modelling tool.
To implement a new extension point within Open-BPMN an adaptor has to implement a BPMNExtension and define a new Server Module to register the new Extension. Open-BPMN will automatically integrate tne BPMNExtension into the modeling life-cycle and manage to store the new attributes into the .bpmn model file.
The BPMNElementExtension
A BPMNElementExtension
is a Java interface that need to be implemented to define a new extension point within Open-BPMN .
As an adopter you implement a new org.imixs.openbpmn.BPMNElementExtension
to describe custom properties in a separate schemata. The schemata are defined by the JSONForms project. This is a very flexible an easy to use extension mechanism.
The BPMNElementExtension
defines the following methods:
getNamespace
Unique identifier specifying the Extension namespace. The default namespace is ‘bpmn2’. Implementations should overwrite this method.
@Override
public String getNamespace() {
return "foo";
}
getNamespaceURI
Unique target namespace URI
@Override
public String getNamespaceURI() {
return "http://www.foo.org/bpmn2";
}
getLabel
Returns the Extension label to be used in the Tool Palette
@Override
public String getLabel() {
return "My-Extension";
}
handlesElementTypeId
Returns true if the given ElementTypeID can be handled by this extension. This method is used to verify if a custom implementation of an extension can be applied to a BPMNModelElement.
@Override
public boolean handlesElementTypeId(final String elementTypeId) {
return (BPMNTypes.TASK.equals(elementTypeId));
}
handlesBPMNElement
Validates whether the given {@link BPMNBaseElement} can be handled by this BPMN extension. The default implementation returns true. Implementations can accept only specific BPMN element types or elements containing specific BPMN 2.0 extensions.
@Override
public boolean handlesBPMNElement(final BPMNElement bpmnElement) {
if (bpmnElement instanceof Activity) {
Activity task = (Activity) bpmnElement;
if (task.getType().equals(BPMNTypes.TASK)) {
// next check the extension attribute imixs:username
if (task.hasAttribute(getNamespace() + ":username")) {
return true;
}
}
}
return false;
}
getPriority
Returns the priority of this action handler. The priority is used to derive the execution order if multiple extension handlers should execute the same BPMNBaseElement. The default priority is 0
and the priority is sorted descending. This means handlers with a priority > 0 are executed before handlers with a default priority and handlers with a priority >0 are executed afterwards.
addExtension
Adds an extension to a given BPMN Element
public void addExtension(final BPMNElement bpmnElement) {
if (bpmnElement instanceof Activity) {
bpmnElement.setExtensionAttribute(getNamespace(), "username", "100");
}
}
buildPropertiesForm
This Method is called to generate a JSON Forms Object when the element is loaded. The method adds the BPMNElement properties into a JSON Schema.
You can add a new data field by calling
builder.add("myField","someData")
uiSchemaBuilder. //
addCategory("General"). //
addLayout(Layout.HORIZONTAL). //
addElements("username", "category"). //
schemaBuilder.addProperty("username", "string", "Please enter your name");
This JsonObjectBuilder is used on the BPMNGmodelFactory to generate the JsonForms
updatePropertiesData
Updates the properties data provided by the modeling tool in the corresponding BPMN Element. The method receives the BPMNElement and a json object containing all new values. An extension can also update the given json object during this operation if needed.
The BPMNModelExtension
A BPMNModelExtension
is a Java interface that extends the way a BPMN model file is loaded or stored by Open-BPMN
As an adopter you implement a new org.imixs.openbpmn.extensions.BPMNModelExtension
to implement additional behavior during loading or saving a BPMN model.
The BPMNModelExtension
defines the following methods:
onLoad
This method is called after a BPMNModel was loaded the first time. The model can be modified. The parameter path
provides the file path the model was loaded from.
@Override
public void onLoad(BPMNModel model, Path path) {
....
}
onSave
This method is called before the BPMNModel is stored to disk. The parameter path
provides the file path the model was loaded from.
@Override
public void onLoad(BPMNModel model, Path path) {
....
}
getPriority
Returns the priority of this action handler. The priority is used to derive the execution order if multiple extension handlers should execute the same BPMNBaseElement. The default priority is 0
and the priority is sorted descending. This means handlers with a priority > 0 are executed before handlers with a default priority and handlers with a priority >0 are executed afterwards.
Register a BPMNExtension
To register a custom BPMNExtension you need to extend class BPMNDiagramModule
and overwrite the methods configureBPMNExtensions
and configureBPMNModelExtensions
. In this methods your new custom Extension Points can be registered:
public class MyBPMNDiagramModule extends BPMNDiagramModule {
@Override
public void configureBPMNExtensions(final Multibinder<BPMNElementExtension> binding) {
// bind BPMN default extensions
super.configureBPMNExtensions(binding);
// Bind your custom BPMNExtensions
binding.addBinding().to(MyBPMNTaskExtension.class);
}
@Override
public void configureBPMNModelExtensions(final Multibinder<BPMNModelExtension> binding) {
super.configureBPMNModelExtensions(binding);
// bind your optional model extensions....
}
}
Finally you implement a custom GLSP ServerLauncher to configure a new ServerModule:
public final class MyBPMNServerLauncher {
private MyBPMNServerLauncher() {
}
public static void main(final String[] args) {
String processName = "MyCustomOpenBPMNServer";
try {
DefaultCLIParser parser = new DefaultCLIParser(args, processName);
LaunchUtil.configure(parser);
int port = parser.parsePort();
ServerModule bpmnServerModule = new ServerModule()
.configureDiagramModule(new MyBPMNDiagramModule());
GLSPServerLauncher launcher = new SocketGLSPServerLauncher(bpmnServerModule);
launcher.start("localhost", port);
} catch (ParseException ex) {
ex.printStackTrace();
LaunchUtil.printHelp(processName, DefaultCLIParser.getDefaultOptions());
}
}
}
After the new ServerModule is started Open-BPMN will add the Extension to the Tool-Palette to add the Extension to a BPMN Element. After an Element was extended, the Open-BPMN Property Section will automatically show the new sections to edit your extension attributes.
