diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 8745d2528..2b702048f 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -56,6 +56,7 @@ This removes Rollup warnings about missing global names for externalized peer de - 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. +- https://github.com/eclipse-syson/syson/issues/2387[#2387] [diagrams] Add support of objective requirement inheritance in _objective_ compartments of `CaseUsage` and `CaseDefinition` 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 2482e9370..74e99e990 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 @@ -23,6 +23,7 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.stream.Stream; import org.eclipse.emf.ecore.EClass; import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput; @@ -52,6 +53,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; @@ -916,6 +920,32 @@ public void checkConcernUsageStakeholdersInheritanceWithReferenceSubsetting() { .run(); } + private static Stream objectiveInheritanceParameters() { + return Stream.of( + Arguments.of("New Case Definition", "New Subclassification", SysmlPackage.eINSTANCE.getCaseDefinition(), GeneralViewWithTopNodesTestProjectData.GraphicalIds.CASE_DEFINITION_ID), + Arguments.of("New Case", "New Redefinition", SysmlPackage.eINSTANCE.getCaseUsage(), GeneralViewWithTopNodesTestProjectData.GraphicalIds.CASE_USAGE_ID), + Arguments.of("New Case", "New Subsetting", SysmlPackage.eINSTANCE.getCaseUsage(), GeneralViewWithTopNodesTestProjectData.GraphicalIds.CASE_USAGE_ID), + Arguments.of("New Case", "New Reference Subsetting", SysmlPackage.eINSTANCE.getCaseUsage(), GeneralViewWithTopNodesTestProjectData.GraphicalIds.CASE_USAGE_ID) + ); + } + + @ParameterizedTest + @MethodSource("objectiveInheritanceParameters") + public void checkObjectiveInheritanceWithSpecialization(String subclassifier, String specialization, EClass eClass, String baseElementNodeId) { + new ElementSpecializationInheritanceTestRunner() + .baseElementToInheritFromEClass(eClass) + .baseElementToInheritFromNodeId(baseElementNodeId) + .elementToInheritCreationToolName("New Objective") + .withEdgeExpected() + .withSelectedElementId("") + .elementToInheritExpectedListItemLabelText("requirement1") + .compartmentName("objective") + .elementThatInheritFromBaseElementCreationToolName(subclassifier) + .elementThatInheritFromBaseElementEClass(eClass) + .specializationToolName(specialization) + .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 8e60546a2..9d9d6b5f6 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,6 +75,11 @@ 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"; + + public static final String CASE_DEFINITION_ID = "92a34fc4-058e-34c2-b4fa-829b5ef11090"; + + public static final String CASE_USAGE_ID = "0e713cc2-1872-31ec-ad87-c9d85b692458"; + } /** 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 08fa5b582..09aa2b1eb 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 @@ -26,12 +26,14 @@ import org.eclipse.syson.sysml.Definition; import org.eclipse.syson.sysml.ExhibitStateUsage; import org.eclipse.syson.sysml.Feature; +import org.eclipse.syson.sysml.ObjectiveMembership; import org.eclipse.syson.sysml.OwningMembership; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.PerformActionUsage; import org.eclipse.syson.sysml.ReferenceUsage; import org.eclipse.syson.sysml.RequirementConstraintKind; import org.eclipse.syson.sysml.RequirementConstraintMembership; +import org.eclipse.syson.sysml.RequirementUsage; import org.eclipse.syson.sysml.SatisfyRequirementUsage; import org.eclipse.syson.sysml.StakeholderMembership; import org.eclipse.syson.sysml.StateUsage; @@ -142,19 +144,17 @@ public Boolean caseFeature(Feature object) { */ @Override public Boolean casePartUsage(PartUsage object) { - boolean result; + final boolean result; if (this.shouldConsiderParameter(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(); + result = object.getOwningMembership() instanceof StakeholderMembership; + } else if (this.isActorReference()) { + // We are dealing with an Actor // so the part usage is an actor if and only if, it is contained by a ActorMembership - result = membership instanceof ActorMembership; + result = object.getOwningMembership() instanceof ActorMembership; } else { EClassifier eType = this.eReference.getEType(); EClass eClass = object.eClass(); @@ -211,6 +211,26 @@ public Boolean caseReferenceUsage(ReferenceUsage object) { return eType.equals(eClass) || (eType instanceof EClass eTypeEClass && eTypeEClass.isSuperTypeOf(eClass)); } + @Override + public Boolean caseRequirementUsage(RequirementUsage object) { + final boolean result; + if (this.isObjectiveReference()) { + // We are dealing with an objective + // so the part usage is an objective if and only if, it is contained by an ObjectiveMembership + result = object.getOwningMembership() instanceof ObjectiveMembership; + } else { + EClassifier eType = this.eReference.getEType(); + EClass eClass = object.eClass(); + return eType.equals(eClass) || (eType instanceof EClass eTypeEClass && eTypeEClass.isSuperTypeOf(eClass)); + } + return result; + } + + private boolean isObjectiveReference() { + return this.eReference.equals(SysmlPackage.eINSTANCE.getCaseDefinition_ObjectiveRequirement()) || + this.eReference.equals(SysmlPackage.eINSTANCE.getCaseUsage_ObjectiveRequirement()); + } + /** * Filters inherited satisfy requirement usages against the targeted compartment. * 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 62adc58cd..01f9409da 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 @@ -848,18 +848,15 @@ private List> createCompartmentsForObjecti final List> compartmentNodeDescriptionProviders = new ArrayList<>(); compartmentNodeDescriptionProviders.add(new CaseDefinitionObjectiveRequirementCompartmentNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); - compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getCaseDefinition(), - SysmlPackage.eINSTANCE.getCaseDefinition_ObjectiveRequirement(), colorProvider, this.getDescriptionNameGenerator())); - compartmentNodeDescriptionProviders - .add(new ObjectiveDocumentationCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getCaseDefinition(), SysmlPackage.eINSTANCE.getCaseDefinition_ObjectiveRequirement(), - colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getCaseDefinition(), SysmlPackage.eINSTANCE.getCaseDefinition_ObjectiveRequirement(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new ObjectiveDocumentationCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getCaseDefinition(), SysmlPackage.eINSTANCE.getCaseDefinition_ObjectiveRequirement(), colorProvider, this.getDescriptionNameGenerator())); compartmentNodeDescriptionProviders.add(new CaseUsageObjectiveRequirementCompartmentNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); - compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getCaseUsage(), SysmlPackage.eINSTANCE.getCaseUsage_ObjectiveRequirement(), - colorProvider, this.getDescriptionNameGenerator())); - compartmentNodeDescriptionProviders - .add(new ObjectiveDocumentationCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getCaseUsage(), SysmlPackage.eINSTANCE.getCaseUsage_ObjectiveRequirement(), - colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getCaseUsage(), SysmlPackage.eINSTANCE.getCaseUsage_ObjectiveRequirement(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new ObjectiveDocumentationCompartmentItemNodeDescription(SysmlPackage.eINSTANCE.getCaseUsage(), SysmlPackage.eINSTANCE.getCaseUsage_ObjectiveRequirement(), colorProvider, this.getDescriptionNameGenerator())); + + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getCaseDefinition(), SysmlPackage.eINSTANCE.getCaseDefinition_ObjectiveRequirement(), colorProvider, this.getDescriptionNameGenerator())); + compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(SysmlPackage.eINSTANCE.getCaseUsage(), SysmlPackage.eINSTANCE.getCaseUsage_ObjectiveRequirement(), 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 d36e0efe7..ae071ca63 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,11 +10,10 @@ ** 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 stakeholder inheritance in _stakeholders_ compartments of `RequirementUsage` and `RequirementDefinition` graphical nodes. - ** Add support of `SatisfyRequirementUsage` inheritance in _satisfy requirements_ compartment of `PartUsage` and `PartDefinition` graphical nodes. +** Add support of objective requirement inheritance in _objective_ compartments of `CaseUsage` and `CaseDefinition` graphical nodes. * In textual import/export: