Skip to content

Commit 4239872

Browse files
committed
[2196] Align Flow border-node tools targets
Bug: #2196 Signed-off-by: Axel RICHARD <axel.richard@obeo.fr>
1 parent 87da9e6 commit 4239872

11 files changed

Lines changed: 136 additions & 38 deletions

File tree

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ This change ensures compatibility with classpath resource resolution, which requ
6262
- https://github.com/eclipse-syson/syson/issues/2094[#2094] [libraries] Ensure library documents are read-only.
6363
- https://github.com/eclipse-syson/syson/issues/2143[#2143] [configuration] Fixed classpath resource resolution on Windows by enforcing forward slashes (`/`) in library paths.
6464
- https://github.com/eclipse-syson/syson/issues/2185[#2185] [explorer] When creating a `ConstraintUsage` inside a `Requirement` the new constraint is now correctly owned through a `RequirementConstraintMembership`.
65+
- https://github.com/eclipse-syson/syson/issues/2196[#2196] [diagrams] Align the _New Flow (flow)_ tool on `PortUsage`, `ItemUsage`, and `ReferenceUsage` border nodes with the supported `FlowUsage` rendered endpoints, preventing unsupported targets such as regular `ActionUsage` graphical nodes.
6566
- https://github.com/eclipse-syson/syson/issues/2204[#2204] [diagrams] Fix an issue where the resize of _Documentation_ graphical nodes was not working correctly, allowing inside text to overflow outside of the graphical node.
6667

6768
=== Improvements

backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVEdgePortUsageTests.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import org.eclipse.sirius.components.diagrams.ArrowStyle;
3131
import org.eclipse.sirius.components.diagrams.Diagram;
3232
import org.eclipse.sirius.components.diagrams.Edge;
33+
import org.eclipse.sirius.components.view.diagram.EdgeTool;
34+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
3335
import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider;
3436
import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState;
3537
import org.eclipse.syson.AbstractIntegrationTests;
@@ -39,6 +41,7 @@
3941
import org.eclipse.syson.application.controllers.diagrams.checkers.CheckDiagramElementCount;
4042
import org.eclipse.syson.application.controllers.diagrams.testers.EdgeCreationTester;
4143
import org.eclipse.syson.application.data.GeneralViewPortTestProjectData;
44+
import org.eclipse.syson.application.data.GeneralViewWithTopNodesTestProjectData;
4245
import org.eclipse.syson.services.SemanticRunnableFactory;
4346
import org.eclipse.syson.services.diagrams.DiagramComparator;
4447
import org.eclipse.syson.services.diagrams.DiagramDescriptionIdProvider;
@@ -47,6 +50,7 @@
4750
import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator;
4851
import org.eclipse.syson.sysml.BindingConnector;
4952
import org.eclipse.syson.sysml.SysmlPackage;
53+
import org.eclipse.syson.sysml.helper.EMFUtils;
5054
import org.eclipse.syson.util.IDescriptionNameGenerator;
5155
import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers;
5256
import org.junit.jupiter.api.BeforeEach;
@@ -108,6 +112,36 @@ public void setUp() {
108112
GeneralViewPortTestProjectData.SemanticIds.PACKAGE_1_ID);
109113
}
110114

115+
@DisplayName("GIVEN a General View diagram description, WHEN inspecting the New Flow tool on PortUsage border nodes, THEN ActionUsage nodes are not valid targets")
116+
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
117+
@Test
118+
public void givenGeneralViewDiagramDescriptionWhenInspectingFlowToolTargetsThenActionUsageNodesAreNotValidTargets() {
119+
var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
120+
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
121+
122+
var portUsageBorderNodeDescription = EMFUtils.allContainedObjectOfType(diagramDescription, NodeDescription.class)
123+
.filter(nodeDescription -> this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort())
124+
.equals(nodeDescription.getName()))
125+
.findFirst();
126+
assertThat(portUsageBorderNodeDescription).isPresent();
127+
128+
var actionUsageNodeDescription = EMFUtils.allContainedObjectOfType(diagramDescription, NodeDescription.class)
129+
.filter(nodeDescription -> this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getActionUsage()).equals(nodeDescription.getName()))
130+
.findFirst();
131+
assertThat(actionUsageNodeDescription).isPresent();
132+
var referenceUsageBorderNodeDescriptionName = this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getReferenceUsage());
133+
var inheritedPortUsageBorderNodeDescriptionName = this.descriptionNameGenerator
134+
.getInheritedBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort());
135+
136+
var newFlowTool = portUsageBorderNodeDescription.get().getPalette().getEdgeTools().stream()
137+
.filter(edgeTool -> "New Flow (flow)".equals(edgeTool.getName()))
138+
.findFirst();
139+
assertThat(newFlowTool).isPresent();
140+
assertThat(this.getTargetDescriptionNames(newFlowTool.get()))
141+
.contains(referenceUsageBorderNodeDescriptionName, inheritedPortUsageBorderNodeDescriptionName)
142+
.doesNotContain(actionUsageNodeDescription.get().getName());
143+
}
144+
111145
@DisplayName("GIVEN a SysML Project with Ports, WHEN Flow edge tool creation is request between two ports, THEN a new Flow edge is created")
112146
@GivenSysONServer({ GeneralViewPortTestProjectData.SCRIPT_PATH })
113147
@Test
@@ -159,6 +193,14 @@ public void givenSysMLProjectWithPortsWhenFlowUsageEdgeToolCreationIsRequestedTh
159193

