Skip to content

Commit ddf7d17

Browse files
gcoutableAxelRICHARD
authored andcommitted
[1977] Display the PortionKind in the label of OccurrenceUsage graphical nodes
Bug: #1977 Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
1 parent 821a943 commit ddf7d17

File tree

4 files changed

+104
-21
lines changed

4 files changed

+104
-21
lines changed

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Integration tests that require Elasticsearch now need to extend `AbstractIntegra
6464

6565
=== New features
6666

67+
- https://github.com/eclipse-syson/syson/issues/1977[#1977] [diagram] Display the _timeslice_ and _snapshot_ prefixes in the label of `OccurrenceUsage` graphical nodes and some of the graphical nodes representing subclasses of `OccurrenceUsage`.
6768

6869
== v2026.1.0
6970

backend/services/syson-diagram-services/src/main/java/org/eclipse/syson/diagram/services/utils/MultiLineLabelSwitch.java

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public String caseElement(Element object) {
102102
public String caseAcceptActionUsage(AcceptActionUsage object) {
103103
StringBuilder label = new StringBuilder();
104104
label
105-
.append(this.getBasicNamePrefix(object))
105+
.append(this.getOccurrenceUsagePrefix(object))
106106
.append(LabelConstants.OPEN_QUOTE)
107107
.append(this.reference(object))
108108
.append("accept action")
@@ -139,7 +139,7 @@ public String caseActionDefinition(ActionDefinition object) {
139139
public String caseActionUsage(ActionUsage object) {
140140
StringBuilder label = new StringBuilder();
141141
label
142-
.append(this.getBasicNamePrefix(object))
142+
.append(this.getOccurrenceUsagePrefix(object))
143143
.append(LabelConstants.OPEN_QUOTE)
144144
.append(this.reference(object))
145145
.append("action")
@@ -173,7 +173,7 @@ public String caseAllocationDefinition(AllocationDefinition object) {
173173
public String caseAllocationUsage(AllocationUsage object) {
174174
StringBuilder label = new StringBuilder();
175175
label
176-
.append(this.getBasicNamePrefix(object))
176+
.append(this.getOccurrenceUsagePrefix(object))
177177
.append(LabelConstants.OPEN_QUOTE)
178178
.append(this.reference(object))
179179
.append("allocation")
@@ -226,7 +226,7 @@ public String caseAttributeUsage(AttributeUsage object) {
226226
public String caseAssignmentActionUsage(AssignmentActionUsage object) {
227227
StringBuilder label = new StringBuilder();
228228
label
229-
.append(this.getBasicNamePrefix(object))
229+
.append(this.getOccurrenceUsagePrefix(object))
230230
.append(LabelConstants.OPEN_QUOTE)
231231
.append(this.reference(object))
232232
.append("assign")
@@ -254,7 +254,7 @@ public String caseCaseDefinition(CaseDefinition object) {
254254
public String caseCaseUsage(CaseUsage object) {
255255
StringBuilder label = new StringBuilder();
256256
label
257-
.append(this.getBasicNamePrefix(object))
257+
.append(this.getOccurrenceUsagePrefix(object))
258258
.append(LabelConstants.OPEN_QUOTE)
259259
.append(this.reference(object))
260260
.append("case")
@@ -311,7 +311,7 @@ public String caseConcernDefinition(ConcernDefinition object) {
311311
public String caseConcernUsage(ConcernUsage object) {
312312
StringBuilder label = new StringBuilder();
313313
label
314-
.append(this.getBasicNamePrefix(object))
314+
.append(this.getOccurrenceUsagePrefix(object))
315315
.append(LabelConstants.OPEN_QUOTE)
316316
.append(this.reference(object))
317317
.append("concern")
@@ -345,7 +345,7 @@ public String caseConstraintDefinition(ConstraintDefinition object) {
345345
public String caseConstraintUsage(ConstraintUsage object) {
346346
StringBuilder label = new StringBuilder();
347347
label
348-
.append(this.getBasicNamePrefix(object))
348+
.append(this.getOccurrenceUsagePrefix(object))
349349
.append(LabelConstants.OPEN_QUOTE)
350350
.append(this.reference(object))
351351
.append("constraint")
@@ -434,7 +434,7 @@ public String caseEnumerationDefinition(EnumerationDefinition object) {
434434
public String caseExhibitStateUsage(ExhibitStateUsage object) {
435435
StringBuilder label = new StringBuilder();
436436
label
437-
.append(this.getBasicNamePrefix(object))
437+
.append(this.getOccurrenceUsagePrefix(object))
438438
.append(this.getIsParallel(object.isIsParallel()))
439439
.append(LabelConstants.OPEN_QUOTE)
440440
.append(this.reference(object))
@@ -469,7 +469,7 @@ public String caseInterfaceDefinition(InterfaceDefinition object) {
469469
public String caseInterfaceUsage(InterfaceUsage object) {
470470
StringBuilder label = new StringBuilder();
471471
label
472-
.append(this.getBasicNamePrefix(object))
472+
.append(this.getOccurrenceUsagePrefix(object))
473473
.append(LabelConstants.OPEN_QUOTE)
474474
.append(this.reference(object))
475475
.append("interface")
@@ -519,7 +519,7 @@ public String caseNamespaceImport(NamespaceImport object) {
519519
public String caseItemUsage(ItemUsage object) {
520520
StringBuilder label = new StringBuilder();
521521
label
522-
.append(this.getBasicNamePrefix(object))
522+
.append(this.getOccurrenceUsagePrefix(object))
523523
.append(LabelConstants.OPEN_QUOTE)
524524
.append(this.reference(object))
525525
.append("item")
@@ -568,8 +568,7 @@ public String caseOccurrenceDefinition(OccurrenceDefinition object) {
568568
public String caseOccurrenceUsage(OccurrenceUsage object) {
569569
StringBuilder label = new StringBuilder();
570570
label
571-
.append(this.getBasicNamePrefix(object))
572-
.append(this.individual(object))
571+
.append(this.getOccurrenceUsagePrefix(object))
573572
.append(LabelConstants.OPEN_QUOTE)
574573
.append(this.reference(object))
575574
.append("occurrence")
@@ -612,7 +611,7 @@ public String casePartUsage(PartUsage object) {
612611
if (!(object.getOwningMembership() instanceof ActorMembership)) {
613612
// The label shouldn't contain abstract, ref, or part if the part represents an actor.
614613
label
615-
.append(this.getBasicNamePrefix(object))
614+
.append(this.getOccurrenceUsagePrefix(object))
616615
.append(LabelConstants.OPEN_QUOTE)
617616
.append(this.reference(object))
618617
.append("part")
@@ -634,7 +633,7 @@ public String casePartUsage(PartUsage object) {
634633
public String casePerformActionUsage(PerformActionUsage object) {
635634
StringBuilder label = new StringBuilder();
636635
label
637-
.append(this.getBasicNamePrefix(object))
636+
.append(this.getOccurrenceUsagePrefix(object))
638637
.append(LabelConstants.OPEN_QUOTE)
639638
.append(this.reference(object))
640639
.append(this.getPerformActionUsageTag(object))
@@ -666,7 +665,7 @@ public String casePortDefinition(PortDefinition object) {
666665
public String casePortUsage(PortUsage object) {
667666
StringBuilder label = new StringBuilder();
668667
label
669-
.append(this.getBasicNamePrefix(object))
668+
.append(this.getOccurrenceUsagePrefix(object))
670669
.append(LabelConstants.OPEN_QUOTE)
671670
.append(this.reference(object))
672671
.append("port")
@@ -732,7 +731,7 @@ public String caseRequirementDefinition(RequirementDefinition object) {
732731
public String caseRequirementUsage(RequirementUsage object) {
733732
StringBuilder label = new StringBuilder();
734733
label
735-
.append(this.getBasicNamePrefix(object))
734+
.append(this.getOccurrenceUsagePrefix(object))
736735
.append(LabelConstants.OPEN_QUOTE)
737736
.append(this.reference(object))
738737
.append("requirement")
@@ -752,7 +751,7 @@ public String caseRequirementUsage(RequirementUsage object) {
752751
public String caseSatisfyRequirementUsage(SatisfyRequirementUsage object) {
753752
StringBuilder label = new StringBuilder();
754753
label
755-
.append(this.getBasicNamePrefix(object))
754+
.append(this.getOccurrenceUsagePrefix(object))
756755
.append(LabelConstants.OPEN_QUOTE)
757756
.append(this.reference(object))
758757
.append("satisfy requirement")
@@ -786,7 +785,7 @@ public String caseUseCaseDefinition(UseCaseDefinition object) {
786785
public String caseUseCaseUsage(UseCaseUsage object) {
787786
StringBuilder label = new StringBuilder();
788787
label
789-
.append(this.getBasicNamePrefix(object))
788+
.append(this.getOccurrenceUsagePrefix(object))
790789
.append(LabelConstants.OPEN_QUOTE)
791790
.append(this.reference(object))
792791
.append("use case")
@@ -821,7 +820,7 @@ public String caseStateDefinition(StateDefinition object) {
821820
public String caseStateUsage(StateUsage object) {
822821
StringBuilder label = new StringBuilder();
823822
label
824-
.append(this.getBasicNamePrefix(object))
823+
.append(this.getOccurrenceUsagePrefix(object))
825824
.append(this.getIsParallel(object.isIsParallel()))
826825
.append(LabelConstants.OPEN_QUOTE)
827826
.append(this.reference(object))
@@ -842,7 +841,7 @@ public String caseStateUsage(StateUsage object) {
842841
public String caseViewUsage(ViewUsage object) {
843842
StringBuilder label = new StringBuilder();
844843
label
845-
.append(this.getBasicNamePrefix(object))
844+
.append(this.getOccurrenceUsagePrefix(object))
846845
.append(LabelConstants.OPEN_QUOTE)
847846
.append(this.reference(object))
848847
.append("view")
@@ -871,6 +870,14 @@ private StringBuilder getIsParallel(boolean isParallel) {
871870
return parallel;
872871
}
873872

873+
private String getOccurrenceUsagePrefix(OccurrenceUsage occurrenceUsage) {
874+
return new StringBuilder()
875+
.append(this.getBasicNamePrefix(occurrenceUsage))
876+
.append(this.individual(occurrenceUsage))
877+
.append(this.portionKind(occurrenceUsage))
878+
.toString();
879+
}
880+
874881
private String getBasicNamePrefix(Type object) {
875882
StringBuilder label = new StringBuilder();
876883
if (object instanceof Usage usage) {
@@ -1004,6 +1011,18 @@ private String individual(boolean isIndividual) {
10041011
return label.toString();
10051012
}
10061013

1014+
private String portionKind(OccurrenceUsage occurrenceUsage) {
1015+
StringBuilder label = new StringBuilder();
1016+
if (occurrenceUsage.isSetPortionKind()) {
1017+
label
1018+
.append(LabelConstants.OPEN_QUOTE)
1019+
.append(occurrenceUsage.getPortionKind().getName())
1020+
.append(LabelConstants.CLOSE_QUOTE)
1021+
.append(LabelConstants.CR);
1022+
}
1023+
return label.toString();
1024+
}
1025+
10071026
private String assignmentActionUsageDetails(AssignmentActionUsage aau) {
10081027
StringBuilder label = new StringBuilder();
10091028
if (aau.getReferent() != null) {

backend/services/syson-diagram-services/src/test/java/org/eclipse/syson/diagram/services/utils/MultilineLabelSwitchTest.java

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024, 2025 Obeo.
2+
* Copyright (c) 2024, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -26,6 +26,8 @@
2626
import org.eclipse.syson.sysml.Definition;
2727
import org.eclipse.syson.sysml.Element;
2828
import org.eclipse.syson.sysml.FeatureMembership;
29+
import org.eclipse.syson.sysml.OccurrenceUsage;
30+
import org.eclipse.syson.sysml.PortionKind;
2931
import org.eclipse.syson.sysml.SysmlFactory;
3032
import org.eclipse.syson.sysml.SysmlPackage;
3133
import org.eclipse.syson.sysml.Type;
@@ -63,6 +65,8 @@ public class MultilineLabelSwitchTest {
6365

6466
private static final String DEFAULT_ASSIGNMENT_ACTION_USAGE_LABEL = LabelConstants.OPEN_QUOTE + REF_ATTRIBUTE_LABEL + "assign" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
6567

68+
private static final String DEFAULT_CASE_USAGE_LABEL = LabelConstants.OPEN_QUOTE + REF_ATTRIBUTE_LABEL + "case" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
69+
6670
private static final String DEFAULT_COMMENT_LABEL = LabelConstants.OPEN_QUOTE + "comment" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
6771

6872
private static final String DEFAULT_CONCERN_DEFINITION_LABEL = LabelConstants.OPEN_QUOTE + "concern def" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
@@ -113,6 +117,8 @@ public class MultilineLabelSwitchTest {
113117

114118
private static final String DEFAULT_USE_CASE_USAGE_LABEL = LabelConstants.OPEN_QUOTE + REF_ATTRIBUTE_LABEL + "use case" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
115119

120+
private static final String DEFAULT_VIEW_USAGE_LABEL = LabelConstants.OPEN_QUOTE + REF_ATTRIBUTE_LABEL + "view" + LabelConstants.CLOSE_QUOTE + LabelConstants.SPACE;
121+
116122
private static final String DEFAULT_STATE_DEFINITION_LABEL = LabelConstants.OPEN_QUOTE + "state def" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
117123

118124
private static final String DEFAULT_STATE_USAGE_LABEL = LabelConstants.OPEN_QUOTE + REF_ATTRIBUTE_LABEL + "state" + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
@@ -203,6 +209,28 @@ private static Stream<Arguments> prefixParameterProvider() {
203209
);
204210
}
205211

212+
private static Stream<Arguments> timesliceSnapshotPrefixParameterProvider() {
213+
return Stream.of(
214+
Arguments.of(SYSML.getOccurrenceUsage(), DEFAULT_OCCURRENCE_USAGE_LABEL),
215+
Arguments.of(SYSML.getActionUsage(), DEFAULT_ACTION_LABEL),
216+
Arguments.of(SYSML.getAcceptActionUsage(), DEFAULT_ACCEPT_ACTION_LABEL),
217+
Arguments.of(SYSML.getAssignmentActionUsage(), DEFAULT_ASSIGNMENT_ACTION_USAGE_LABEL),
218+
Arguments.of(SYSML.getCaseUsage(), DEFAULT_CASE_USAGE_LABEL),
219+
Arguments.of(SYSML.getUseCaseUsage(), DEFAULT_USE_CASE_USAGE_LABEL),
220+
Arguments.of(SYSML.getPerformActionUsage(), DEFAULT_PERFORM_ACTION_USAGE_LABEL),
221+
Arguments.of(SYSML.getExhibitStateUsage(), DEFAULT_EXHIBIT_STATE_USAGE_LABEL),
222+
Arguments.of(SYSML.getStateUsage(), DEFAULT_STATE_USAGE_LABEL),
223+
Arguments.of(SYSML.getConstraintUsage(), DEFAULT_CONSTRAINT_USAGE_LABEL),
224+
Arguments.of(SYSML.getSatisfyRequirementUsage(), DEFAULT_SATISFY_REQUIREMENT_USAGE_LABEL),
225+
Arguments.of(SYSML.getItemUsage(), DEFAULT_ITEM_USAGE_LABEL),
226+
Arguments.of(SYSML.getPartUsage(), DEFAULT_PART_USAGE_LABEL),
227+
Arguments.of(SYSML.getAllocationUsage(), DEFAULT_ALLOCATION_USAGE_LABEL),
228+
Arguments.of(SYSML.getInterfaceUsage(), DEFAULT_INTERFACE_USAGE_LABEL),
229+
Arguments.of(SYSML.getViewUsage(), DEFAULT_VIEW_USAGE_LABEL),
230+
Arguments.of(SYSML.getPortUsage(), DEFAULT_PORT_USAGE_LABEL)
231+
);
232+
}
233+
206234
@ParameterizedTest(name = "[{index}] Check default prefix in {0} element label")
207235
@MethodSource("defaultParameterProvider")
208236
public void testDefaultLabel(EClass elementType, String defaultLabel) {
@@ -294,6 +322,40 @@ public void testPrefixLabelWithVariantProperty(EClass elementType, String defaul
294322
}
295323
}
296324

325+
@ParameterizedTest(name = "[{index}] Check timeslice prefix in {0} element label")
326+
@MethodSource("timesliceSnapshotPrefixParameterProvider")
327+
public void testPrefixLabelWithTimesliceProperty(EClass elementType, String defaultLabel) {
328+
Element element = (Element) SysmlFactory.eINSTANCE.create(elementType);
329+
if (element instanceof OccurrenceUsage occurrenceUsage) {
330+
occurrenceUsage.setPortionKind(PortionKind.TIMESLICE);
331+
String timeslicePrefix = LabelConstants.OPEN_QUOTE + PortionKind.TIMESLICE.getName() + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
332+
if (element instanceof AcceptActionUsage) {
333+
assertEquals(timeslicePrefix + defaultLabel + LabelConstants.CR,
334+
this.multiLineLabelSwitch.doSwitch(element));
335+
} else {
336+
assertEquals(timeslicePrefix + defaultLabel,
337+
this.multiLineLabelSwitch.doSwitch(element));
338+
}
339+
}
340+
}
341+
342+
@ParameterizedTest(name = "[{index}] Check snapshot prefix in {0} element label")
343+
@MethodSource("timesliceSnapshotPrefixParameterProvider")
344+
public void testPrefixLabelWithSnapshotProperty(EClass elementType, String defaultLabel) {
345+
Element element = (Element) SysmlFactory.eINSTANCE.create(elementType);
346+
if (element instanceof OccurrenceUsage occurrenceUsage) {
347+
occurrenceUsage.setPortionKind(PortionKind.SNAPSHOT);
348+
String snapshotPrefix = LabelConstants.OPEN_QUOTE + PortionKind.SNAPSHOT.getName() + LabelConstants.CLOSE_QUOTE + LabelConstants.CR;
349+
if (element instanceof AcceptActionUsage) {
350+
assertEquals(snapshotPrefix + defaultLabel + LabelConstants.CR,
351+
this.multiLineLabelSwitch.doSwitch(element));
352+
} else {
353+
assertEquals(snapshotPrefix + defaultLabel,
354+
this.multiLineLabelSwitch.doSwitch(element));
355+
}
356+
}
357+
}
358+
297359
private Element createNestedElementIn(Element parentElement, EClass elementType) {
298360
Element newElement = (Element) SysmlFactory.eINSTANCE.create(elementType);
299361
FeatureMembership membership = SysmlFactory.eINSTANCE.createFeatureMembership();

doc/content/modules/user-manual/pages/release-notes/2026.3.0.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ part system {
7171
This tool allows to create a `SatisfyRequirementUsage` based on the `RequirementUsage` selected during the tool creation.
7272
** Add _New Satisfy Requirement_ graphical edge tool between `Feature` graphical nodes and `RequirementUsage` graphical nodes.
7373
This tool allows to create a `SatisfyRequirementUsage` between the `Feature` and `RequirementUsage` selected during the tool creation.
74+
** Add the _timeslice_ and _snapshot_ prefixes in the label of `OccurrenceUsage` graphical nodes and some of the graphical nodes representing subclasses of `OccurrenceUsage`.
7475

7576
* In textual import/export:
7677

0 commit comments

Comments
 (0)