diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index ea216f077..a01f4aed6 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -48,6 +48,7 @@ One creates a `ConcernUsage` and another one creates `FramedConcernMembership`. This is currently supported on `Features` (e.g. `Attribute`), `Constraints` and `Transitions` (guard conditions) view new context menu actions (_Create expression_ and _Edit expression_) on the corresponding elements in the _Explorer_. - https://github.com/eclipse-syson/syson/issues/2247[#2247] [diagrams] Add the support for creating _timeslices/snapshots_ from the different kind of `OccurrenceDefiniton` graphical nodes. It leverages the selection dialog to either create an _occurrence timeslice/snapshot_, or the _usage timeslice/snapshot_ matching the `OccurrenceDefinition` on which the tool is applied. +- https://github.com/eclipse-syson/syson/issues/2250[#2250] [diagrams] Leverage the selection dialog to improve the graphical node tools creating a _require_ `ConstraintUsage`, or an _assume_ `ConstraintUsage`, from `RequirementUsage` and `RequirementDefinition` graphical nodes. == v2026.5.0 diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeRequirementCreationTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeRequirementCreationTests.java index e7d87552b..1d3b7b3b7 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeRequirementCreationTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeRequirementCreationTests.java @@ -45,7 +45,9 @@ import org.eclipse.syson.application.controllers.diagrams.testers.ToolTester; import org.eclipse.syson.application.controllers.utils.TestNameGenerator; import org.eclipse.syson.application.data.GeneralViewWithTopNodesTestProjectData; +import org.eclipse.syson.diagram.common.view.nodes.AssumeConstraintCompartmentItemNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.FramedConcernCompartmentItemNodeDescription; +import org.eclipse.syson.diagram.common.view.nodes.RequireConstraintCompartmentItemNodeDescription; import org.eclipse.syson.services.SemanticRunnableFactory; import org.eclipse.syson.services.diagrams.DiagramComparator; import org.eclipse.syson.services.diagrams.DiagramDescriptionIdProvider; @@ -54,11 +56,13 @@ import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; import org.eclipse.syson.sysml.ConcernUsage; +import org.eclipse.syson.sysml.ConstraintUsage; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.FramedConcernMembership; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.ReferenceSubsetting; import org.eclipse.syson.sysml.ReferenceUsage; +import org.eclipse.syson.sysml.RequirementConstraintMembership; import org.eclipse.syson.sysml.Specialization; import org.eclipse.syson.sysml.Subsetting; import org.eclipse.syson.sysml.SysmlPackage; @@ -144,8 +148,21 @@ private static Stream concernUsageChildNodeParameters() { private static Stream concernUsageSiblingAndChildNodeParameters() { return Stream.of( - Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "assume constraints", SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), "New Assume constraint", 6, 1), - Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "require constraints", SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), "New Require constraint", 6, 1)) + Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "assume constraints", SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), "New Assume constraint", AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, 6, 1), + Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "require constraints", SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), "New Require constraint", RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, 6, 1)) + .map(TestNameGenerator::namedArguments); + } + + private static Stream createSubsettedConstraintUsageNodes() { + return Stream.of( + Arguments.of(SysmlPackage.eINSTANCE.getRequirementUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_USAGE_ID, "requirement", "New Assume constraint", "assume constraints", AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getRequirementDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_DEFINITION_ID, "RequirementDefinition", "New Assume constraint", "assume constraints", AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getRequirementUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_USAGE_ID, "requirement", "New Require constraint", "require constraints", RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getRequirementDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_DEFINITION_ID, "RequirementDefinition", "New Require constraint", "require constraints", RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getConcernUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_USAGE_ID, "concern", "New Assume constraint", "assume constraints", AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getConcernDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_DEFINITION_ID, "ConcernDefinition", "New Assume constraint", "assume constraints", AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getConcernUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_USAGE_ID, "concern", "New Require constraint", "require constraints", RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint()), + Arguments.of(SysmlPackage.eINSTANCE.getConcernDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_DEFINITION_ID, "ConcernDefinition", "New Require constraint", "require constraints", RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint())) .map(TestNameGenerator::namedArguments); } @@ -164,9 +181,14 @@ private static Stream concernDefinitionChildNodeParameters() { private static Stream concernDefinitionSiblingAndChildNodeParameters() { return Stream.of( - Arguments.of(SysmlPackage.eINSTANCE.getRequirementUsage(), "requirements", SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement(), null, 11, 1), - Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "assume constraints", SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), "New Assume constraint", 6, 1), - Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "require constraints", SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint(), "New Require constraint", 6, 1)) + Arguments.of(SysmlPackage.eINSTANCE.getRequirementUsage(), "requirements", SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement(), null, 11, 1)) + .map(TestNameGenerator::namedArguments); + } + + private static Stream createConcernDefinitionSiblingAndChildNodesWithCustomTools() { + return Stream.of( + Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "assume constraints", SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), "New Assume constraint", AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, 6, 1), + Arguments.of(SysmlPackage.eINSTANCE.getConstraintUsage(), "require constraints", SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint(), "New Require constraint", RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME, 6, 1)) .map(TestNameGenerator::namedArguments); } @@ -336,7 +358,7 @@ public void createConcernUsageChildNodes(EClass childEClass, String compartmentN @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) @ParameterizedTest @MethodSource("concernUsageSiblingAndChildNodeParameters") - public void createConcernUsageSiblingAndChildNodes(EClass childEClass, String compartmentName, EReference containmentReference, String creationToolNameParameter, int expectedNumberOfNewNodes, + public void createConcernUsageSiblingAndChildNodes(EClass childEClass, String compartmentName, EReference containmentReference, String creationToolNameParameter, String compartmentItemSuffix, int expectedNumberOfNewNodes, int expectedNumberOfNewEdges) { var flux = this.givenSubscriptionToDiagram(); @@ -357,14 +379,14 @@ public void createConcernUsageSiblingAndChildNodes(EClass childEClass, String co creationToolName = this.descriptionNameGenerator.getCreationToolName(childEClass); } - Runnable createNodeRunnable = this.creationTestsService.createNode(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, creationToolName); + Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithoutSelectionProvided(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, creationToolName); Consumer diagramCheck = assertRefreshedDiagramThat(newDiagram -> { var initialDiagram = diagram.get(); new CheckDiagramElementCount(this.diagramComparator) .hasNewNodeCount(expectedNumberOfNewNodes) .hasNewEdgeCount(expectedNumberOfNewEdges) .check(initialDiagram, newDiagram); - String listStatesNodeDescription = this.descriptionNameGenerator.getCompartmentItemName(parentEClass, containmentReference); + String listStatesNodeDescription = this.descriptionNameGenerator.getCompartmentItemName(parentEClass, containmentReference) + compartmentItemSuffix; new CheckNodeInCompartment(diagramDescriptionIdProvider, this.diagramComparator) .withTargetObjectId(targetObjectId) .withCompartmentName(compartmentName) @@ -383,6 +405,74 @@ public void createConcernUsageSiblingAndChildNodes(EClass childEClass, String co .verify(Duration.ofSeconds(10)); } + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) + @MethodSource("createSubsettedConstraintUsageNodes") + @ParameterizedTest + public void createSubsettedConstraintUsageNodes(EClass parentEClass, String targetObjectId, String parentLabel, String toolName, String compartmentName, String compartmentItemSuffix, EReference containmentReference) { + var flux = this.givenSubscriptionToDiagram(); + + var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID); + var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider); + + AtomicReference diagram = new AtomicReference<>(); + Consumer initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram::set); + + Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithSingleSelection(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, toolName, GeneralViewWithTopNodesTestProjectData.SemanticIds.CONSTRAINT_USAGE_ID); + Consumer diagramCheck = assertRefreshedDiagramThat(newDiagram -> { + new CheckDiagramElementCount(this.diagramComparator) + .hasNewNodeCount(6) + .hasNewEdgeCount(2) + .check(diagram.get(), newDiagram); + + new CheckDiagramElementCount(this.diagramComparator) + .hasNewNodeCount(0) + .hasNewEdgeCount(0) + .check(diagram.get(), newDiagram, true); + + String listConstraintNodeDescription = this.descriptionNameGenerator.getCompartmentItemName(parentEClass, containmentReference) + compartmentItemSuffix; + new CheckNodeInCompartment(diagramDescriptionIdProvider, this.diagramComparator) + .withTargetObjectId(targetObjectId) + .withCompartmentName(compartmentName) + .hasNodeDescriptionName(listConstraintNodeDescription) + .hasCompartmentCount(0) + .check(diagram.get(), newDiagram); + }); + + Consumer additionalCheck = object -> { + assertThat(object).isInstanceOf(List.class) + .asInstanceOf(type(List.class)) + .satisfies(constraints -> { + assertThat((List) constraints).size().isEqualTo(1); + assertThat(constraints.getFirst()) + .isInstanceOf(ConstraintUsage.class) + .asInstanceOf(type(ConstraintUsage.class)) + .satisfies(constraint -> { + assertThat(constraint.eContainer()).isInstanceOf(RequirementConstraintMembership.class) + .asInstanceOf(type(RequirementConstraintMembership.class)) + .satisfies(membership -> { + assertThat(this.identityService.getId(membership.getReferencedConstraint())).isEqualTo(GeneralViewWithTopNodesTestProjectData.SemanticIds.CONSTRAINT_USAGE_ID); + assertThat(constraint.getOwnedRelationship().getFirst()).isInstanceOf(ReferenceSubsetting.class) + .asInstanceOf(type(ReferenceSubsetting.class)) + .satisfies(referenceSubsetting -> { + assertThat(referenceSubsetting.getReferencedFeature()).isEqualTo(membership.getReferencedConstraint()); + }); + }); + }); + }); + }; + + Runnable semanticCheck = this.semanticCheckerService.checkEditingContext(this.semanticCheckerService.getElementInParentSemanticChecker(parentLabel, containmentReference, SysmlPackage.eINSTANCE.getConstraintUsage(), additionalCheck)); + + StepVerifier.create(flux) + .consumeNextWith(initialDiagramContentConsumer) + .then(createNodeRunnable) + .consumeNextWith(diagramCheck) + .then(semanticCheck) + .thenCancel() + .verify(Duration.ofSeconds(10)); + } + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) @ParameterizedTest @MethodSource("concernUsageBorderAndChildNodeParameters") @@ -480,6 +570,56 @@ public void createConcernDefinitionSiblingAndChildNodes(EClass childEClass, Stri .verify(Duration.ofSeconds(10)); } + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) + @ParameterizedTest + @MethodSource("createConcernDefinitionSiblingAndChildNodesWithCustomTools") + public void createConcernDefinitionSiblingAndChildNodesWithCustomTools(EClass childEClass, String compartmentName, EReference containmentReference, String creationToolNameParameter, String compartmentItemSuffix, int expectedNumberOfNewNodes, + int expectedNumberOfNewEdges) { + var flux = this.givenSubscriptionToDiagram(); + + AtomicReference diagram = new AtomicReference<>(); + Consumer initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram::set); + + var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID, + SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID); + var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider); + + EClass parentEClass = SysmlPackage.eINSTANCE.getConcernDefinition(); + String targetObjectId = GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_DEFINITION_ID; + + final String creationToolName; + if (creationToolNameParameter != null) { + creationToolName = creationToolNameParameter; + } else { + creationToolName = this.descriptionNameGenerator.getCreationToolName(childEClass); + } + + Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithoutSelectionProvided(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, creationToolName); + Consumer diagramCheck = assertRefreshedDiagramThat(newDiagram -> { + var initialDiagram = diagram.get(); + new CheckDiagramElementCount(this.diagramComparator) + .hasNewNodeCount(expectedNumberOfNewNodes) + .hasNewEdgeCount(expectedNumberOfNewEdges) + .check(initialDiagram, newDiagram); + String listStatesNodeDescription = this.descriptionNameGenerator.getCompartmentItemName(parentEClass, containmentReference) + compartmentItemSuffix; + new CheckNodeInCompartment(diagramDescriptionIdProvider, this.diagramComparator) + .withTargetObjectId(targetObjectId) + .withCompartmentName(compartmentName) + .hasNodeDescriptionName(listStatesNodeDescription) + .hasCompartmentCount(0) + .check(initialDiagram, newDiagram); + }); + Runnable semanticCheck = this.semanticCheckerService.checkEditingContext(this.semanticCheckerService.getElementInParentSemanticChecker("ConcernDefinition", containmentReference, childEClass)); + + StepVerifier.create(flux) + .consumeNextWith(initialDiagramContentConsumer) + .then(createNodeRunnable) + .consumeNextWith(diagramCheck) + .then(semanticCheck) + .thenCancel() + .verify(Duration.ofSeconds(10)); + } + @GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }) @ParameterizedTest @MethodSource("concernDefinitionChildNodeParameters") diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationExposeService.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationExposeService.java index f04e9eed2..e5d5cb54e 100644 --- a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationExposeService.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/DiagramMutationExposeService.java @@ -50,6 +50,7 @@ import org.eclipse.syson.sysml.PartDefinition; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.PortUsage; +import org.eclipse.syson.sysml.RequirementConstraintMembership; import org.eclipse.syson.sysml.SysmlFactory; import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysml.TextualRepresentation; @@ -140,11 +141,12 @@ public Element expose(Element element, IEditingContext editingContext, DiagramCo viewUsage.getOwnedRelationship().add(membershipExpose); new ElementInitializerSwitch().doSwitch(membershipExpose); // if it is the General View, we want to hide tree elements if a compartment containing the same - // element is displayed or it is displayed as border node + // element is displayed or it is displayed as border node, or if there is another exposed relation if (selectedNode != null && ViewDefinitionKind.isGeneralView(this.utilService.getViewDefinitionKind(element, List.of(), editingContext))) { this.hideNodeIfVisibleCompartmentCouldHostTheFutureNode(element, editingContext, diagramContext, selectedNode, convertedNodes); this.hideNodeIfBorderNodeCouldHostTheFutureNode(element, editingContext, diagramContext, selectedNode, convertedNodes); this.hideNodeIfNestedIsDefault(element, editingContext, diagramContext, selectedNode, convertedNodes); + this.hideNodeIfHasReferenceSubset(element, editingContext, diagramContext, selectedNode, convertedNodes); } } } @@ -276,7 +278,7 @@ public boolean removeFromExposedElements(Element element, Node selectedNode, IEd * Returns the elements contained by {@code parentElement} that should be rendered. *

