Delegate Providers

A DelegateProvider registers a delegate module with the Moxie Engine via a Service Provider Interface (SPI) proxy. This occurs at the start of a Moxie 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 Moxie 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 Moxie 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.