Delegate Providers
A DelegateProvider
registers a delegate module with
Behavior Execution Engine
via a Service Provider Interface (SPI) proxy. This occurs at the start of a
Behavior Execution Engine
simulation.
You need to include the SPI file in the resulting JAR to load the delegate module prior to running a simulation.
To create and include an SPI file, create a simple text file named com.agi.moxie.spi.DelegateProvider in the same
directory as your source directory (usually src) and the build.gradle file:
\resources\META-INF\services\com.agi.moxie.spi.DelegateProvider.
That file should contain the fully qualified canonical name of your DelegateProvider
for the delegate module.
For the example in Figure 1, the name is
com.agi.moxie.samples.balloonride.structure.impl.BalloonRideDelegateProvider
and you can find this SPI file in the sample code provided as a reference in your Behavior Execution Engine installation.
Let's take a look at the contents of BalloonRideDelegateProvider
in Figure 1:
package com.agi.moxie.samples.balloonride.structure.impl;
import com.agi.moxie.api.DelegateModuleDescriptor;
import com.agi.moxie.api.analysistools.BuiltInAnalysisToolController;
import com.agi.moxie.samples.balloonride.structure.Balloon;
import com.agi.moxie.samples.balloonride.structure.BalloonOperator;
import com.agi.moxie.samples.balloonride.structure.Passenger;
import com.agi.moxie.spi.DelegateProvider;
import tech.units.indriya.unit.Units;
import javax.measure.Unit;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* The {@link DelegateProvider} for the sample balloon ride simulation.
*/
public class BalloonRideDelegateProvider implements DelegateProvider {
@Override
public DelegateModuleDescriptor provideDescriptor() {
Map<String, Unit<?>> customUnits = new HashMap<>();
customUnits.put("MyCustomProject::units::meter", Units.METRE);
return new DelegateModuleDescriptor(
getClass(),
Arrays.asList(
AdultPassenger.class,
Balloon.class,
BalloonDelegate.class,
BalloonOperator.class,
BalloonOperatorDelegate.class,
ChildPassenger.class,
Passenger.class
), //Delegates
BuiltInAnalysisToolController.class, //AnalysisToolController
Collections.emptyList(), //Custom Stereotype implementations
customUnits
);
}
}
Figure 1: The balloon ride example's delegate provider
The only method you must implement for a DelegateProvider
is provideDescriptor()
,
which returns a DelegateModuleDescriptor
.
A DelegateModuleDescriptor
specifies the delegate types and the associated AnalysisToolController
.
You may also specify stereotype implementations for use in analysis tools and delegates.
Focusing on the list of delegates and the AnalysisToolController
parameters, you can see that these delegates
contain the
custom code which implements the opaque behaviors in the state machines. If you do not have any delegates written, you can specify
Collections.emptyList()
to serve as a placeholder. In Figure 1 above, the balloon ride sample uses
the
BuiltInAnalysisToolController
as its analysis tool controller.
The DelegateModuleDescriptor
also enables you to register custom units with the
Behavior Execution Engine
to resolve SysML value types at runtime. Using this method, you can map the fully qualified name of your SysML unit to the corresponding Unit<?>
for use in Java. This is the qualified name for the SysML unit, not the qualified name for the value type used as the type for a
value property. The engine will automatically handle the SysML quantity kind and custom value types based on which unit is specified in SysML. For
more information on the runtime usage and conversion of unit quantities, see the section on Units
under Properties and Operations.