Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ It has long been unused by Sirius Web itself (since the transition to MUI).
- https://github.com/eclipse-syson/syson/issues/2306[#2306] [diagrams] Fixed an error when trying to rename a constraint displayed as a list item through direct edit.

=== Improvements

- https://github.com/eclipse-syson/syson/issues/2198[#2198] [diagrams] Improve diagram-to-diagram drag and drop to support dropping multiple graphical nodes at once, leveraging Sirius Web's `droppedNodes` and `droppedElements` variables.
- https://github.com/eclipse-syson/syson/issues/2182[#2182] [services] Provide a way for downstream applications to extend _ISysMLMoveElementService_.
- https://github.com/eclipse-syson/syson/issues/2240[#2240] [diagrams] Update the choice of _timeslice_ and _snapshot_ elements that can be created in the selection dialog of tools creating _timeslice_ and _snapshot_ elements.
Expand Down Expand Up @@ -75,6 +76,7 @@ It leverages the selection dialog to either create an _occurrence timeslice/snap
- https://github.com/eclipse-syson/syson/issues/2113[#2113] [diagrams] Handle start/end/merge/decision... graphical nodes on Action Flow View diagram background
- https://github.com/eclipse-syson/syson/issues/2303[#2303] [diagrams] Add support for list item inheritance in _states_ and _exhibit states_ compartments
- https://github.com/eclipse-syson/syson/issues/2239[#2239] [diagrams] Add the support for a frontend tool to rotate `ForkNode` and `JoinNode` graphical nodes
- https://github.com/eclipse-syson/syson/issues/2316[#2316] [diagrams] Add support for list item inheritance in _perform actions_ compartments

== v2026.5.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,55 @@ public void checkStateUsageExhibitStatesInheritanceWithRedefinition() {
.run();
}

@DisplayName("GIVEN a base ActionDefinition with a perform action, WHEN another ActionDefinition is subclassing the base ActionDefinition, THEN the base ActionDefinition perform actions are inherited by the other ActionDefinition")
@Test
public void checkActionDefinitionPerformActionsInheritanceWithSubclassification() {
new ElementSpecializationInheritanceTestRunner()
.baseElementToInheritFromEClass(SysmlPackage.eINSTANCE.getActionDefinition())
.baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.ACTION_DEFINITION_ID)
.elementToInheritCreationToolName("New Perform action")
.withEdgeExpected()
.withSelectedElementId("")
.elementToInheritExpectedListItemLabelText("ref ")
.compartmentName("perform actions")
.elementThatInheritFromBaseElementCreationToolName("New Action Definition")
.elementThatInheritFromBaseElementEClass(SysmlPackage.eINSTANCE.getActionDefinition())
.specializationToolName("New Subclassification")
.run();
}

@DisplayName("GIVEN a StateDefinition with a do action, WHEN a StateUsage is typed by the StateDefinition, THEN the StateDefinition perform actions are inherited by the StateUsage")
@Test
public void checkStateDefinitionPerformActionsInheritanceWithFeatureTyping() {
new ElementSpecializationInheritanceTestRunner()
.baseElementToInheritFromEClass(SysmlPackage.eINSTANCE.getStateDefinition())
.baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.STATE_DEFINITION_ID)
.elementToInheritCreationToolName("New Do Action")
.withSelectedElementId(GeneralViewWithTopNodesTestProjectData.SemanticIds.ACTION_USAGE_ID)
.elementToInheritExpectedListItemLabelText("ref do ::> action")
.compartmentName("perform actions")
.elementThatInheritFromBaseElementCreationToolName("New State")
.elementThatInheritFromBaseElementEClass(SysmlPackage.eINSTANCE.getStateUsage())
.specializationToolName("New Feature Typing")
.run();
}

@DisplayName("GIVEN a StateUsage with an entry action, WHEN a PartUsage is subsetting by reference the StateUsage, THEN the StateUsage perform actions are inherited by the PartUsage")
@Test
public void checkStateUsagePerformActionsInheritanceWithReferenceSubsetting() {
new ElementSpecializationInheritanceTestRunner()
.baseElementToInheritFromEClass(SysmlPackage.eINSTANCE.getStateUsage())
.baseElementToInheritFromNodeId(GeneralViewWithTopNodesTestProjectData.GraphicalIds.STATE_USAGE_ID)
.elementToInheritCreationToolName("New Entry Action")
.withSelectedElementId(GeneralViewWithTopNodesTestProjectData.SemanticIds.ACTION_USAGE_ID)
.elementToInheritExpectedListItemLabelText("ref entry ::> action")
.compartmentName("perform actions")
.elementThatInheritFromBaseElementCreationToolName("New Part")
.elementThatInheritFromBaseElementEClass(SysmlPackage.eINSTANCE.getPartUsage())
.specializationToolName("New Reference Subsetting")
.run();
}