* This method is typically used by - * {@link #addToExposedElements(Element, IEditingContext, DiagramContext, Node, Map, boolean)} to navigate the model + * {@link #addToExposedElements(Element, boolean, IEditingContext, DiagramContext, Node, Map)} to navigate the model * and find the elements to display. *

* @@ -486,6 +488,24 @@ private void hideNodeIfNestedIsDefault(Element element, IEditingContext editingC } } + private void hideNodeIfHasReferenceSubset(Element element, IEditingContext editingContext, DiagramContext diagramContext, Node selectedNode, Map convertedNodes) { + var owningMembership = element.getOwningMembership(); + if (owningMembership.eClass().equals(SysmlPackage.eINSTANCE.getRequirementConstraintMembership())) { + var requirementConstraintMembership = (RequirementConstraintMembership) owningMembership; + if (requirementConstraintMembership.getReferencedConstraint() != requirementConstraintMembership.getOwnedConstraint() && requirementConstraintMembership.getOwnedConstraint() == element) { + var parentId = this.diagramQueryElementService.getGraphicalParentId(diagramContext, selectedNode); + var descriptionId = this.diagramQueryElementService.getNodeDescriptionId(element, diagramContext.diagram(), editingContext); + if (parentId != null && descriptionId.isPresent()) { + var nodeId = new NodeIdProvider().getNodeId(parentId, + descriptionId.get(), + NodeContainmentKind.CHILD_NODE, + this.siriusWebCoreServices.identityService().getId(element)); + diagramContext.diagramEvents().add(new HideDiagramElementEvent(Set.of(nodeId), true)); + } + } + } + } + private boolean isItemNotContainedByAction(Element element) { boolean isItemNotContainedByAction = false; if (Objects.equals(SysmlPackage.eINSTANCE.getItemUsage(), element.eClass())) { diff --git a/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/ModelMutationElementService.java b/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/ModelMutationElementService.java index 4d4922770..3aa953add 100644 --- a/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/ModelMutationElementService.java +++ b/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/ModelMutationElementService.java @@ -19,6 +19,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.sirius.components.emf.utils.SiriusEMFCopier; import org.eclipse.syson.sysml.ConcernUsage; +import org.eclipse.syson.sysml.ConstraintUsage; import org.eclipse.syson.sysml.Definition; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.FeatureTyping; @@ -26,6 +27,8 @@ import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.Relationship; +import org.eclipse.syson.sysml.RequirementConstraintKind; +import org.eclipse.syson.sysml.RequirementConstraintMembership; import org.eclipse.syson.sysml.RequirementDefinition; import org.eclipse.syson.sysml.RequirementUsage; import org.eclipse.syson.sysml.SatisfyRequirementUsage; @@ -235,6 +238,42 @@ public FramedConcernMembership createFramedConcern(Type type, ConcernUsage conce return null; } + /** + * In a {@link RequirementUsage} or a {@link RequirementDefinition}, creates a {@link RequirementConstraintMembership} containing a {@link ConstraintUsage}. + * The {@link RequirementConstraintKind} is used to indicate whether the constraint is {@code required} or {@code assumed}. + * If a {@link ConstraintUsage} is given, the {@link RequirementConstraintMembership} owned constraint will be subsetted by the given {@link ConstraintUsage}. + * + * @param type + * the type that will hold the {@link RequirementConstraintMembership}, {@code type} must be a {@link RequirementDefinition} or a requirementUsage + * @param constraintUsage + * the {@link ConstraintUsage} subsetted by reference, can be {@code null} + * @param constraintKind + * whether the constraint is {@code required} or {@code assumed} + * @return the created {@link RequirementConstraintMembership} when {@code type} is a {@link RequirementDefinition}, or a {@link RequirementUsage}, {@code null} otherwise + */ + public RequirementConstraintMembership createConstraint(Type type, ConstraintUsage constraintUsage, RequirementConstraintKind constraintKind) { + if (type instanceof RequirementDefinition || type instanceof RequirementUsage) { + var newRequirementConstraintMembership = SysmlFactory.eINSTANCE.createRequirementConstraintMembership(); + type.getOwnedRelationship().add(newRequirementConstraintMembership); + newRequirementConstraintMembership.setKind(constraintKind); + + var newConstraintUsage = SysmlFactory.eINSTANCE.createConstraintUsage(); + newRequirementConstraintMembership.getOwnedRelatedElement().add(newConstraintUsage); + + this.metamodelMutationElementService.initialize(newRequirementConstraintMembership); + this.metamodelMutationElementService.initialize(newConstraintUsage); + + if (constraintUsage != null) { + var newReferenceSubsetting = SysmlFactory.eINSTANCE.createReferenceSubsetting(); + newConstraintUsage.getOwnedRelationship().add(newReferenceSubsetting); + newReferenceSubsetting.setReferencedFeature(constraintUsage); + this.metamodelMutationElementService.initialize(newReferenceSubsetting); + } + return newRequirementConstraintMembership; + } + return null; + } + /** * Creates a {@link SatisfyRequirementUsage SatisfyRequirement} on {@code parentElement}. *

diff --git a/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/aql/ModelMutationAQLService.java b/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/aql/ModelMutationAQLService.java index 44970c6a9..b97218e47 100644 --- a/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/aql/ModelMutationAQLService.java +++ b/backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/aql/ModelMutationAQLService.java @@ -18,10 +18,12 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.syson.model.services.ModelMutationElementService; import org.eclipse.syson.sysml.ConcernUsage; +import org.eclipse.syson.sysml.ConstraintUsage; import org.eclipse.syson.sysml.Documentation; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.Membership; import org.eclipse.syson.sysml.PartUsage; +import org.eclipse.syson.sysml.RequirementConstraintKind; import org.eclipse.syson.sysml.RequirementUsage; import org.eclipse.syson.sysml.Type; import org.eclipse.syson.sysml.ViewUsage; @@ -113,4 +115,11 @@ public Element setAsView(ViewUsage viewUsage, String newViewDefinition) { public Element createFramedConcern(Type type, ConcernUsage concernUsage) { return this.modelMutationElementService.createFramedConcern(type, concernUsage); } + + /** + * {@link ModelMutationElementService#createConstraint(Type, ConstraintUsage, RequirementConstraintKind)}. + */ + public Element createConstraint(Type type, ConstraintUsage constraintUsage, RequirementConstraintKind constraintKind) { + return this.modelMutationElementService.createConstraint(type, constraintUsage, constraintKind); + } } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AssumeConstraintCompartmentItemNodeDescription.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AssumeConstraintCompartmentItemNodeDescription.java new file mode 100644 index 000000000..51203a0d2 --- /dev/null +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AssumeConstraintCompartmentItemNodeDescription.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.diagram.common.view.nodes; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.view.builder.providers.IColorProvider; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.util.IDescriptionNameGenerator; +import org.eclipse.syson.util.SysMLMetamodelHelper; + +/** + * Used to create a {@link org.eclipse.syson.sysml.ConstraintUsage} compartment item node description. + *

+ * {@link org.eclipse.syson.sysml.ConstraintUsage} compartment items have to be contained in a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#ASSUMPTION}. + *

+ * @author gcoutable + */ +public class AssumeConstraintCompartmentItemNodeDescription extends CompartmentItemNodeDescriptionProvider { + public static final String COMPARTMENT_ITEM_NAME = " assume constraint"; + + public AssumeConstraintCompartmentItemNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) { + super(eClass, eReference, colorProvider, descriptionNameGenerator); + } + + @Override + protected String getDomainType() { + return SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getElement()); + } + + @Override + protected String getName() { + return super.getName() + COMPARTMENT_ITEM_NAME; + } +} diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AssumeConstraintCompartmentNodeDescription.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AssumeConstraintCompartmentNodeDescription.java new file mode 100644 index 000000000..00a61f4f9 --- /dev/null +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AssumeConstraintCompartmentNodeDescription.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.diagram.common.view.nodes; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; +import org.eclipse.sirius.components.view.builder.providers.IColorProvider; +import org.eclipse.sirius.components.view.builder.providers.INodeToolProvider; +import org.eclipse.sirius.components.view.diagram.DiagramDescription; +import org.eclipse.sirius.components.view.diagram.NodeDescription; +import org.eclipse.syson.diagram.common.view.tools.AssumeConstraintNodeToolProvider; +import org.eclipse.syson.util.IDescriptionNameGenerator; + +/** + * Compartment node allowing to display {@link org.eclipse.syson.sysml.ConstraintUsage} owned by a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#ASSUMPTION}. + * + * @author gcoutable + */ +public class AssumeConstraintCompartmentNodeDescription extends AbstractCompartmentNodeDescriptionProvider { + + public static final String COMPARTMENT_NAME = " assume"; + + public AssumeConstraintCompartmentNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) { + super(eClass, eReference, colorProvider, descriptionNameGenerator); + } + + @Override + protected String getCompartmentName() { + return this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + COMPARTMENT_NAME; + } + + @Override + protected String getCustomCompartmentLabel() { + return "assume constraints"; + } + + @Override + public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) { + cache.getNodeDescription(this.getCompartmentName()).ifPresent(nodeDescription -> { + cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentItemName(this.eClass, this.eReference) + AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME) + .ifPresent(itemNodeDescription -> nodeDescription.getChildrenDescriptions().add(itemNodeDescription)); + nodeDescription.setPalette(this.createCompartmentPalette(cache)); + }); + } + + @Override + protected List getItemCreationToolProviders() { + return List.of(new AssumeConstraintNodeToolProvider()); + } + + @Override + protected List getDroppableNodes(IViewDiagramElementFinder cache) { + return List.of(); + } +} diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/RequireConstraintCompartmentItemNodeDescription.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/RequireConstraintCompartmentItemNodeDescription.java new file mode 100644 index 000000000..eca178967 --- /dev/null +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/RequireConstraintCompartmentItemNodeDescription.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.diagram.common.view.nodes; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.view.builder.providers.IColorProvider; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.util.IDescriptionNameGenerator; +import org.eclipse.syson.util.SysMLMetamodelHelper; + +/** + * Used to create a {@link org.eclipse.syson.sysml.ConstraintUsage} compartment item node description. + *

+ * {@link org.eclipse.syson.sysml.ConstraintUsage} compartment items have to be contained in a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#REQUIREMENT}. + *

+ * @author gcoutable + */ +public class RequireConstraintCompartmentItemNodeDescription extends CompartmentItemNodeDescriptionProvider { + public static final String COMPARTMENT_ITEM_NAME = " require constraint"; + + public RequireConstraintCompartmentItemNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) { + super(eClass, eReference, colorProvider, descriptionNameGenerator); + } + + @Override + protected String getDomainType() { + return SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getElement()); + } + + @Override + protected String getName() { + return super.getName() + COMPARTMENT_ITEM_NAME; + } +} diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/RequireConstraintCompartmentNodeDescription.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/RequireConstraintCompartmentNodeDescription.java new file mode 100644 index 000000000..16f4863f3 --- /dev/null +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/RequireConstraintCompartmentNodeDescription.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.diagram.common.view.nodes; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; +import org.eclipse.sirius.components.view.builder.providers.IColorProvider; +import org.eclipse.sirius.components.view.builder.providers.INodeToolProvider; +import org.eclipse.sirius.components.view.diagram.DiagramDescription; +import org.eclipse.sirius.components.view.diagram.NodeDescription; +import org.eclipse.syson.diagram.common.view.tools.RequireConstraintNodeToolProvider; +import org.eclipse.syson.util.IDescriptionNameGenerator; + +/** + * Compartment node allowing to display {@link org.eclipse.syson.sysml.ConstraintUsage} owned by a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#REQUIREMENT}. + * + * @author gcoutable + */ +public class RequireConstraintCompartmentNodeDescription extends AbstractCompartmentNodeDescriptionProvider { + + public static final String COMPARTMENT_NAME = " require"; + + public RequireConstraintCompartmentNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) { + super(eClass, eReference, colorProvider, descriptionNameGenerator); + } + + @Override + protected String getCompartmentName() { + return this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + COMPARTMENT_NAME; + } + + @Override + protected String getCustomCompartmentLabel() { + return "require constraints"; + } + + @Override + public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) { + cache.getNodeDescription(this.getCompartmentName()).ifPresent(nodeDescription -> { + cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentItemName(this.eClass, this.eReference) + RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME) + .ifPresent(itemNodeDescription -> nodeDescription.getChildrenDescriptions().add(itemNodeDescription)); + nodeDescription.setPalette(this.createCompartmentPalette(cache)); + }); + } + + @Override + protected List getItemCreationToolProviders() { + return List.of(new RequireConstraintNodeToolProvider()); + } + + @Override + protected List getDroppableNodes(IViewDiagramElementFinder cache) { + return List.of(); + } +} diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java index 91d039150..06d27d6cf 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java @@ -626,6 +626,34 @@ public List getConcernReferenceSelectionDialogChildren(Object return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getConcernUsage())); } + /** + * Provides the root elements in the tree of the selection dialog for presenting all existing ConstraintUsage. + * + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that + * contain at least one {@link org.eclipse.syson.sysml.ConstraintUsage}. + */ + public List getConstraintReferenceSelectionDialogElements(IEditingContext editingContext) { + return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getConstraintUsage())); + } + + /** + * Provides the children of element in the tree of the selection dialog for presenting all existing ConstraiNtUsage. + * + * @param selectionDialogTreeElement + * a (non-{@code null}) selection dialog tree element. + * @param editingContext + * the (non-{@code null}) {@link IEditingContext}. + * @param expandedIds + * the list of already expanded treeItems, by their Ids. + * @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) an + * {@link org.eclipse.syson.sysml.ConstraintUsage}. + */ + public List getConstraintReferenceSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List expandedIds) { + return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getConstraintUsage())); + } + /** diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AssumeConstraintNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AssumeConstraintNodeToolProvider.java new file mode 100644 index 000000000..d0f6de1cd --- /dev/null +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/AssumeConstraintNodeToolProvider.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.diagram.common.view.tools; + +import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; +import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; +import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; +import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; +import org.eclipse.sirius.components.view.builder.providers.INodeToolProvider; +import org.eclipse.sirius.components.view.diagram.DialogDescription; +import org.eclipse.sirius.components.view.diagram.NodeTool; +import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; +import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; +import org.eclipse.syson.model.services.aql.ModelMutationAQLService; +import org.eclipse.syson.sysml.RequirementConstraintKind; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.util.AQLConstants; +import org.eclipse.syson.util.ServiceMethod; +import org.eclipse.syson.util.SysMLMetamodelHelper; + +/** + * Used to create an Assume {@link org.eclipse.syson.sysml.ConstraintUsage} in a {@link org.eclipse.syson.sysml.RequirementUsage} or a {@link org.eclipse.syson.sysml.RequirementDefinition}. + * + * @author gcoutable + */ +public class AssumeConstraintNodeToolProvider implements INodeToolProvider { + + private final DiagramBuilders diagramBuilderHelper = new DiagramBuilders(); + + private final ViewBuilders viewBuilderHelper = new ViewBuilders(); + + @Override + public NodeTool create(IViewDiagramElementFinder cache) { + var builder = this.diagramBuilderHelper.newNodeTool(); + + var updateExposedElements = this.viewBuilderHelper.newChangeContext() + .expression(ServiceMethod.of4(DiagramMutationAQLService::expose).aqlSelf(IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT, Node.SELECTED_NODE, + ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); + + // We expose both the reference constraint and owned constraint because the tool `show content as tree` should display the owned constraint. + // However, if the reference constraint and the owned constraint are different, it means the owned constraint is subsetted by reference, and thus we hide the owned constraint graphical node + // thanks to DiagramMutationExposeService#hideNodeIfHasReferenceSubset + var exposeReferenceConstraint = this.viewBuilderHelper.newChangeContext() + .expression(AQLConstants.AQL_SELF + "." + SysmlPackage.eINSTANCE.getRequirementConstraintMembership_ReferencedConstraint().getName()) + .children(updateExposedElements.build()); + + var exposeOwnedConstraint = this.viewBuilderHelper.newChangeContext() + .expression(AQLConstants.AQL_SELF + "." + SysmlPackage.eINSTANCE.getRequirementConstraintMembership_OwnedConstraint().getName()) + .children(updateExposedElements.build()); + + var body = this.viewBuilderHelper.newChangeContext() + .expression(ServiceMethod.of2(ModelMutationAQLService::createConstraint).aqlSelf("selectedObject", "assumptionConstraint")) + .children(exposeOwnedConstraint.build(), exposeReferenceConstraint.build()); + + String requirementConstraintKindType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getRequirementConstraintKind()); + var letRequirementConstraintLiteral = this.viewBuilderHelper.newLet() + .variableName("assumptionConstraint") + .valueExpression(AQLConstants.AQL + requirementConstraintKindType + ".getEEnumLiteral('" + RequirementConstraintKind.ASSUMPTION.getLiteral() + "').instance") + .children(body.build()); + + return builder + .name(this.getToolName()) + .iconURLsExpression("/icons/full/obj16/ConstraintUsage.svg") + .body(letRequirementConstraintLiteral.build()) + .dialogDescription(this.getDialogDescription()) + .build(); + } + + private String getToolName() { + return "New Assume constraint"; + } + + private DialogDescription getDialogDescription() { + String constraintUsageType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getConstraintUsage()); + + var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() + .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + constraintUsageType + ")") + .elementsExpression(ServiceMethod.of0(ViewToolService::getConstraintReferenceSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) + .childrenExpression(ServiceMethod.of2(ViewToolService::getConstraintReferenceSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) + .build(); + + return this.diagramBuilderHelper.newSelectionDialogDescription() + .selectionDialogTreeDescription(selectionDialogTree) + .defaultTitleExpression(this.getToolName()) + .noSelectionTitleExpression(this.getToolName()) + .withSelectionTitleExpression(this.getToolName()) + .descriptionExpression("Create an Assume Constraint") + .noSelectionActionLabelExpression("Create a New Assume Constraint") + .noSelectionActionDescriptionExpression("Create a New Assume Constraint without referencing an existing Constraint") + .withSelectionActionLabelExpression("Select an existing Constraint to assume") + .withSelectionActionDescriptionExpression("Create a New Assume Constraint referencing the selected Constraint") + .noSelectionActionStatusMessageExpression("It will create a New Assume Constraint without referencing an existing Constraint") + .selectionRequiredWithoutSelectionStatusMessageExpression("Select one Constraint to assume") + .selectionRequiredWithSelectionStatusMessageExpression(AQLConstants.AQL + "'It will create a new Constraint referencing ' + selectedObjects->first().name") + .optional(true) + .build(); + } +} diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FramedConcernNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FramedConcernNodeToolProvider.java index 6ae05a681..9548130b5 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FramedConcernNodeToolProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/FramedConcernNodeToolProvider.java @@ -90,7 +90,7 @@ private DialogDescription getSelectionDialogDescription() { .withSelectionActionLabelExpression("Select an existing Concern to frame") .withSelectionActionDescriptionExpression("Create a New Framed Concern referencing the selected Concern") .noSelectionActionStatusMessageExpression("It will create a New Framed Concern without referencing an existing Concern") - .selectionRequiredWithoutSelectionStatusMessageExpression("Select on Concern to frame") + .selectionRequiredWithoutSelectionStatusMessageExpression("Select one Concern to frame") .selectionRequiredWithSelectionStatusMessageExpression(AQLConstants.AQL + "'It will create a new Concern referencing ' + selectedObjects->first().name") .optional(true) .build(); diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/RequireConstraintNodeToolProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/RequireConstraintNodeToolProvider.java new file mode 100644 index 000000000..fd6447423 --- /dev/null +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/tools/RequireConstraintNodeToolProvider.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2026 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.syson.diagram.common.view.tools; + +import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.trees.renderer.TreeRenderer; +import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; +import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders; +import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders; +import org.eclipse.sirius.components.view.builder.providers.INodeToolProvider; +import org.eclipse.sirius.components.view.diagram.DialogDescription; +import org.eclipse.sirius.components.view.diagram.NodeTool; +import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter; +import org.eclipse.syson.diagram.common.view.services.ViewToolService; +import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService; +import org.eclipse.syson.model.services.aql.ModelMutationAQLService; +import org.eclipse.syson.sysml.RequirementConstraintKind; +import org.eclipse.syson.sysml.SysmlPackage; +import org.eclipse.syson.util.AQLConstants; +import org.eclipse.syson.util.ServiceMethod; +import org.eclipse.syson.util.SysMLMetamodelHelper; + +/** + * Used to create a Require {@link org.eclipse.syson.sysml.ConstraintUsage} in a {@link org.eclipse.syson.sysml.RequirementUsage} or a {@link org.eclipse.syson.sysml.RequirementDefinition}. + * + * @author gcoutable + */ +public class RequireConstraintNodeToolProvider implements INodeToolProvider { + + private final DiagramBuilders diagramBuilderHelper = new DiagramBuilders(); + + private final ViewBuilders viewBuilderHelper = new ViewBuilders(); + + @Override + public NodeTool create(IViewDiagramElementFinder cache) { + var builder = this.diagramBuilderHelper.newNodeTool(); + + var updateExposedElements = this.viewBuilderHelper.newChangeContext() + .expression(ServiceMethod.of4(DiagramMutationAQLService::expose).aqlSelf(IEditingContext.EDITING_CONTEXT, DiagramContext.DIAGRAM_CONTEXT, Node.SELECTED_NODE, + ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE)); + + // We expose both the reference constraint and owned constraint because the tool `show content as tree` should display the owned constraint. + // However, if the reference constraint and the owned constraint are different, it means the owned constraint is subsetted by reference, and thus we hide the owned constraint graphical node + // thanks to DiagramMutationExposeService#hideNodeIfHasReferenceSubset + var exposeReferenceConstraint = this.viewBuilderHelper.newChangeContext() + .expression(AQLConstants.AQL_SELF + "." + SysmlPackage.eINSTANCE.getRequirementConstraintMembership_ReferencedConstraint().getName()) + .children(updateExposedElements.build()); + + var exposeOwnedConstraint = this.viewBuilderHelper.newChangeContext() + .expression(AQLConstants.AQL_SELF + "." + SysmlPackage.eINSTANCE.getRequirementConstraintMembership_OwnedConstraint().getName()) + .children(updateExposedElements.build()); + + var body = this.viewBuilderHelper.newChangeContext() + .expression(ServiceMethod.of2(ModelMutationAQLService::createConstraint).aqlSelf("selectedObject", "requirementConstraint")) + .children(exposeOwnedConstraint.build(), exposeReferenceConstraint.build()); + + String requirementConstraintKindType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getRequirementConstraintKind()); + var letRequirementConstraintLiteral = this.viewBuilderHelper.newLet() + .variableName("requirementConstraint") + .valueExpression(AQLConstants.AQL + requirementConstraintKindType + ".getEEnumLiteral('" + RequirementConstraintKind.REQUIREMENT.getLiteral() + "').instance") + .children(body.build()); + + return builder + .name(this.getToolName()) + .iconURLsExpression("/icons/full/obj16/ConstraintUsage.svg") + .body(letRequirementConstraintLiteral.build()) + .dialogDescription(this.getDialogDescription()) + .build(); + } + + private String getToolName() { + return "New Require constraint"; + } + + private DialogDescription getDialogDescription() { + String constraintUsageType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getConstraintUsage()); + + var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription() + .isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + constraintUsageType + ")") + .elementsExpression(ServiceMethod.of0(ViewToolService::getConstraintReferenceSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT)) + .childrenExpression(ServiceMethod.of2(ViewToolService::getConstraintReferenceSelectionDialogChildren).aqlSelf(IEditingContext.EDITING_CONTEXT, TreeRenderer.EXPANDED)) + .build(); + + return this.diagramBuilderHelper.newSelectionDialogDescription() + .selectionDialogTreeDescription(selectionDialogTree) + .defaultTitleExpression(this.getToolName()) + .noSelectionTitleExpression(this.getToolName()) + .withSelectionTitleExpression(this.getToolName()) + .descriptionExpression("Create a Require Constraint") + .noSelectionActionLabelExpression("Create a New Require Constraint") + .noSelectionActionDescriptionExpression("Create a New Require Constraint without referencing an existing Constraint") + .withSelectionActionLabelExpression("Select an existing Constraint to require") + .withSelectionActionDescriptionExpression("Create a New Require Constraint referencing the selected Constraint") + .noSelectionActionStatusMessageExpression("It will create a New Require Constraint without referencing an existing Constraint") + .selectionRequiredWithoutSelectionStatusMessageExpression("Select one Constraint to require") + .selectionRequiredWithSelectionStatusMessageExpression(AQLConstants.AQL + "'It will create a new Constraint referencing ' + selectedObjects->first().name") + .optional(true) + .build(); + } +} diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDescriptionNameGenerator.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDescriptionNameGenerator.java index 8ad77a1df..26e13f7dc 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDescriptionNameGenerator.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDescriptionNameGenerator.java @@ -12,8 +12,6 @@ *******************************************************************************/ package org.eclipse.syson.standard.diagrams.view; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.util.DescriptionNameGenerator; /** @@ -32,17 +30,4 @@ public class SDVDescriptionNameGenerator extends DescriptionNameGenerator { public SDVDescriptionNameGenerator() { super(PREFIX); } - - @Override - public String getCreationToolName(EReference eReference) { - String name = super.getCreationToolName(eReference); - if (SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint().equals(eReference) - || SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint().equals(eReference)) { - name = "New Assume constraint"; - } else if (SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint().equals(eReference) - || SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint().equals(eReference)) { - name = "New Require constraint"; - } - return name; - } } diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionProvider.java index 00e3626df..6f6691229 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/SDVDiagramDescriptionProvider.java @@ -47,6 +47,8 @@ import org.eclipse.syson.diagram.common.view.nodes.ActionFlowCompartmentNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.AddYourFirstElement; import org.eclipse.syson.diagram.common.view.nodes.AnnotatingNodeDescriptionProvider; +import org.eclipse.syson.diagram.common.view.nodes.AssumeConstraintCompartmentItemNodeDescription; +import org.eclipse.syson.diagram.common.view.nodes.AssumeConstraintCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.CompartmentItemNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.DecisionActionNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.DoneActionNodeDescriptionProvider; @@ -59,6 +61,8 @@ import org.eclipse.syson.diagram.common.view.nodes.InterconnectionCompartmentNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.JoinActionNodeDescriptionProvider; import org.eclipse.syson.diagram.common.view.nodes.MergeActionNodeDescriptionProvider; +import org.eclipse.syson.diagram.common.view.nodes.RequireConstraintCompartmentItemNodeDescription; +import org.eclipse.syson.diagram.common.view.nodes.RequireConstraintCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.SatisfyRequirementCompartmentItemNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.SatisfyRequirementCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider; @@ -212,8 +216,8 @@ public class SDVDiagramDescriptionProvider implements IRepresentationDescription Map.entry(SysmlPackage.eINSTANCE.getAttributeUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedReference())), Map.entry(SysmlPackage.eINSTANCE.getCaseDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation())), Map.entry(SysmlPackage.eINSTANCE.getCaseUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), - Map.entry(SysmlPackage.eINSTANCE.getConcernDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint())), - Map.entry(SysmlPackage.eINSTANCE.getConcernUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), + Map.entry(SysmlPackage.eINSTANCE.getConcernDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement())), + Map.entry(SysmlPackage.eINSTANCE.getConcernUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), Map.entry(SysmlPackage.eINSTANCE.getConnectionDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart())), Map.entry(SysmlPackage.eINSTANCE.getConstraintDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedConstraint())), Map.entry(SysmlPackage.eINSTANCE.getConstraintUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedConstraint(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), @@ -231,8 +235,8 @@ public class SDVDiagramDescriptionProvider implements IRepresentationDescription Map.entry(SysmlPackage.eINSTANCE.getPerformActionUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), SysmlPackage.eINSTANCE.getUsage_NestedAction())), Map.entry(SysmlPackage.eINSTANCE.getPortDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort(), SysmlPackage.eINSTANCE.getDefinition_OwnedReference(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem())), Map.entry(SysmlPackage.eINSTANCE.getPortUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedReference(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), SysmlPackage.eINSTANCE.getUsage_NestedItem())), - Map.entry(SysmlPackage.eINSTANCE.getRequirementDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter(), SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint())), - Map.entry(SysmlPackage.eINSTANCE.getRequirementUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), + Map.entry(SysmlPackage.eINSTANCE.getRequirementDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter(), SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement())), + Map.entry(SysmlPackage.eINSTANCE.getRequirementUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), Map.entry(SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), Map.entry(SysmlPackage.eINSTANCE.getStateDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAction(), SysmlPackage.eINSTANCE.getDefinition_OwnedState())), Map.entry(SysmlPackage.eINSTANCE.getStateUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAction(), SysmlPackage.eINSTANCE.getUsage_NestedState())), @@ -381,6 +385,8 @@ public RepresentationDescription create(IColorProvider colorProvider) { this.linkInterconnectionCompartment(cache); this.linkSatisfyRequirementsCompartment(cache); this.linkFramedConcernCompartment(cache); + this.linkRequireConstraintCompartment(cache); + this.linkAssumeConstraintCompartment(cache); var palette = this.createDiagramPalette(cache); diagramDescription.setPalette(palette); @@ -581,6 +587,14 @@ private List> createAllCompartmentNodeDesc // RequirementUsage, RequirementDefinition compartmentNodeDescriptionProviders.addAll(this.createFramedConcernCompartments(colorProvider)); + // Compartments "require constraints" (Constraint contained by RequirementConstraintMembership with RequirementConstraintKind#REQUIREMENT) is defined for: + // RequirementUsage, RequirementDefinition + compartmentNodeDescriptionProviders.addAll(this.createRequireConstraintCompartments(colorProvider)); + + // Compartments "assume constraints" (Constraint contained by RequirementConstraintMembership with RequirementConstraintKind#ASSUMPTION) is defined for: + // RequirementUsage, RequirementDefinition + compartmentNodeDescriptionProviders.addAll(this.createAssumeConstraintCompartments(colorProvider)); + compartmentNodeDescriptionProviders.addAll(this.createCompartmentsForListItems(colorProvider)); return compartmentNodeDescriptionProviders; @@ -723,6 +737,50 @@ private List> createFramedConcernCompartme return compartmentNodeDescriptionProviders; } + private List> createRequireConstraintCompartments(IColorProvider colorProvider) { + List> compartmentNodeDescriptionProviders = new ArrayList<>(); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new RequireConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + return compartmentNodeDescriptionProviders; + } + + private List> createAssumeConstraintCompartments(IColorProvider colorProvider) { + List> compartmentNodeDescriptionProviders = new ArrayList<>(); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentNodeDescription(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new AssumeConstraintCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), + colorProvider, this.getDescriptionNameGenerator())); + return compartmentNodeDescriptionProviders; + } + private List> createCompartmentsForConnectionEnd(IColorProvider colorProvider) { final List> compartmentNodeDescriptionProviders = new ArrayList<>(); @@ -1412,6 +1470,62 @@ private void linkFramedConcernCompartment(IViewDiagramElementFinder cache) { }); } + private void linkRequireConstraintCompartment(IViewDiagramElementFinder cache) { + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getRequirementDefinition())) + .ifPresent(requirementDefinitionNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementDefinitionNodeDescription.getReusedChildNodeDescriptions()::add); + }); + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getRequirementUsage())) + .ifPresent(requirementUsageNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementUsageNodeDescription.getReusedChildNodeDescriptions()::add); + }); + + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getConcernDefinition())) + .ifPresent(requirementDefinitionNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementDefinitionNodeDescription.getReusedChildNodeDescriptions()::add); + }); + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getConcernUsage())) + .ifPresent(requirementUsageNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementUsageNodeDescription.getReusedChildNodeDescriptions()::add); + }); + } + + private void linkAssumeConstraintCompartment(IViewDiagramElementFinder cache) { + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getRequirementDefinition())) + .ifPresent(requirementDefinitionNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementDefinitionNodeDescription.getReusedChildNodeDescriptions()::add); + }); + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getRequirementUsage())) + .ifPresent(requirementUsageNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementUsageNodeDescription.getReusedChildNodeDescriptions()::add); + }); + + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getConcernDefinition())) + .ifPresent(requirementDefinitionNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementDefinitionNodeDescription.getReusedChildNodeDescriptions()::add); + }); + cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(SysmlPackage.eINSTANCE.getConcernUsage())) + .ifPresent(requirementUsageNodeDescription -> { + cache.getNodeDescription(this.descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME) + .ifPresent(requirementUsageNodeDescription.getReusedChildNodeDescriptions()::add); + }); + } + private void addCompartmentNodeDescriptionInNodeDescription(IViewDiagramElementFinder cache, NodeDescription compartmentNodeDescription, EClass eClass) { cache.getNodeDescription(this.getDescriptionNameGenerator().getNodeName(eClass)) .ifPresent(nodeDescription -> { diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/FakeNodeDescriptionProvider.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/FakeNodeDescriptionProvider.java index 9f9125a70..f668c795a 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/FakeNodeDescriptionProvider.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/FakeNodeDescriptionProvider.java @@ -19,8 +19,10 @@ import org.eclipse.sirius.components.view.builder.providers.IColorProvider; import org.eclipse.sirius.components.view.diagram.NodeDescription; import org.eclipse.syson.diagram.common.view.nodes.AbstractFakeNodeDescriptionProvider; +import org.eclipse.syson.diagram.common.view.nodes.AssumeConstraintCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.FramedConcernCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.InterconnectionCompartmentNodeDescriptionProvider; +import org.eclipse.syson.diagram.common.view.nodes.RequireConstraintCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.SatisfyRequirementCompartmentNodeDescription; import org.eclipse.syson.diagram.common.view.nodes.StatesCompartmentNodeDescriptionProvider; import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; @@ -60,18 +62,6 @@ protected List getChildrenDescription(IViewDiagramElementFinder private void addReusableCompartments(IViewDiagramElementFinder cache, IDescriptionNameGenerator descriptionNameGenerator, List childrenNodes) { // don't forget to add custom compartments - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_SubjectParameter())) - .ifPresent(childrenNodes::add); - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter())) - .ifPresent(childrenNodes::add); - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter())) - .ifPresent(childrenNodes::add); - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_SubjectParameter())) - .ifPresent(childrenNodes::add); - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_ActorParameter())) - .ifPresent(childrenNodes::add); - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter())) - .ifPresent(childrenNodes::add); cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_SubjectParameter())) .ifPresent(childrenNodes::add); cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter())) @@ -142,9 +132,33 @@ private void addReusableCompartments(IViewDiagramElementFinder cache, IDescripti .ifPresent(childrenNodes::add); this.addCustomCompartmentsForRequirements(cache, descriptionNameGenerator, childrenNodes); + this.addCustomCompartmentsForConcerns(cache, descriptionNameGenerator, childrenNodes); this.addCustomCompartmentsForParts(cache, descriptionNameGenerator, childrenNodes); } + private void addCustomCompartmentsForConcerns(IViewDiagramElementFinder cache, IDescriptionNameGenerator descriptionNameGenerator, List childrenNodes) { + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_SubjectParameter())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_SubjectParameter())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_ActorParameter())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + } + private void addCustomCompartmentsForRequirements(IViewDiagramElementFinder cache, IDescriptionNameGenerator descriptionNameGenerator, List childrenNodes) { cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_SubjectParameter())) .ifPresent(childrenNodes::add); @@ -160,8 +174,16 @@ private void addCustomCompartmentsForRequirements(IViewDiagramElementFinder cach .ifPresent(childrenNodes::add); cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_FramedConcern()) + FramedConcernCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); - cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementDefinition_FramedConcern()) + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_FramedConcern()) + FramedConcernCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint()) + + RequireConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); + cache.getNodeDescription(descriptionNameGenerator.getCompartmentName(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint()) + + AssumeConstraintCompartmentNodeDescription.COMPARTMENT_NAME).ifPresent(childrenNodes::add); } private void addCustomCompartmentsForParts(IViewDiagramElementFinder cache, IDescriptionNameGenerator descriptionNameGenerator, List childrenNodes) { diff --git a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SDVNodeToolSectionSwitch.java b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SDVNodeToolSectionSwitch.java index 7a05bc4b1..b8f571e4e 100644 --- a/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SDVNodeToolSectionSwitch.java +++ b/backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/services/SDVNodeToolSectionSwitch.java @@ -30,6 +30,7 @@ import org.eclipse.syson.diagram.common.view.tools.ActionFlowCompartmentNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.ActorCompartmentNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.AssignmentActionNodeToolProvider; +import org.eclipse.syson.diagram.common.view.tools.AssumeConstraintNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.CompartmentNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.ConnectionDefinitionEndCompartmentNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.DecisionActionNodeToolProvider; @@ -51,6 +52,7 @@ import org.eclipse.syson.diagram.common.view.tools.PartUsageInterfaceNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.PartUsageSubsettingNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.PerformActionNodeToolProvider; +import org.eclipse.syson.diagram.common.view.tools.RequireConstraintNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.SatisfyNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.SatisfyRequirementNodeToolProvider; import org.eclipse.syson.diagram.common.view.tools.SetAsCompositeToolProvider; @@ -298,6 +300,10 @@ public List caseConcernDefinition(ConcernDefinition object) { this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewSubjectNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewActorNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewStakeholderNodeTool()); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new RequireConstraintNodeToolProvider().create(this.cache)); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new AssumeConstraintNodeToolProvider().create(this.cache)); this.toolDescriptionService.addNodeTool(sections, ToolConstants.VIEW_AS, new ViewNodeAsToolProvider(AQLUtils.aqlString(StandardDiagramsConstants.GV_QN), StandardDiagramsConstants.GV).create(this.cache)); @@ -325,6 +331,10 @@ public List caseConcernUsage(ConcernUsage object) { this.toolDescriptionService.createNodeTool(this.getNodeDescription(SysmlPackage.eINSTANCE.getPartUsage()), SysmlPackage.eINSTANCE.getPartUsage())); this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, this.toolDescriptionService.createNodeTool(this.getNodeDescription(SysmlPackage.eINSTANCE.getRequirementUsage()), SysmlPackage.eINSTANCE.getRequirementUsage())); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new RequireConstraintNodeToolProvider().create(this.cache)); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new AssumeConstraintNodeToolProvider().create(this.cache)); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewSubjectNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewActorNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewStakeholderNodeTool()); @@ -707,6 +717,10 @@ public List caseRequirementUsage(RequirementUsage object) { this.toolDescriptionService.createNodeTool(this.getNodeDescription(SysmlPackage.eINSTANCE.getRequirementUsage()), SysmlPackage.eINSTANCE.getRequirementUsage())); this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, new FramedConcernNodeToolProvider().create(this.cache)); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new RequireConstraintNodeToolProvider().create(this.cache)); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new AssumeConstraintNodeToolProvider().create(this.cache)); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewSubjectNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewActorNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewStakeholderNodeTool()); @@ -729,6 +743,10 @@ public List caseRequirementDefinition(RequirementDefinition obj var sections = this.toolDescriptionService.createDefaultNodeToolSections(); this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, new FramedConcernNodeToolProvider().create(this.cache)); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new RequireConstraintNodeToolProvider().create(this.cache)); + this.toolDescriptionService.addNodeTool(sections, ToolConstants.REQUIREMENTS, + new AssumeConstraintNodeToolProvider().create(this.cache)); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewSubjectNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewActorNodeTool()); this.toolDescriptionService.addNodeTool(sections, ToolConstants.STRUCTURE, this.createNewStakeholderNodeTool()); diff --git a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc index ccea80739..50a816445 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc @@ -28,6 +28,7 @@ image::release-notes-framed-concern-tool.png[Tool to create a _frame_ concern us image::release-notes-frames-compartment.png[frames compartment displaying concern usages of a requirement, width=40%,height=40%] ** Leverage the selection dialog to improve the graphical node tool creating a _frame_ `ConcernUsage` from `RequirementUsage` and `RequirementDefinition` graphical nodes. +** Leverage the selection dialog to improve the graphical node tools creating a _require_ `ConstraintUsage`, or an _assume_ `ConstraintUsage`, from `RequirementUsage` and `RequirementDefinition` graphical nodes. ** Add the support for creating _timeslices/snapshots_ from the different kind of `OccurrenceDefiniton` graphical nodes. It leverages the selection dialog to either create an _occurrence timeslice/snapshot_, or the _usage timeslice/snapshot_ matching the `OccurrenceDefinition` on which the tool is applied.