Skip to content

Commit 359e2c5

Browse files
committed
[1581] Display inherited PortUsages as border nodes in diagrams
Bug: #1581 Signed-off-by: Florian ROUËNÉ <florian.rouene@obeosoft.com>
1 parent 675e241 commit 359e2c5

15 files changed

Lines changed: 476 additions & 78 deletions

File tree

CHANGELOG.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
=== New features
1818

19+
- https://github.com/eclipse-syson/syson/issues/1581[#1581] [diagrams] Display inherited `PortUsages` as border nodes in diagrams
20+
1921
== v2025.10.0
2022

2123
=== Breaking changes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.application.controllers.diagrams.general.view;
14+
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
import static org.eclipse.sirius.components.diagrams.tests.DiagramEventPayloadConsumer.assertRefreshedDiagramThat;
17+
18+
import com.jayway.jsonpath.JsonPath;
19+
20+
import java.time.Duration;
21+
import java.util.UUID;
22+
import java.util.concurrent.atomic.AtomicReference;
23+
import java.util.function.Consumer;
24+
25+
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput;
26+
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload;
27+
import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator;
28+
import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState;
29+
import org.eclipse.syson.AbstractIntegrationTests;
30+
import org.eclipse.syson.application.controllers.diagrams.graphql.ShowDiagramsInheritedMembersMutationRunner;
31+
import org.eclipse.syson.application.data.GeneralViewInheritedPortTestProjectData;
32+
import org.eclipse.syson.diagram.common.view.services.dto.ShowDiagramsInheritedMembersInput;
33+
import org.eclipse.syson.diagram.common.view.services.dto.ShowDiagramsInheritedMembersSuccessPayload;
34+
import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription;
35+
import org.junit.jupiter.api.BeforeEach;
36+
import org.junit.jupiter.api.DisplayName;
37+
import org.junit.jupiter.api.Test;
38+
import org.springframework.beans.factory.annotation.Autowired;
39+
import org.springframework.boot.test.context.SpringBootTest;
40+
import org.springframework.test.context.jdbc.Sql;
41+
import org.springframework.test.context.jdbc.SqlConfig;
42+
import org.springframework.transaction.annotation.Transactional;
43+
44+
import reactor.core.publisher.Flux;
45+
import reactor.test.StepVerifier;
46+
47+
/**
48+
* Tests the display of inherited ports inside the General View diagram.
49+
*
50+
* @author frouene
51+
*/
52+
@Transactional
53+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
54+
public class GVInheritedPortTests extends AbstractIntegrationTests {
55+
56+
@Autowired
57+
private IGivenInitialServerState givenInitialServerState;
58+
59+
@Autowired
60+
private IGivenDiagramSubscription givenDiagramSubscription;
61+
62+
@Autowired
63+
private ShowDiagramsInheritedMembersMutationRunner showDiagramsInheritedMembersMutationRunner;
64+
65+
private Flux<DiagramRefreshedEventPayload> givenSubscriptionToDiagram() {
66+
var diagramEventInput = new DiagramEventInput(UUID.randomUUID(),
67+
GeneralViewInheritedPortTestProjectData.EDITING_CONTEXT_ID,
68+
GeneralViewInheritedPortTestProjectData.GraphicalIds.DIAGRAM_ID);
69+
return this.givenDiagramSubscription.subscribe(diagramEventInput);
70+
}
71+
72+
@BeforeEach
73+
public void beforeEach() {
74+
this.givenInitialServerState.initialize();
75+
}
76+
77+
@DisplayName("GIVEN a diagram with some inherited port, WHEN show inherited members filter is uncheck, THEN inherited ports are not displayed")
78+
@Sql(scripts = { GeneralViewInheritedPortTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
79+
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
80+
@Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
81+
@Test
82+
public void checkInheritedPortsVisibility() {
83+
var flux = this.givenSubscriptionToDiagram();
84+
85+
var diagramId = new AtomicReference<String>();
86+
87+
Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram -> {
88+
diagramId.set(diagram.getId());
89+
var part2Node = new DiagramNavigator(diagram).nodeWithLabel("«part»\npart2").getNode();
90+
assertThat(part2Node.getBorderNodes()).hasSize(1);
91+
assertThat(part2Node.getBorderNodes()).allMatch(node -> node.getOutsideLabels().get(0).text().equals("port1"));
92+
var v1Node = new DiagramNavigator(diagram).nodeWithLabel("«part»\nv1 : Vehicle").getNode();
93+
assertThat(v1Node.getBorderNodes()).hasSize(1);
94+
assertThat(v1Node.getBorderNodes()).allMatch(node -> node.getOutsideLabels().get(0).text().equals("^fuelInPort : FuelPort"));
95+
});
96+
97+
Runnable uncheckShowInheritedMembersFilter = () -> {
98+
var input = new ShowDiagramsInheritedMembersInput(
99+
UUID.randomUUID(),
100+
GeneralViewInheritedPortTestProjectData.EDITING_CONTEXT_ID,
101+
diagramId.get(),
102+
false);
103+
var result = this.showDiagramsInheritedMembersMutationRunner.run(input);
104+
String typename = JsonPath.read(result, "$.data.showDiagramsInheritedMembers.__typename");
105+
assertThat(typename).isEqualTo(ShowDiagramsInheritedMembersSuccessPayload.class.getSimpleName());
106+
};
107+
108+
Consumer<Object> updatedDiagramContentConsumerAfterInheritedVisibilityChange = assertRefreshedDiagramThat(diagram -> {
109+
var part2Node = new DiagramNavigator(diagram).nodeWithLabel("«part»\npart2").getNode();
110+
assertThat(part2Node.getBorderNodes()).hasSize(1);
111+
var v1Node = new DiagramNavigator(diagram).nodeWithLabel("«part»\nv1 : Vehicle").getNode();
112+
assertThat(v1Node.getBorderNodes()).hasSize(0);
113+
});
114+
115+
StepVerifier.create(flux)
116+
.consumeNextWith(initialDiagramContentConsumer)
117+
.then(uncheckShowInheritedMembersFilter)
118+
.consumeNextWith(updatedDiagramContentConsumerAfterInheritedVisibilityChange)
119+
.thenCancel()
120+
.verify(Duration.ofSeconds(10));
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.application.controllers.diagrams.graphql;
14+
15+
import java.util.Objects;
16+
17+
import org.eclipse.sirius.components.core.api.IInput;
18+
import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor;
19+
import org.eclipse.sirius.components.graphql.tests.api.IMutationRunner;
20+
import org.springframework.stereotype.Service;
21+
22+
/**
23+
* Used to show diagram inherited members with the GraphQL API.
24+
*
25+
* @author frouene
26+
*/
27+
@Service
28+
public class ShowDiagramsInheritedMembersMutationRunner implements IMutationRunner<IInput> {
29+
30+
private static final String SHOW_DIAGRAM_INHERITED_MEMBERS_MUTATION = """
31+
mutation showDiagramsInheritedMembers($input: ShowDiagramsInheritedMembersInput!) {
32+
showDiagramsInheritedMembers(input: $input) {
33+
__typename
34+
... on ShowDiagramsInheritedMembersSuccessPayload {
35+
show
36+
}
37+
... on ErrorPayload {
38+
message
39+
}
40+
}
41+
}
42+
""";
43+
44+
private final IGraphQLRequestor graphQLRequestor;
45+
46+
public ShowDiagramsInheritedMembersMutationRunner(IGraphQLRequestor graphQLRequestor) {
47+
this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor);
48+
}
49+
50+
@Override
51+
public String run(IInput input) {
52+
return this.graphQLRequestor.execute(SHOW_DIAGRAM_INHERITED_MEMBERS_MUTATION, input);
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.application.data;
14+
15+
/**
16+
* Identifiers for "GeneralView-InheritedPort" project.
17+
*
18+
* @author frouene
19+
*/
20+
public class GeneralViewInheritedPortTestProjectData {
21+
22+
public static final String SCRIPT_PATH = "/scripts/database-content/GeneralView-InheritedPort.sql";
23+
24+
public static final String EDITING_CONTEXT_ID = "c3b348b0-548e-4bee-b039-925a0a9eece0";
25+
26+
/**
27+
* Ids of graphical elements.
28+
*/
29+
public static class GraphicalIds {
30+
31+
public static final String DIAGRAM_ID = "d10ee99f-f2cf-4182-a614-e620e885f55f";
32+
33+
}
34+
35+
/**
36+
* Ids for the semantic elements.
37+
*/
38+
public static class SemanticIds {
39+
40+
}
41+
42+
}

backend/application/syson-application/src/test/resources/scripts/database-content/GeneralView-InheritedPort.sql

Lines changed: 100 additions & 0 deletions
Large diffs are not rendered by default.

backend/services/syson-services/src/main/java/org/eclipse/syson/util/DescriptionNameGenerator.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ protected String getBorderNodeName(String prefix, String type) {
5656
return this.getName(prefix, "BorderNode", type);
5757
}
5858

59+
protected String getInheritedBorderNodeName(String prefix, String type) {
60+
return this.getName(prefix, "InheritedBorderNode", type);
61+
}
62+
5963
protected String getCompartmentName(String prefix, String suffix) {
6064
return this.getName(prefix, "Compartment", suffix);
6165
}
@@ -175,6 +179,19 @@ public String getBorderNodeName(EClass eClass) {
175179
return this.getBorderNodeName(this.getDiagramPrefix(), eClass.getName());
176180
}
177181

182+
/**
183+
* Returns the name of an inherited border {@link NodeDescription} starting with the diagram prefix and followed by the name of
184+
* the given {@link EClass}.
185+
*
186+
* @param eClass
187+
* the {@link EClass} used to compute the name of the border {@link NodeDescription}.
188+
* @return a string starting with the diagram prefix and followed by the name of the given {@link EClass}
189+
*/
190+
@Override
191+
public String getInheritedBorderNodeName(EClass eClass) {
192+
return this.getInheritedBorderNodeName(this.getDiagramPrefix(), eClass.getName());
193+
}
194+
178195
/**
179196
* Returns the name of a compartment {@link NodeDescription} starting with the diagram prefix, followed by the name
180197
* of the given {@link EClass} and the name of the given {@link EReference}.

backend/services/syson-services/src/main/java/org/eclipse/syson/util/IDescriptionNameGenerator.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ default String getCreationToolName(EReference eReference) {
9494
*/
9595
String getBorderNodeName(EClass eClass);
9696

97+
/**
98+
* Returns the name of an inherited border {@link NodeDescription} using the given {@link EClass}.
99+
*
100+
* @param eClass
101+
* the {@link EClass} used to compute the name of the border {@link NodeDescription}.
102+
* @return a string used to name an inherited border {@link NodeDescription}.
103+
*/
104+
String getInheritedBorderNodeName(EClass eClass);
105+
97106
/**
98107
* Returns the name of a compartment {@link NodeDescription} using the given {@link EClass} and {@link EReference}.
99108
*

0 commit comments

Comments
 (0)