/**
* This test runner verifies that creating a specializing relationship create inherited elements.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.syson.sysml.ActionUsage;
import org.eclipse.syson.sysml.Behavior;
import org.eclipse.syson.sysml.ConstraintUsage;
import org.eclipse.syson.sysml.Definition;
import org.eclipse.syson.sysml.ExhibitStateUsage;
import org.eclipse.syson.sysml.Feature;
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;
Expand Down Expand Up @@ -79,13 +81,11 @@ public Boolean caseExhibitStateUsage(ExhibitStateUsage object) {
// Add this behavior parameter check for each caseXXXUsage.
// In this case, we want to display inherited parameters (directed feature) but not all features with the same
// type.
if (!shouldKeep && this.shouldConsiderParameter(object)) {
if (this.shouldConsiderParameter(object)) {
shouldKeep = this.isInheritedParameter(object);
}
if (!shouldKeep && this.shouldConsiderExhibitState(object)) {
} else if (this.shouldConsiderExhibitState(object)) {
shouldKeep = this.isInheritedState(object);
}
if (!shouldKeep) {
} else {
shouldKeep = super.caseExhibitStateUsage(object);
}
return shouldKeep;
Expand Down Expand Up @@ -115,6 +115,22 @@ public Boolean casePartUsage(PartUsage object) {
return eType.equals(eClass) || (eType instanceof EClass eTypeEClass && eTypeEClass.isSuperTypeOf(eClass));
}

@Override
public Boolean casePerformActionUsage(PerformActionUsage object) {
Boolean shouldKeep = Boolean.FALSE;
// Add this behavior parameter check for each caseXXXUsage.
// In this case, we want to display inherited parameters (directed feature) but not all features with the same
// type.
if (this.shouldConsiderParameter(object)) {
shouldKeep = this.isInheritedParameter(object);
} else if (this.shouldConsiderPerformUsage(object)) {
shouldKeep = this.isInheritedAction(object);
} else {
shouldKeep = super.casePerformActionUsage(object);
}
return shouldKeep;
}

@Override
public Boolean caseReferenceUsage(ReferenceUsage object) {
// Add this behavior parameter check for each caseXXXUsage.
Expand Down Expand Up @@ -162,4 +178,23 @@ private boolean isInheritedState(Feature feature) {
};
return featureState.contains(feature);
}

private boolean shouldConsiderPerformUsage(Feature feature) {
if (!(feature instanceof PerformActionUsage)) {
return false;
}

EClassifier eType = this.eReference.getEType();
EClass eClass = feature.eClass();
return eType.equals(eClass) || (eType instanceof EClass eTypeEClass && eTypeEClass.isSuperTypeOf(eClass));
}

private boolean isInheritedAction(Feature feature) {
List< ActionUsage> featureActions = switch (feature.getOwner()) {
case Definition definition -> definition.getOwnedAction();
case Usage usage -> usage.getNestedAction();
default -> List.of();
};
return featureActions.contains(feature);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
import org.eclipse.syson.standard.diagrams.view.nodes.ObjectiveDocumentationCompartmentItemNodeDescription;
import org.eclipse.syson.standard.diagrams.view.nodes.PerformActionsCompartmentItemNodeDescriptionProvider;
import org.eclipse.syson.standard.diagrams.view.nodes.PerformActionsCompartmentNodeDescriptionProvider;
import org.eclipse.syson.standard.diagrams.view.nodes.PerformActionsInheritedCompartmentItemNodeDescriptionProvider;
import org.eclipse.syson.standard.diagrams.view.nodes.PortDefinitionOwnedItemBorderNodeDescriptionProvider;
import org.eclipse.syson.standard.diagrams.view.nodes.PortDefinitionOwnedItemCompartmentItemNodeDescriptionProvider;
import org.eclipse.syson.standard.diagrams.view.nodes.PortUsageBorderNodeDescriptionProvider;
Expand Down Expand Up @@ -639,13 +640,15 @@ private List<IDiagramElementDescriptionProvider<?>> createCompartmentsForListIte
compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new CompartmentNodeDescriptionProvider(eClass, eReference, colorProvider));
compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsInheritedCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsCompartmentNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
} else if ((SysmlPackage.eINSTANCE.getPartUsage().equals(eClass) && SysmlPackage.eINSTANCE.getUsage_NestedAction().equals(eReference))
|| (SysmlPackage.eINSTANCE.getPartDefinition().equals(eClass) && SysmlPackage.eINSTANCE.getDefinition_OwnedAction().equals(eReference))) {
compartmentNodeDescriptionProviders.add(new ActionItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new CompartmentNodeDescriptionProvider(eClass, eReference, colorProvider));
compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsInheritedCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsCompartmentNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
} else if ((SysmlPackage.eINSTANCE.getPartUsage().equals(eClass) && SysmlPackage.eINSTANCE.getUsage_NestedState().equals(eReference))
Expand All @@ -661,6 +664,7 @@ private List<IDiagramElementDescriptionProvider<?>> createCompartmentsForListIte
compartmentNodeDescriptionProviders.add(new CompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new CompartmentNodeDescriptionProvider(eClass, eReference, colorProvider));
compartmentNodeDescriptionProviders.add(new InheritedCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsInheritedCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsCompartmentItemNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
compartmentNodeDescriptionProviders.add(new PerformActionsCompartmentNodeDescriptionProvider(eClass, eReference, colorProvider, this.getDescriptionNameGenerator()));
} else if (SysmlPackage.eINSTANCE.getPortDefinition().equals(eClass) && SysmlPackage.eINSTANCE.getDefinition_OwnedItem().equals(eReference)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ protected List<NodeDescription> getDroppableNodes(IViewDiagramElementFinder cach
public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) {
cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + PERFORM_ACTIONS_COMPARTMENT_NAME).ifPresent(nd -> {
cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentItemName(this.eClass, this.eReference) + PERFORM_ACTIONS_COMPARTMENT_NAME).ifPresent(nd.getChildrenDescriptions()::add);
cache.getNodeDescription(this.getDescriptionNameGenerator().getInheritedCompartmentItemName(this.eClass, this.eReference) + PERFORM_ACTIONS_COMPARTMENT_NAME).ifPresent(nd.getChildrenDescriptions()::add);
nd.setPalette(this.createCompartmentPalette(cache));
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* 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.standard.diagrams.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.sirius.components.view.diagram.NodeDescription;
import org.eclipse.syson.diagram.common.view.nodes.InheritedCompartmentItemNodeDescriptionProvider;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.AQLConstants;
import org.eclipse.syson.util.IDescriptionNameGenerator;
import org.eclipse.syson.util.SysMLMetamodelHelper;

/**
* The inherited perform action compartment list item node description provider.
*
* @author gcoutable
*/
public class PerformActionsInheritedCompartmentItemNodeDescriptionProvider extends InheritedCompartmentItemNodeDescriptionProvider {
public PerformActionsInheritedCompartmentItemNodeDescriptionProvider(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) {
super(eClass, eReference, colorProvider, descriptionNameGenerator);
}

@Override
public NodeDescription create() {
NodeDescription nd = super.create();
var qualifiedName = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getPerformActionUsage());
nd.setName(this.descriptionNameGenerator.getInheritedCompartmentItemName(this.eClass, this.eReference) + PerformActionsCompartmentNodeDescriptionProvider.PERFORM_ACTIONS_COMPARTMENT_NAME);
nd.setDomainType(qualifiedName);
nd.setPreconditionExpression(AQLConstants.AQL_SELF + ".oclIsTypeOf(" + qualifiedName + ")");
return nd;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ Users should use the dedicated tools to edit expressions instead, as they ensure
+
image::release-notes-rotate-fork-join-graphical-nodes.png[For both fork nodes and two join nodes, display one horizontal and one vertical graphical node. Also display the palette with the rotate tool, width=50%,height=50%]

** Add support for list item inheritance in _perform actions_ compartments.

* In the _Explorer_ view:

** The tree items corresponding to the internals of `Expression` elements (syntax tree) are now hidden by default.
Expand Down
Loading