Skip to main content

Adding dynamic constraints during model editing operations

Preview released

This function and the API used in this function have been released in advance. We do not guarantee the quality at this time, so please use it at your own risk. Also, please note that these specifications are subject to change without notice.

Overview

In addition to the multiplicity and path constraints that come standard with Next Design, you can add your own constraints based on model field values and more.

The following implementation is required to incorporate dynamic constraints:

  • Implementation of dynamic constraint interface
  • Implementation of dynamic constraint registration process

Implementation of dynamic constraint interface

Implement the interface according to the type of constraint.

Please refer to each API specification for details.

note
  • It is possible to implement multiple interfaces with the same dynamic constraint. For example, if you want to implement different model association permission constraints for each view, you can define a class for each view and implement IModelReferenceProvider.
  • The same type of dynamic constraint is applied in the order in which they are registered.
  • If an implementation of a dynamic constraint returns null, the following dynamic constraint applies: In the absence of the following dynamic constraints, the Next Design standard behavior applies.

Implementation of dynamic constraint registration process

Implement the dynamic constraint registration process in the public method Activate of the main class that implements IExtention. Use Register of IProject.EditingCapabilityProviderRegistry to register dynamic constraints.

Implementation example

Here is an example of implementing the IExtension interface in the EditingCapabilityEntryPoint class. The implementation of the possibility constraint at the time of model association and the candidate constraint at the time of adding the model reference is the ModelReferenceProvider class, and the implementation of the candidate constraint of the entity type at the time of model creation is the ModelCreationProvider class.

Implementation example of IExtension

    public class EditingCapabilityEntryPoint: IExtension
{
///<summary>
///Processing when extension is activated
///</summary>
///<param name = "context"> </param>
public void Activate (IContext context)
{
//Register the dynamic constraint.
var registry = context.App.Workspace.CurrentProject.EditingCapabilityProviderRegistry;
registry.Register (new ModelReferenceProvider (context));
registry.Register (new ModelCreationProvider ());
}
}

Sample: Addition of model and limitation of connector connection

As a sample of dynamic constraints during model editing operations, we will show you how to add constraints to model additions and connector connections. The following describes everything from creating a new Visual Studio project to actually embedding dynamic constraints.

Overall flow

  • Create a new Visual Studio project
  • Implementation of interface in dynamic constraint class
  • Implementation of dynamic constraint registration process

Public sample

  • A set of sample source code created by the following procedure is available on GitHub.

    External link: EditingCapabilitySample

Goal image

Screen capture or GIF animation Screen capture or GIF animation

  • Open the [Advanced Driving System Software Development] project from the Next Design sample project.

  • Constraints on the working model (including "TBD" in the name).

    • If "TBD" is included in the port name of the connection destination, connector connection is disabled.

      • When connecting the connector from [System Functional Structure]-[Functional Structure Diagram] in [System Logical Design], "Cannot be associated with TBD" is displayed.
    • If "TBD" is included in the name of the use case, the model that can be added is only "scenario" and the addition of conditions is disabled.

      • When adding a model by selecting a use case from [Use case]-[Use case Diagram] in [System Requirements Development], "Condition: Pre-condition" and "Condition: Post-condition" are not displayed.

Create a new Visual Studio project

When developing dynamic constraints when editing a model, select Class Library as the project type when creating a new project.

The following settings when creating a new project are the same as Tutorials> Batch Model Verification.

  • A copy of the extension development DLL
  • Added reference setting for extension development DLL
  • Automation of debug execution preparation

Create and define a new manifest. The following is similar to Tutorials> Bulk Model Validation.

  • Execution program entry point definition
  • Extension life cycle definition
  • Specify the target profile of the extension

The following definition is not required in the manifest to implement dynamic constraints when editing a model.

  • UI extension point definition (ribbon tab group button)
  • Command extension point definition

Implementation code

manifest.json

{
"name": "DensoCreate.NextDesign.Extensions.EditingCapabilitySample",
"version": "1.0.0",
"publisher": "DENSO CREATE Inc.",
"license": "Conforms to the Next Design License Agreement. Copyright (C) 2021 DENSO CREATE INC. All rights reserved.",

"main": "EditingCapabilitySample.dll", //Specify the build result DLL file name as an entry point.
"lifecycle": "project", //Specify the project lifecycle as the lifecycle.
"baseprofile": "In-vehicle system software development" //Specify the profile name as a condition of the target project.
}

Implementation of interface in dynamic constraint class

Add a class that implements dynamic constraints and implement the following interfaces depending on the type of constraint.

Constraints to addInterfaces to implementMethods that need to be implemented
Allowability constraint when associating a modelIModelReferenceProviderCanRelate method
Candidate constraints when adding model referencesIModelReferenceProviderGetReferences method
Entity type candidate constraint when creating a modelIModelCreationProviderGetCreatableClasses method

Implement the interface with the following class.

  • ModelReferenceProvider: Constraints on whether or not to associate an editor model
  • ModelCreationProvider: Entity type candidate constraint when creating a model

Implementation code

Implement IModelReferenceProvider to limit connections to models with TBD in their names.

ModelReferenceProvider.cs

using System.Linq;
using NextDesign.Core;
using NextDesign.Core.EditingCapabilities;
using NextDesign.Desktop;

namespace Editing Capability
{
///<summary>
///A provider that customizes the model association function
///</summary>
public class ModelReferenceProvider: IModelReferenceProvider
{
///<summary>
///Context.
///</summary>
private IContext m_Context;

#region construction/disappearance

///<summary>
///Constructor.
///</summary>
///<param name = "context"> context </param>
public ModelReferenceProvider (IContext context)
{
m_Context = context;
}

#endregion

///<summary>
///Get selection candidates when referencing a model
///</summary>
///<param name = "referableParams"> Parameters for determining selection candidates </param>
///<returns> Candidate results </returns>
public ModelReferableResult GetReferences (ModelReferableParams referableParams)
{
var model = referableParams.Model;
var modelMetaClass = model.Metaclass;
var field = referableParams.Field;

//Narrow down the candidates for the connection destination port
if (! IsPort (modelMetaClass))
{
//No judgment is required except for the port
return null;
}

if (field.Name! = "ToPorts")
{
//No judgment is required except for the connection destination port
return null;
}

var result = CapabilityResults.Ignore;
var models = Enumerable.Empty <IModel> ();

if (IsInputPort (modelMetaClass))
{
//If it is an input port
//Candidates for input ports of child components of their own parent (component) and whose names do not include TBD.
result = CapabilityResults.Success;
var metamodels = m_Context.App.Workspace.CurrentProject.Profile.Metamodels;
var subSystems = model.Owner.GetChildren (). Where (c => c.Metaclass.IsClassOf (metamodels.GetClass ("SubSystem")));
var inputPorts = subSystems.SelectMany (s => s.GetChildren (). Where (c => (
IsInputPort (c.Metaclass)
&& (! c.Name.Contains ("TBD"))
)));
models = inputPorts;
}
else if (IsOutputPort (modelMetaClass))
{
//If it is an output port
//With the input port of the child component (function only) of the parent (component) of its own parent (component)
//Candidates for the output port of the parent (component) of its own parent (component) and whose name does not include TBD.
result = CapabilityResults.Success;
var metamodels = m_Context.App.Workspace.CurrentProject.Profile.Metamodels;
var subSystems = model.Owner.Owner.GetChildren (). Where (c => c.Metaclass.IsClassOf (metamodels.GetClass ("SubSystem"))). ToList ();
var inputPorts = subSystems.SelectMany (s => s.GetChildren (). Where (c => (
IsInputPort (c.Metaclass)
&& (! c.Name.Contains ("TBD"))
)));
var outputPorts = model.Owner.Owner.GetChildren (). Where (c => (
IsOutputPort (c.Metaclass)
&& (! c.Name.Contains ("TBD"))
));
models = inputPorts.Union (outputPorts);
}

var referenceResult = new ModelReferableResult
{
Result = result,
Models = models
};;
return referenceResult;
}

///<summary>
///Judge whether model association is possible
///</summary>
///<param name = "relateParams"> Parameters for determining whether to associate </params </param>
///<returns> Results of association availability </returns>
public ModelRelateResult CanRelate (ModelRelateParams relateParams)
{
var model = relateParams.Model;
var opposite = relateParams.OppositeModel;
var modelMetaClass = model.Metaclass;
var oppositeMetaClass = opposite.Metaclass;

| if (! IsPort (modelMetaClass) ||! IsPort (oppositeMetaClass)) |
{
//Returns null to keep the standard of Next Design except for the port
return null;
}

var result = CapabilityResults.Ignore;
var canRelate = false;
string guideText = null;
//Restrict connections with ports that include "TBD" in their names.
if (opposite.Name.Contains ("TBD"))
{
result = CapabilityResults.Success;
canRelate = false;
guideText = "Cannot be associated with TBD";
}
else else
{
//Returns null to keep the Next Design standard pass/fail judgment except for TBD.
return null;
}
var relateResult = new ModelRelateResult
{
Result = result,
CanRelate = canRelate,
GuideText = guideText
};;

return relateResult;
}

///<summary>
///Determine if the target class is a port
///</summary>
///<param name = "targetClass"> Target class </param>
///True for <returns> ports </returns>
private bool IsPort (IClass targetClass)
{
var metamodels = m_Context.App.Workspace.CurrentProject.Profile.Metamodels;
IClass systemStructurePortBase = metamodels.GetClass ("SystemStructurePortBase");

return targetClass.IsClassOf (systemStructurePortBase);
}

///<summary>
///Determine if the target class is an input port
///</summary>
///<param name = "targetClass"> Target class </param>
///True for <returns> ports </returns>
private bool IsInputPort (IClass targetClass)
{
var metamodels = m_Context.App.Workspace.CurrentProject.Profile.Metamodels;
IClass inputPort = metamodels.GetClass ("FuntionFlowInputPortInnerSystem");

return targetClass.IsClassOf (inputPort);
}

///<summary>
///Determine if the target class is an output port
///</summary>
///<param name = "targetClass"> Target class </param>
///True for <returns> ports </returns>
private bool IsOutputPort (IClass targetClass)
{
var metamodels = m_Context.App.Workspace.CurrentProject.Profile.Metamodels;
IClass outputPort = metamodels.GetClass ("FuntionFlowOutputPortInnerSystem");

return targetClass.IsClassOf (outputPort);
}
}
}

