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.
Constraint type and interface to implement
Constraints Interface Method IModelReferenceProvider CanRelate Method Candidate constraint when adding model reference IModelReferenceProvider GetReferences method Candidate constraint of entity type when creating model IModelCreationProvider GetCreatableClasses method
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
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 add | Interfaces to implement | Methods that need to be implemented |
---|---|---|
Allowability constraint when associating a model | IModelReferenceProvider | CanRelate method |
Candidate constraints when adding model references | IModelReferenceProvider | GetReferences method |
Entity type candidate constraint when creating a model | IModelCreationProvider | GetCreatableClasses 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.
}
}
}