From f7be3d45f0b8d35b7ae910b428d573c886c29581 Mon Sep 17 00:00:00 2001 From: Jerome Gout Date: Tue, 4 Aug 2026 14:42:31 +0200 Subject: [PATCH] [2382] Add support of stakeholder inheritance in stakeholders Add support of stakeholder inheritance in _stakeholders_ compartments of `RequirementUsage` and `RequirementDefinition` graphical nodes. Bug: https://github.com/eclipse-syson/syson/issues/2382 Signed-off-by: Jerome Gout --- CHANGELOG.adoc | 1 + .../GVCompartmentItemInheritanceTests.java | 126 ++++++++++++++++++ ...eneralViewWithTopNodesTestProjectData.java | 1 - .../InheritedCompartmentItemFilterSwitch.java | 33 ++++- .../view/SDVDiagramDescriptionProvider.java | 10 ++ .../pages/release-notes/2026.9.0.adoc | 3 +- 6 files changed, 167 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 1d78f0cae..4f090375e 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -43,6 +43,7 @@ In any case, it is strongly recommended to back up your data before proceeding w - https://github.com/eclipse-syson/syson/issues/2375[#2375] [diagrams] Add support of require constraints inheritance in _require constraints_ compartments of `RequirementUsage`, `RequirementDefinition` and subtypes graphical nodes. - https://github.com/eclipse-syson/syson/issues/2378[#2378] [diagrams] Add support of framed concern inheritance in frames compartment of RequirementUsage and RequirementDefinition. - https://github.com/eclipse-syson/syson/issues/2380[#2380] [diagrams] Add support of `SatisfyRequirementUsage` inheritance in _satisfy requirements_ compartment of `PartUsage` and `PartDefinition` graphical nodes. +- https://github.com/eclipse-syson/syson/issues/2382[#2382] [diagrams] Add support of stakeholder inheritance in _stakeholders_ compartments of `RequirementUsage` and `RequirementDefinition` graphical nodes. == v2026.7.0 diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVCompartmentItemInheritanceTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVCompartmentItemInheritanceTests.java index e61009046..2482e9370 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVCompartmentItemInheritanceTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVCompartmentItemInheritanceTests.java @@ -790,6 +790,132 @@ public void checkRequirementUsageSatisfyRequirementsInheritanceWithReferenceSubs .run(); } + @DisplayName("GIVEN a base RequirementDefinition with a stakeholder, WHEN a RequirementDefinition is subclassifying the base RequirementDefinition, THEN the RequirementDefinition stakeholders are inherited from the base RequirementDefinition") + @Test + public void checkRequirementDefinitionStakeholdersInheritanceWithSubclassification() { + var eClass = SysmlPackage.eINSTANCE.getRequirementDefinition(); + new ElementSpecializationInheritanceTestRunner() + .baseElementToInheritFromEClass(eClass) + .baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.REQUIREMENT_DEFINITION_ID) + .elementToInheritCreationToolName("New Stakeholder") + .withEdgeExpected() + .withSelectedElementId("") + .elementToInheritExpectedListItemLabelText("stakeholder1") + .compartmentName("stakeholders") + .elementThatInheritFromBaseElementCreationToolName("New Requirement Definition") + .elementThatInheritFromBaseElementEClass(eClass) + .specializationToolName("New Subclassification") + .run(); + } + + private ElementSpecializationInheritanceTestRunner getRequirementUsageStakeholdersInheritanceTestRunner() { + var eClass = SysmlPackage.eINSTANCE.getRequirementUsage(); + return new ElementSpecializationInheritanceTestRunner() + .baseElementToInheritFromEClass(eClass) + .baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.REQUIREMENT_USAGE_ID) + .elementToInheritCreationToolName("New Stakeholder") + .withEdgeExpected() + .withSelectedElementId("") + .elementToInheritExpectedListItemLabelText("stakeholder1") + .compartmentName("stakeholders") + .elementThatInheritFromBaseElementCreationToolName("New Requirement") + .elementThatInheritFromBaseElementEClass(eClass); + } + + @DisplayName("GIVEN a base RequirementUsage with a stakeholder, WHEN a RequirementUsage is subsetting the base RequirementUsage, THEN the RequirementUsage stakeholders are inherited from the base RequirementUsage") + @Test + public void checkRequirementUsageStakeholdersInheritanceWithSubsetting() { + this.getRequirementUsageStakeholdersInheritanceTestRunner() + .specializationToolName("New Subsetting") + .run(); + } + + @DisplayName("GIVEN a base RequirementUsage with a stakeholder, WHEN a RequirementUsage is subsetting by reference the base RequirementUsage, THEN the RequirementUsage stakeholders are inherited from the base RequirementUsage") + @Test + public void checkRequirementUsageStakeholdersInheritanceWithReferenceSubsetting() { + this.getRequirementUsageStakeholdersInheritanceTestRunner() + .specializationToolName("New Reference Subsetting") + .run(); + } + + private ElementSpecializationInheritanceTestRunner getSatisfyRequirementUsageStakeholdersInheritanceTestRunner() { + var eClass = SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(); + return new ElementSpecializationInheritanceTestRunner() + .baseElementToInheritFromEClass(eClass) + .baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.SATISFY_REQUIREMENT_USAGE_ID) + .elementToInheritCreationToolName("New Stakeholder") + .withEdgeExpected() + .withSelectedElementId("") + .elementToInheritExpectedListItemLabelText("stakeholder1") + .compartmentName("stakeholders") + .elementThatInheritFromBaseElementCreationToolName("New Satisfy Requirement") + .elementThatInheritFromBaseElementEClass(eClass); + } + + @DisplayName("GIVEN a base SatisfyRequirementUsage with a stakeholder, WHEN a SatisfyRequirementUsage is subsetting the base SatisfyRequirementUsage, THEN the SatisfyRequirementUsage stakeholders are inherited from the base SatisfyRequirementUsage") + @Test + public void checkSatisfyRequirementUsageStakeholdersInheritanceWithSubsetting() { + this.getSatisfyRequirementUsageStakeholdersInheritanceTestRunner() + .specializationToolName("New Subsetting") + .run(); + } + + @DisplayName("GIVEN a base SatisfyRequirementUsage with a stakeholder, WHEN a SatisfyRequirementUsage is subsetting by reference the base SatisfyRequirementUsage, THEN the SatisfyRequirementUsage stakeholders are inherited from the base SatisfyRequirementUsage") + @Test + public void checkSatisfyRequirementUsageStakeholdersInheritanceWithReferenceSubsetting() { + this.getSatisfyRequirementUsageStakeholdersInheritanceTestRunner() + .specializationToolName("New Reference Subsetting") + .run(); + } + + @DisplayName("GIVEN a base ConcernDefinition with a stakeholder, WHEN a ConcernDefinition is subclassifying the base ConcernDefinition, THEN the ConcernDefinition assume constraints are inherited from the base ConcernDefinition") + @Test + public void checkConcernDefinitionStakeholdersInheritanceWithSubclassification() { + var eClass = SysmlPackage.eINSTANCE.getConcernDefinition(); + new ElementSpecializationInheritanceTestRunner() + .baseElementToInheritFromEClass(eClass) + .baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.CONCERN_DEFINITION_ID) + .elementToInheritCreationToolName("New Stakeholder") + .withEdgeExpected() + .withSelectedElementId("") + .elementToInheritExpectedListItemLabelText("stakeholder1") + .compartmentName("stakeholders") + .elementThatInheritFromBaseElementCreationToolName("New Concern Definition") + .elementThatInheritFromBaseElementEClass(eClass) + .specializationToolName("New Subclassification") + .run(); + } + + private ElementSpecializationInheritanceTestRunner getConcernUsageStakeholdersInheritanceTestRunner() { + var eClass = SysmlPackage.eINSTANCE.getConcernUsage(); + return new ElementSpecializationInheritanceTestRunner() + .baseElementToInheritFromEClass(eClass) + .baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.CONCERN_USAGE_ID) + .elementToInheritCreationToolName("New Stakeholder") + .withEdgeExpected() + .withSelectedElementId("") + .elementToInheritExpectedListItemLabelText("stakeholder1") + .compartmentName("stakeholders") + .elementThatInheritFromBaseElementCreationToolName("New Concern") + .elementThatInheritFromBaseElementEClass(eClass); + } + + @DisplayName("GIVEN a base ConcernUsage with a stakeholder, WHEN a ConcernUsage is subsetting the base ConcernUsage, THEN the ConcernUsage assume constraints are inherited from the base ConcernUsage") + @Test + public void checkConcernUsageStakeholdersInheritanceWithSubsetting() { + this.getConcernUsageStakeholdersInheritanceTestRunner() + .specializationToolName("New Subsetting") + .run(); + } + + @DisplayName("GIVEN a base ConcernUsage with a stakeholder, WHEN a ConcernUsage is subsetting by reference the base ConcernUsage, THEN the ConcernUsage assume constraints are inherited from the base ConcernUsage") + @Test + public void checkConcernUsageStakeholdersInheritanceWithReferenceSubsetting() { + this.getConcernUsageStakeholdersInheritanceTestRunner() + .specializationToolName("New Reference Subsetting") + .run(); + } + /** * This test runner verifies that creating a specializing relationship create inherited elements. * diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java index 0d2a23d86..8e60546a2 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewWithTopNodesTestProjectData.java @@ -75,7 +75,6 @@ public static class GraphicalIds { public static final String PORT_DEFINITION_ID = "bad8fa43-eb03-35dd-a025-34fd2e71d5a3"; public static final String SATISFY_REQUIREMENT_USAGE_ID = "450a4e50-c67b-3c40-8801-64aa0cd85bd6"; - } /** diff --git a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/InheritedCompartmentItemFilterSwitch.java b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/InheritedCompartmentItemFilterSwitch.java index 653aeae98..08fa5b582 100644 --- a/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/InheritedCompartmentItemFilterSwitch.java +++ b/backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/InheritedCompartmentItemFilterSwitch.java @@ -20,6 +20,7 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.syson.sysml.ActionUsage; +import org.eclipse.syson.sysml.ActorMembership; import org.eclipse.syson.sysml.Behavior; import org.eclipse.syson.sysml.ConstraintUsage; import org.eclipse.syson.sysml.Definition; @@ -32,6 +33,7 @@ import org.eclipse.syson.sysml.RequirementConstraintKind; import org.eclipse.syson.sysml.RequirementConstraintMembership; import org.eclipse.syson.sysml.SatisfyRequirementUsage; +import org.eclipse.syson.sysml.StakeholderMembership; import org.eclipse.syson.sysml.StateUsage; import org.eclipse.syson.sysml.Step; import org.eclipse.syson.sysml.SysmlPackage; @@ -140,12 +142,35 @@ public Boolean caseFeature(Feature object) { */ @Override public Boolean casePartUsage(PartUsage object) { + boolean result; if (this.shouldConsiderParameter(object)) { - return this.isInheritedParameter(object); + result = this.isInheritedParameter(object); + } else if (this.isStakeholderReference()) { + // We are dealing with a stakeholder + var membership = object.getOwningMembership(); + // so the part usage is a stakeholder if and only if, it is contained by a StakeholderMembership + result = membership instanceof StakeholderMembership; + } if (this.isActorReference()) { + // We are dealing with an Actor? + var membership = object.getOwningMembership(); + // so the part usage is an actor if and only if, it is contained by a ActorMembership + result = membership instanceof ActorMembership; + } else { + EClassifier eType = this.eReference.getEType(); + EClass eClass = object.eClass(); + result = eType.equals(eClass) || (eType instanceof EClass eTypeEClass && eTypeEClass.isSuperTypeOf(eClass)); } - EClassifier eType = this.eReference.getEType(); - EClass eClass = object.eClass(); - return eType.equals(eClass) || (eType instanceof EClass eTypeEClass && eTypeEClass.isSuperTypeOf(eClass)); + return result; + } + + private boolean isStakeholderReference() { + return this.eReference.equals(SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter()) + || this.eReference.equals(SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter()); + } + + private boolean isActorReference() { + return this.eReference.equals(SysmlPackage.eINSTANCE.getRequirementUsage_ActorParameter()) + || this.eReference.equals(SysmlPackage.eINSTANCE.getRequirementDefinition_ActorParameter()); } /** 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 bf2c4d105..62adc58cd 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 @@ -934,6 +934,8 @@ private List> createCompartmentsForStakeho SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getRequirementDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getRequirementDefinition(), + SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); // RequirementUsage: stakeholder compartment & items compartmentNodeDescriptionProviders.add(new RequirementUsageStakeholdersCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getRequirementUsage(), @@ -941,24 +943,32 @@ private List> createCompartmentsForStakeho compartmentNodeDescriptionProviders .add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getRequirementUsage(), + SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); // ConcernDefinition: stakeholder compartment & items compartmentNodeDescriptionProviders.add(new RequirementDefinitionStakeholdersCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getConcernDefinition(), SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getConcernDefinition(), + SysmlPackage.eINSTANCE.getRequirementDefinition_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); // ConcernUsage: stakeholder compartment & items compartmentNodeDescriptionProviders.add(new RequirementUsageStakeholdersCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getConcernUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getConcernUsage(), + SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); // SatisfyRequirementUsage: stakeholder compartment & items compartmentNodeDescriptionProviders.add(new RequirementUsageStakeholdersCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getSatisfyRequirementUsage(), + SysmlPackage.eINSTANCE.getRequirementUsage_StakeholderParameter(), colorProvider, this.getDescriptionNameGenerator())); return compartmentNodeDescriptionProviders; } diff --git a/doc/content/modules/user-manual/pages/release-notes/2026.9.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2026.9.0.adoc index 87e3cf070..517f6494d 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2026.9.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2026.9.0.adoc @@ -10,10 +10,9 @@ ** Add support of framed concern inheritance in _frames_ compartments of `RequirementUsage` and `RequirementDefinition` graphical nodes. ** Add support of `ItemUsage` inheritance in _items_ compartments of `PortUsage` and `PortDefinition` graphical nodes. ** Add support of assume constraint inheritance in _assume constraints_ compartments of `RequirementUsage` and `RequirementDefinition` graphical nodes. - ** Add support of require constraints inheritance in _require constraints_ compartments of `RequirementUsage`, `RequirementDefinition` and subtypes graphical nodes. - ** Add support of `SatisfyRequirementUsage` inheritance in _satisfy requirements_ compartment of `PartUsage` and `PartDefinition` graphical nodes. +** Add support of stakeholder inheritance in _stakeholders_ compartments of `RequirementUsage` and `RequirementDefinition` graphical nodes. * In textual import/export: