Skip to Content
Evaluate Get Started Develop Plugins Glossary

Customize BPMN Import

Customize BPMN import when a source model uses conventions that need a different mapping to native Workflow Engine schemes. BpmnConverterBuilder replaces individual conversion visitors, applies BpmnConverterSettings, and produces the converter passed to the BPMN Plugin. The remaining visitors keep their default behavior.

Choose the replacement scope

BpmnConverterBuilder.Create() starts a converter builder. Call the required replacement methods and finish with Build(settings); omitting a replacement selects that visitor's standard implementation. Each replacement method returns the same builder, and a later call for the same visitor replaces the earlier choice.

Node visitors create activities. Flow visitors create outgoing transitions and update their incoming settings. ProcessVisitor coordinates complete process conversion, including nested processes and diagram coordinates.

Visitor classBuilder methodConversion responsibility
TaskNodeVisitorWithCustomTaskNodeVisitorTask nodes become activities.
GatewayNodeVisitorWithCustomGatewayNodeVisitorGateway nodes become activities.
EventNodeVisitorWithCustomEventNodeVisitorEvent nodes become activities or deferred trigger mappings.
SubprocessNodeVisitorWithCustomSubprocessNodeVisitorNonempty subprocess nodes become Inline activities; empty ones become ordinary activities.
CallActivityNodeVisitorWithCustomCallActivityNodeVisitorCall activity nodes become activities.
TaskFlowVisitorWithCustomTaskFlowVisitorTask sequence flows become transitions.
GatewayFlowVisitorWithCustomGatewayFlowVisitorGateway flows receive branch, trigger, and merge settings.
EventFlowVisitorWithCustomEventFlowVisitorEvent flows receive command, timer, or automatic triggers.
SubprocessFlowVisitorWithCustomSubprocessFlowVisitorFlows connect converted subprocess activities.
CallActivityFlowVisitorWithCustomCallActivityFlowVisitorFlows connect converted call activities.
ProcessVisitorWithCustomProcessVisitorComplete process, subprocess, and diagram conversion.

The task, gateway, and event visitors expose non-virtual dispatch methods such as AddTask and AddOutgoingFlow. Override their specialized protected virtual methods, such as AddServiceTask or AddOutgoingFlowExclusiveGateway, to change a particular BPMN type. CallActivityNodeVisitor.AddCallActivity and SubprocessNodeVisitor.AddSubprocessActivity are public virtual methods.

The default ProcessVisitor first creates nodes, then adds all sequence flows, then updates incoming flows. Incoming updates can override settings assigned during flow creation. Replace ProcessVisitor only when changes to individual node and flow visitors cannot express the required conversion.

Configure conversion settings

Build(BpmnConverterSettings? settings = null) assigns settings to the converter's visitors. When settings are omitted, visitors use the defaults below. Both members are init-only properties, so choose their values while constructing the settings object.

PropertyTypeDefaultWhen read and effect
DateTimeKindDateTimeKindLocalDuring fixed timeDate conversion, selects XML date handling as Local, Utc, or Unspecified. Duration and expression timers do not use this setting.
DefaultAutoSchemeUpdatebooltrueDuring BaseNodeVisitor.CreateActivity, enables or disables automatic scheme updates on the created activity. A custom visitor that bypasses this helper must apply its own defaults.

Converter settings affect subsequent imports through that converter. Creating another converter does not rewrite stored schemes or change existing process instances. The automatic update flag controls an activity's eligibility for the runtime's scheme update mechanism; it does not synchronize a scheme with its original BPMN file.

Replace call activity conversion

The default CallActivityNodeVisitor creates an ordinary activity and records an unsupported-call warning. The following configuration replaces that mapping with an application convention: a call to ReviewOrder becomes an activity implementation named Call_ReviewOrder.

Configure is an application helper in this example. Pass it an already configured Workflow Runtime before starting the runtime. It constructs the custom converter, passes it to BpmnPlugin, and registers the plugin with WithPlugin.

BpmnImportConfiguration.cs
using System;using OptimaJet.Workflow.BpmnPlugin;using OptimaJet.Workflow.BpmnPlugin.Import;using OptimaJet.Workflow.BpmnPlugin.Model;using OptimaJet.Workflow.Core.Model.Builder;using OptimaJet.Workflow.Core.Runtime;public static class BpmnImportConfiguration{    public static WorkflowRuntime Configure(WorkflowRuntime runtime)    {        var settings = new BpmnConverterSettings        {            DateTimeKind = DateTimeKind.Utc,            DefaultAutoSchemeUpdate = false        };        BpmnConverter converter = BpmnConverterBuilder.Create()            .WithCustomCallActivityNodeVisitor(new ApplicationCallVisitor())            .Build(settings);        return runtime.WithPlugin(new BpmnPlugin(converter));    }}public sealed class ApplicationCallVisitor : CallActivityNodeVisitor{    public override void AddCallActivity(        TCallActivity callActivity,        BpmnConverterContext context)    {        IActivityBuilder activityBuilder = CreateActivity(callActivity, context);        string calledName = callActivity.CalledElement?.Name;        if (string.IsNullOrWhiteSpace(calledName))        {            string issue = $"Call activity '{callActivity.Id}' has no calledElement.";            context.LogIssue(issue);            activityBuilder.CreateCommentary(issue);            return;        }        string actionName = $"Call_{calledName}";        activityBuilder.CreateImplementationAtEnd(actionName);        activityBuilder.CreateCommentary($"Application action: {actionName}.");    }}

CreateActivity preserves the standard ID-to-activity-name mapping, the BPMN name-to-state mapping, state-change eligibility for named nodes, and DefaultAutoSchemeUpdate. The normal diagram pass still assigns coordinates using the BPMN element ID. The default call activity flow visitor continues to connect the activity to its neighbors.

The helper calls State(flowNode.Name).EnableSetState() when the BPMN name is not blank and NotState() otherwise. These are the same state-setting decisions that an application visitor would apply when creating the activity directly through context.Builder.

This custom visitor creates an action reference; the application must implement and register each Call_<calledElement> action before executing the scheme. The example does not start a called BPMN process automatically or reproduce BPMN call activity execution semantics. If the application needs another execution model, change both its action implementation and the conversion convention.

Inspect conversion before saving

BpmnConverter.ConvertBpmnDocument converts BPMN XML without saving schemes or starting processes. Use it to inspect conversion issues before allowing an application import. This standalone .NET 10 program reads a BPMN file supplied as its only command-line argument and reports each converted scheme.

InspectBpmnImport.cs
using System;using System.IO;using OptimaJet.Workflow.BpmnPlugin.Import;if (args.Length != 1){    throw new ArgumentException("Pass the path to one BPMN XML file.");}BpmnConverter converter = BpmnConverterBuilder.Create().Build();using var reader = File.OpenText(args[0]);foreach (ConvertedProcess convertedProcess in converter.ConvertBpmnDocument(reader)){    Console.WriteLine($"Scheme: {convertedProcess.ProcessDefinition.Name}");    Console.WriteLine($"Skip saving: {convertedProcess.DontSave}");    foreach (string issue in convertedProcess.Issues)    {        Console.WriteLine($"Issue: {issue}");    }    if (convertedProcess.Hint is not null)    {        Console.WriteLine($"Hint: {convertedProcess.Hint.Message}");    }}

The reader overload accepts a TextReader and an optional mainSchemeCode. The model overload accepts OptimaJet.Workflow.BpmnPlugin.Model.TDefinitions and the same optional code. Both return List<ConvertedProcess>; the model overload uses an already deserialized BPMN document. A nonempty mainSchemeCode renames the first converted process that is neither inline nor marked DontSave.

Result memberMeaning
ProcessDefinitionConverted native scheme definition, including activities and transitions.
IssuesImmutable list of conversion warnings gathered for that process.
HasIssuestrue when Issues is nonempty.
HintOptional conversion hint with a type and explanatory message.
DontSavetrue when the hint type is ConvertedProcessHintType.DontSave.

The default converter marks a top-level process without activities as DontSave. Conversion does not run the runtime's full scheme save and build pipeline, so an issue-free conversion is not proof that a scheme can be saved or executed. XML deserialization and conversion can also throw exceptions; a service integrating this API must handle those failures separately from Issues.

BpmnConverterContext supplies a visitor's Builder, immutable FlowElements, and BpmnDocument. Use FindMessage, GetFlowNode, and GetSequenceFlow to resolve elements; each lookup can return null. Call LogIssue to add a process-level diagnostic. Add a commentary through the activity or transition builder as well when the warning should remain visible on the corresponding scheme element.

The BPMN import guide applies converters through the Designer's save pipeline. The supported elements reference describes the default mapping that a replacement visitor changes. The BpmnConverter API reference lists the public conversion overloads.

Frequently asked questions

How do I customize only one BPMN element type?

Replace the relevant visitor through BpmnConverterBuilder and override its specialized virtual method. The builder supplies default visitors for every category you leave unchanged.

Can I inspect a BPMN import without writing to the database?

Yes. ConvertBpmnDocument returns converted definitions and their diagnostics without invoking persistence. The Designer upload pipeline adds saving and build validation afterward.

Does changing converter settings update existing schemes?

No. BpmnConverterSettings controls conversion of new input; existing definitions retain their current values. Reimporting with overwrite enabled can replace stored schemes through the Designer import pipeline.

Does a custom CallActivityNodeVisitor automatically execute the called BPMN process?

No. A custom visitor defines the native activity mapping, and the application supplies the corresponding execution behavior. The example creates action references that require registered application implementations.