Implement IModelCreationProvider and limit the models you add to use cases that include TBD in their names.

ModelCreationProvider.cs

using System;
using System.Collections.Generic;
using System.Text;
using NextDesign.Core;
using NextDesign.Core.EditingCapabilities;
using NextDesign.Desktop;
using System.Linq;

namespace Editing Capability
{
class ModelCreationProvider: IModelCreationProvider
{
public ModelCreatableResult GetCreatableClasses (ModelCreatableParams creatableParams)
{
//Return null because it is out of scope except for use cases, and leave it to the Next Design standard.
var metaClass = creatableParams.Owner.Metaclass;
var metamodels = creatableParams.Project.Profile.Metamodels;
IClass requirementClass = metamodels.GetClass ("UseCase");
if (requirementClass! = null)
{
if (! metaClass.IsClassOf (requirementClass))
{
return null;
}
}
//Use cases without "TBD" in the name will return null as there are no particular restrictions.
if (! creativeParams.Owner.Name.Contains ("TBD"))
{
return null;
}

//Use cases with "TBD" in the name do not require any conditions, and the rule is to create only the scenario.
var creatableResult = new ModelCreatableResult
{
Result = CapabilityResults.Success
};;

//Since there are default display candidates in DefaultTypes, only the necessary ones are packed in the return value.
foreach (var type in creatableParams.DefaultTypes)
{
//Since the condition does not need to be created, add only the other conditions.
if (! type.Value.First (). Name.Contains ("Condition"))
{
creatableResult.AddCreatableClasses (type.Key.Name, type.Value);
}
}

return creatableResult;
}
}
}

Implementation of dynamic constraint registration process

Implement the dynamic constraint registration process in the public method Activate of the main class that implements IExtention. There is no need to unregister with the main class public method Deactviate.

Implementation code

Implement model addition and connector connection registration/deregistration.

EditingCapabilityEntryPoint.cs

using NextDesign.Core;
using NextDesign.Desktop;
using NextDesign.Extension;

namespace Editing Capability
{
///<summary>
///Extension entry point for dynamic constraints during model editing operations
///</summary>
public class EditingCapabilityEntryPoint: IExtension
{
///<summary>
///Activate the extension
///</summary>
///<param name = "context"> Execution context </param>
public void Activate (IContext context)
{
//Register the dynamic constraint.
var registry = context.App.Workspace.CurrentProject.EditingCapabilityProviderRegistry;
registry.Register (new ModelReferenceProvider (context));
registry.Register (new ModelCreationProvider ());
}

///<summary>
///Deactivate the extension
///</summary>
///<param name = "context"> Execution context </param>
public void Deactivate (IContext context)
{
//There is no need to remove the constraint.
}
}
}