160194
}
161195

196+
private List<String> getTargetDescriptionNames(EdgeTool edgeTool) {
197+
return edgeTool.getTargetElementDescriptions().stream()
198+
.filter(NodeDescription.class::isInstance)
199+
.map(NodeDescription.class::cast)
200+
.map(NodeDescription::getName)
201+
.toList();
202+
}
203+
162204
@DisplayName("GIVEN a SysML Project with ports, WHEN binding connector as usage edge tool creation is request between two ports, THEN a new binding connector edge is created")
163205
@GivenSysONServer({ GeneralViewPortTestProjectData.SCRIPT_PATH })
164206
@Test

backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVFlowUsageTests.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
import org.eclipse.sirius.components.diagrams.tests.graphql.PaletteQueryRunner;
4545
import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator;
4646
import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionSuccessPayload;
47+
import org.eclipse.sirius.components.view.diagram.EdgeTool;
48+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
4749
import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider;
4850
import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState;
4951
import org.eclipse.syson.AbstractIntegrationTests;
@@ -67,6 +69,7 @@
6769
import org.eclipse.syson.sysml.FlowUsage;
6870
import org.eclipse.syson.sysml.PayloadFeature;
6971
import org.eclipse.syson.sysml.SysmlPackage;
72+
import org.eclipse.syson.sysml.helper.EMFUtils;
7073
import org.eclipse.syson.sysml.helper.LabelConstants;
7174
import org.eclipse.syson.util.IDescriptionNameGenerator;
7275
import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers;
@@ -144,6 +147,48 @@ public void setUp() {
144147
GeneralViewFlowConnectionItemUsagesProjectData.SemanticIds.PACKAGE_1_ID);
145148
}
146149

150+
@DisplayName("GIVEN a General View diagram description, WHEN inspecting the New Flow tool on ItemUsage border nodes, THEN it uses the full renderer-compatible border-node targets")
151+
@GivenSysONServer({ GeneralViewFlowConnectionItemUsagesProjectData.SCRIPT_PATH })
152+
@Test
153+
public void givenGeneralViewDiagramDescriptionWhenInspectingItemFlowToolTargetsThenTheyMatchTheRendererContract() {
154+
var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewFlowConnectionItemUsagesProjectData.EDITING_CONTEXT_ID,
155+
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
156+
157+
var itemUsageBorderNodeDescription = this.findNodeDescription(diagramDescription,
158+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getBehavior_Parameter()));
159+
var actionUsageNodeDescription = this.findNodeDescription(diagramDescription, this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getActionUsage()));
160+
161+
var newFlowTool = itemUsageBorderNodeDescription.getPalette().getEdgeTools().stream()
162+
.filter(edgeTool -> "New Flow (flow)".equals(edgeTool.getName()))
163+
.findFirst();
164+
assertThat(newFlowTool).isPresent();
165+
166+
assertThat(this.getTargetDescriptionNames(newFlowTool.get()))
167+
.containsExactlyInAnyOrderElementsOf(this.getExpectedFlowTargetDescriptionNames())
168+
.doesNotContain(actionUsageNodeDescription.getName());
169+
}
170+
171+
@DisplayName("GIVEN a General View diagram description, WHEN inspecting the New Flow tool on ReferenceUsage border nodes, THEN it uses the full renderer-compatible border-node targets")
172+
@GivenSysONServer({ GeneralViewFlowConnectionItemUsagesProjectData.SCRIPT_PATH })
173+
@Test
174+
public void givenGeneralViewDiagramDescriptionWhenInspectingReferenceFlowToolTargetsThenTheyMatchTheRendererContract() {
175+
var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewFlowConnectionItemUsagesProjectData.EDITING_CONTEXT_ID,
176+
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
177+
178+
var referenceUsageBorderNodeDescription = this.findNodeDescription(diagramDescription,
179+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getReferenceUsage()));
180+
var actionUsageNodeDescription = this.findNodeDescription(diagramDescription, this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getActionUsage()));
181+
182+
var newFlowTool = referenceUsageBorderNodeDescription.getPalette().getEdgeTools().stream()
183+
.filter(edgeTool -> "New Flow (flow)".equals(edgeTool.getName()))
184+
.findFirst();
185+
assertThat(newFlowTool).isPresent();
186+
187+
assertThat(this.getTargetDescriptionNames(newFlowTool.get()))
188+
.containsExactlyInAnyOrderElementsOf(this.getExpectedFlowTargetDescriptionNames())
189+
.doesNotContain(actionUsageNodeDescription.getName());
190+
}
191+
147192
@DisplayName("GIVEN a SysML Project with ItemUsages on ActionUsage, WHEN creating a FlowUsage between them, THEN an edge should be displayed to represent that new flow")
148193
@GivenSysONServer({ GeneralViewFlowConnectionItemUsagesProjectData.SCRIPT_PATH })
149194
@Test
@@ -624,4 +669,31 @@ private void assertConnectionType(IEditingContext editingContext, String connect
624669
var connectionTypeId = this.identityService.getId(connectionType);
625670
assertThat(connectionTypeId).isEqualTo(expectedTypeElementId);
626671
}
672+
673+
private NodeDescription findNodeDescription(org.eclipse.sirius.components.view.diagram.DiagramDescription diagramDescription, String nodeDescriptionName) {
674+
return EMFUtils.allContainedObjectOfType(diagramDescription, NodeDescription.class)
675+
.filter(nodeDescription -> nodeDescriptionName.equals(nodeDescription.getName()))
676+
.findFirst()
677+
.orElseThrow();
678+
}
679+
680+
private List<String> getExpectedFlowTargetDescriptionNames() {
681+
return List.of(
682+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort()),
683+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort()),
684+
this.descriptionNameGenerator.getInheritedBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort()),
685+
this.descriptionNameGenerator.getInheritedBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort()),
686+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem()),
687+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem()),
688+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getBehavior_Parameter()),
689+
this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getReferenceUsage()));
690+
}
691+
692+
private List<String> getTargetDescriptionNames(EdgeTool edgeTool) {
693+
return edgeTool.getTargetElementDescriptions().stream()
694+
.filter(NodeDescription.class::isInstance)
695+
.map(NodeDescription.class::cast)
696+
.map(NodeDescription::getName)
697+
.toList();
698+
}
627699
}

backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractItemUsageBorderNodeDescriptionProvider.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ public AbstractItemUsageBorderNodeDescriptionProvider(EReference eReference, ICo
6262

6363
protected abstract List<NodeDescription> getBindingConectorAsUsageToolTarget(IViewDiagramElementFinder cache);
6464

65-
protected abstract List<NodeDescription> getFlowConnectionToolTargets(IViewDiagramElementFinder cache);
66-
6765
protected abstract String getSemanticCandidatesExpression();
6866

6967
protected abstract String getName();
@@ -165,7 +163,7 @@ private NodePalette createNodePalette(IViewDiagramElementFinder cache, NodeDescr
165163
.toolSections(this.defaultToolsFactory.createDefaultHideRevealNodeToolSection())
166164
.edgeTools(
167165
this.createBindingConnectorAsUsageEdgeTool(this.getBindingConectorAsUsageToolTarget(cache)),
168-
this.createFlowUsageEdgeTool(this.getFlowConnectionToolTargets(cache)))
166+
this.createFlowUsageEdgeTool(this.getFlowUsageToolTargetDescriptions(cache, this.descriptionNameGenerator)))
169167
.quickAccessTools(this.getDuplicateElementAndNodeTool())
170168
.build();
171169
}

backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractNodeDescriptionProvider.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,24 @@
2222
import org.eclipse.sirius.components.core.api.IEditingContext;
2323
import org.eclipse.sirius.components.diagrams.Node;
2424
import org.eclipse.sirius.components.view.UserColor;
25+
import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder;
2526
import org.eclipse.sirius.components.view.builder.generated.diagram.DiagramBuilders;
2627
import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders;
2728
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
2829
import org.eclipse.sirius.components.view.builder.providers.INodeDescriptionProvider;
2930
import org.eclipse.sirius.components.view.diagram.ImageNodeStyleDescription;
31+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
3032
import org.eclipse.sirius.components.view.diagram.NodeTool;
3133
import org.eclipse.sirius.components.view.diagram.NodeToolSection;
3234
import org.eclipse.sirius.components.view.diagram.provider.DefaultToolsFactory;
3335
import org.eclipse.sirius.components.view.emf.diagram.ViewDiagramDescriptionConverter;
3436
import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService;
3537
import org.eclipse.syson.diagram.services.aql.DiagramQueryAQLService;
3638
import org.eclipse.syson.sysml.Element;
39+
import org.eclipse.syson.sysml.SysmlPackage;
3740
import org.eclipse.syson.util.AQLConstants;
3841
import org.eclipse.syson.util.AQLUtils;
42+
import org.eclipse.syson.util.IDescriptionNameGenerator;
3943
import org.eclipse.syson.util.ServiceMethod;
4044
import org.eclipse.syson.util.StandardDiagramsConstants;
4145

@@ -82,6 +86,19 @@ protected ImageNodeStyleDescription createImageNodeStyleDescription(String image
8286
.build();
8387
}
8488

89+
protected List<NodeDescription> getFlowUsageToolTargetDescriptions(IViewDiagramElementFinder cache, IDescriptionNameGenerator descriptionNameGenerator) {
90+
var nodes = new ArrayList<NodeDescription>();
91+
cache.getNodeDescription(descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort())).ifPresent(nodes::add);
92+
cache.getNodeDescription(descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort())).ifPresent(nodes::add);
93+
cache.getNodeDescription(descriptionNameGenerator.getInheritedBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort())).ifPresent(nodes::add);
94+
cache.getNodeDescription(descriptionNameGenerator.getInheritedBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort())).ifPresent(nodes::add);
95+
cache.getNodeDescription(descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem())).ifPresent(nodes::add);
96+
cache.getNodeDescription(descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem())).ifPresent(nodes::add);
97+
cache.getNodeDescription(descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getBehavior_Parameter())).ifPresent(nodes::add);
98+
cache.getNodeDescription(descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getReferenceUsage())).ifPresent(nodes::add);
99+
return nodes;
100+
}
101+
85102
protected NodeTool getDeleteFromDiagramTool() {
86103
return this.diagramBuilderHelper.newNodeTool()
87104
.name("Delete from Diagram")

backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/nodes/AbstractPortUsageBorderNodeDescriptionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ protected EdgeTool createConnectionUsageEdgeTool(IViewDiagramElementFinder cache
156156

157157
protected EdgeTool createFlowUsageEdgeTool(IViewDiagramElementFinder cache) {
158158
return this.getViewEdgeToolService(cache)
159-
.createFlowUsageEdgeTool(new DescriptionFinder(this.descriptionNameGenerator).getConnectableNodeDescriptions(cache.getNodeDescriptions(), SysmlPackage.eINSTANCE.getUsage()));
159+
.createFlowUsageEdgeTool(this.getFlowUsageToolTargetDescriptions(cache, this.descriptionNameGenerator));
160160
}
161161

162162
protected EdgeTool createInterfaceUsageEdgeTool(IViewDiagramElementFinder cache) {

backend/views/syson-standard-diagrams-view/src/main/java/org/eclipse/syson/standard/diagrams/view/nodes/ActionDefinitionParameterBorderNodeDescriptionProvider.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,4 @@ protected List<NodeDescription> getBindingConectorAsUsageToolTarget(IViewDiagram
5252
return nodeDescriptions;
5353
}
5454

55-
@Override
56-
protected List<NodeDescription> getFlowConnectionToolTargets(IViewDiagramElementFinder cache) {
57-
var nodes = new ArrayList<NodeDescription>();
58-
cache.getNodeDescription(this.getName()).ifPresent(nodes::add);
59-
cache.getNodeDescription(this.getDescriptionNameGenerator().getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort())).ifPresent(nodes::add);
60-
cache.getNodeDescription(this.getDescriptionNameGenerator().getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort())).ifPresent(nodes::add);
61-
cache.getNodeDescription(this.getDescriptionNameGenerator().getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem())).ifPresent(nodes::add);
62-
cache.getNodeDescription(this.getDescriptionNameGenerator().getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem())).ifPresent(nodes::add);
63-
return nodes;
64-
}
65-
6655
}

0 commit comments

Comments
 (0)