Skip to content

Commit c76ccee

Browse files
committed
[2250] Leverage the selection dialog to improve the assume and require constraints
Bug: #2250 Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
1 parent d256cc4 commit c76ccee

17 files changed

Lines changed: 840 additions & 40 deletions

File tree

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ One creates a `ConcernUsage` and another one creates `FramedConcernMembership`.
4747
This is currently supported on `Features` (e.g. `Attribute`), `Constraints` and `Transitions` (guard conditions) view new context menu actions (_Create expression_ and _Edit expression_) on the corresponding elements in the _Explorer_.
4848
- https://github.com/eclipse-syson/syson/issues/2247[#2247] [diagrams] Add the support for creating _timeslices/snapshots_ from the different kind of `OccurrenceDefiniton` graphical nodes.
4949
It leverages the selection dialog to either create an _occurrence timeslice/snapshot_, or the _usage timeslice/snapshot_ matching the `OccurrenceDefinition` on which the tool is applied.
50+
- https://github.com/eclipse-syson/syson/issues/2250[#2250] [diagrams] Leverage the selection dialog to improve the graphical node tools creating a _require_ `ConstraintUsage`, or a _assume_ `ConstraintUsage`, from `RequirementUsage` and `RequirementDefinition` graphical nodes.
5051

5152
== v2026.5.0
5253

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

Lines changed: 143 additions & 8 deletions
Large diffs are not rendered by default.

backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/ModelMutationElementService.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919
import org.eclipse.emf.ecore.util.EcoreUtil;
2020
import org.eclipse.sirius.components.emf.utils.SiriusEMFCopier;
2121
import org.eclipse.syson.sysml.ConcernUsage;
22+
import org.eclipse.syson.sysml.ConstraintUsage;
2223
import org.eclipse.syson.sysml.Definition;
2324
import org.eclipse.syson.sysml.Element;
2425
import org.eclipse.syson.sysml.FeatureTyping;
2526
import org.eclipse.syson.sysml.FramedConcernMembership;
2627
import org.eclipse.syson.sysml.Namespace;
2728
import org.eclipse.syson.sysml.PartUsage;
2829
import org.eclipse.syson.sysml.Relationship;
30+
import org.eclipse.syson.sysml.RequirementConstraintKind;
31+
import org.eclipse.syson.sysml.RequirementConstraintMembership;
2932
import org.eclipse.syson.sysml.RequirementDefinition;
3033
import org.eclipse.syson.sysml.RequirementUsage;
3134
import org.eclipse.syson.sysml.SatisfyRequirementUsage;
@@ -235,6 +238,42 @@ public FramedConcernMembership createFramedConcern(Type type, ConcernUsage conce
235238
return null;
236239
}
237240

241+
/**
242+
* In a {@link RequirementUsage} or a {@link RequirementDefinition}, creates a {@link RequirementConstraintMembership} containing a {@link ConstraintUsage}.
243+
* The {@link RequirementConstraintKind} is used to indicate whether the constraint is {@code required} or {@code assumed}.
244+
* If a {@link ConstraintUsage} is given, the {@link RequirementConstraintMembership} owned constraint will be subsetted by the given {@link ConstraintUsage}.
245+
*
246+
* @param type
247+
* the type that will hold the {@link RequirementConstraintMembership}, {@code type} must be a {@link RequirementDefinition} or a requirementUsage
248+
* @param constraintUsage
249+
* the {@link ConstraintUsage} subsetted by reference, can be {@code null}
250+
* @param constraintKind
251+
* whether the constraint is {@code required} or {@code assumed}
252+
* @return the created {@link RequirementConstraintMembership} when {@code type} is a {@link RequirementDefinition}, or a {@link RequirementUsage}, {@code null} otherwise
253+
*/
254+
public RequirementConstraintMembership createConstraint(Type type, ConstraintUsage constraintUsage, RequirementConstraintKind constraintKind) {
255+
if (type instanceof RequirementDefinition || type instanceof RequirementUsage) {
256+
var newRequirementConstraintMembership = SysmlFactory.eINSTANCE.createRequirementConstraintMembership();
257+
type.getOwnedRelationship().add(newRequirementConstraintMembership);
258+
newRequirementConstraintMembership.setKind(constraintKind);
259+
260+
var newConstraintUsage = SysmlFactory.eINSTANCE.createConstraintUsage();
261+
newRequirementConstraintMembership.getOwnedRelatedElement().add(newConstraintUsage);
262+
263+
this.metamodelMutationElementService.initialize(newRequirementConstraintMembership);
264+
this.metamodelMutationElementService.initialize(newConstraintUsage);
265+
266+
if (constraintUsage != null) {
267+
var newReferenceSubsetting = SysmlFactory.eINSTANCE.createReferenceSubsetting();
268+
newConstraintUsage.getOwnedRelationship().add(newReferenceSubsetting);
269+
newReferenceSubsetting.setReferencedFeature(constraintUsage);
270+
this.metamodelMutationElementService.initialize(newReferenceSubsetting);
271+
}
272+
return newRequirementConstraintMembership;
273+
}
274+
return null;
275+
}
276+
238277
/**
239278
* Creates a {@link SatisfyRequirementUsage SatisfyRequirement} on {@code parentElement}.
240279
* <p>

backend/services/syson-model-services/src/main/java/org/eclipse/syson/model/services/aql/ModelMutationAQLService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
import org.eclipse.emf.ecore.EObject;
1919
import org.eclipse.syson.model.services.ModelMutationElementService;
2020
import org.eclipse.syson.sysml.ConcernUsage;
21+
import org.eclipse.syson.sysml.ConstraintUsage;
2122
import org.eclipse.syson.sysml.Documentation;
2223
import org.eclipse.syson.sysml.Element;
2324
import org.eclipse.syson.sysml.Membership;
2425
import org.eclipse.syson.sysml.PartUsage;
26+
import org.eclipse.syson.sysml.RequirementConstraintKind;
2527
import org.eclipse.syson.sysml.RequirementUsage;
2628
import org.eclipse.syson.sysml.Type;
2729
import org.eclipse.syson.sysml.ViewUsage;
@@ -113,4 +115,11 @@ public Element setAsView(ViewUsage viewUsage, String newViewDefinition) {
113115
public Element createFramedConcern(Type type, ConcernUsage concernUsage) {
114116
return this.modelMutationElementService.createFramedConcern(type, concernUsage);
115117
}
118+
119+
/**
120+
* {@link ModelMutationElementService#createConstraint(Type, ConstraintUsage, RequirementConstraintKind)}.
121+
*/
122+
public Element createConstraint(Type type, ConstraintUsage constraintUsage, RequirementConstraintKind constraintKind) {
123+
return this.modelMutationElementService.createConstraint(type, constraintUsage, constraintKind);
124+
}
116125
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 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.diagram.common.view.nodes;
14+
15+
import org.eclipse.emf.ecore.EClass;
16+
import org.eclipse.emf.ecore.EReference;
17+
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
18+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
19+
import org.eclipse.syson.sysml.SysmlPackage;
20+
import org.eclipse.syson.util.IDescriptionNameGenerator;
21+
import org.eclipse.syson.util.SysMLMetamodelHelper;
22+
23+
/**
24+
* Used to create a {@link org.eclipse.syson.sysml.ConstraintUsage} compartment item node description.
25+
* <p>
26+
* {@link org.eclipse.syson.sysml.ConstraintUsage} compartment items have to be contained in a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#ASSUMPTION}.
27+
* </p>
28+
* @author gcoutable
29+
*/
30+
public class AssumeConstraintCompartmentItemNodeDescription extends CompartmentItemNodeDescriptionProvider {
31+
public static final String COMPARTMENT_ITEM_NAME = " assume constraint";
32+
33+
public AssumeConstraintCompartmentItemNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) {
34+
super(eClass, eReference, colorProvider, descriptionNameGenerator);
35+
}
36+
37+
@Override
38+
public NodeDescription create() {
39+
NodeDescription nodeDescription = super.create();
40+
return nodeDescription;
41+
}
42+
43+
@Override
44+
protected String getDomainType() {
45+
return SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getElement());
46+
}
47+
48+
@Override
49+
protected String getName() {
50+
return super.getName() + COMPARTMENT_ITEM_NAME;
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 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.diagram.common.view.nodes;
14+
15+
import java.util.List;
16+
17+
import org.eclipse.emf.ecore.EClass;
18+
import org.eclipse.emf.ecore.EReference;
19+
import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder;
20+
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
21+
import org.eclipse.sirius.components.view.builder.providers.INodeToolProvider;
22+
import org.eclipse.sirius.components.view.diagram.DiagramDescription;
23+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
24+
import org.eclipse.syson.diagram.common.view.tools.AssumeConstraintNodeToolProvider;
25+
import org.eclipse.syson.util.IDescriptionNameGenerator;
26+
27+
/**
28+
* Compartment node allowing to display {@link org.eclipse.syson.sysml.ConstraintUsage} owned by a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#ASSUMPTION}.
29+
*
30+
* @author gcoutable
31+
*/
32+
public class AssumeConstraintCompartmentNodeDescription extends AbstractCompartmentNodeDescriptionProvider {
33+
34+
public static final String COMPARTMENT_NAME = " assume";
35+
36+
public AssumeConstraintCompartmentNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) {
37+
super(eClass, eReference, colorProvider, descriptionNameGenerator);
38+
}
39+
40+
@Override
41+
protected String getCompartmentName() {
42+
return this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + COMPARTMENT_NAME;
43+
}
44+
@Override
45+
protected String getCustomCompartmentLabel() {
46+
return "assume constraints";
47+
}
48+
49+
@Override
50+
public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) {
51+
cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + COMPARTMENT_NAME).ifPresent(nodeDescription -> {
52+
cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentItemName(this.eClass, this.eReference) + AssumeConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME)
53+
.ifPresent(itemNodeDescription -> nodeDescription.getChildrenDescriptions().add(itemNodeDescription));
54+
nodeDescription.setPalette(this.createCompartmentPalette(cache));
55+
});
56+
}
57+
58+
@Override
59+
protected List<INodeToolProvider> getItemCreationToolProviders() {
60+
return List.of(new AssumeConstraintNodeToolProvider());
61+
}
62+
63+
@Override
64+
protected List<NodeDescription> getDroppableNodes(IViewDiagramElementFinder cache) {
65+
return List.of();
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 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.diagram.common.view.nodes;
14+
15+
import org.eclipse.emf.ecore.EClass;
16+
import org.eclipse.emf.ecore.EReference;
17+
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
18+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
19+
import org.eclipse.syson.sysml.SysmlPackage;
20+
import org.eclipse.syson.util.IDescriptionNameGenerator;
21+
import org.eclipse.syson.util.SysMLMetamodelHelper;
22+
23+
/**
24+
* Used to create a {@link org.eclipse.syson.sysml.ConstraintUsage} compartment item node description.
25+
* <p>
26+
* {@link org.eclipse.syson.sysml.ConstraintUsage} compartment items have to be contained in a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#REQUIREMENT}.
27+
* </p>
28+
* @author gcoutable
29+
*/
30+
public class RequireConstraintCompartmentItemNodeDescription extends CompartmentItemNodeDescriptionProvider {
31+
public static final String COMPARTMENT_ITEM_NAME = " require constraint";
32+
33+
public RequireConstraintCompartmentItemNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) {
34+
super(eClass, eReference, colorProvider, descriptionNameGenerator);
35+
}
36+
37+
@Override
38+
public NodeDescription create() {
39+
NodeDescription nodeDescription = super.create();
40+
return nodeDescription;
41+
}
42+
43+
@Override
44+
protected String getDomainType() {
45+
return SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getElement());
46+
}
47+
48+
@Override
49+
protected String getName() {
50+
return super.getName() + COMPARTMENT_ITEM_NAME;
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 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.diagram.common.view.nodes;
14+
15+
import java.util.List;
16+
17+
import org.eclipse.emf.ecore.EClass;
18+
import org.eclipse.emf.ecore.EReference;
19+
import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder;
20+
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
21+
import org.eclipse.sirius.components.view.builder.providers.INodeToolProvider;
22+
import org.eclipse.sirius.components.view.diagram.DiagramDescription;
23+
import org.eclipse.sirius.components.view.diagram.NodeDescription;
24+
import org.eclipse.syson.diagram.common.view.tools.RequireConstraintNodeToolProvider;
25+
import org.eclipse.syson.util.IDescriptionNameGenerator;
26+
27+
/**
28+
* Compartment node allowing to display {@link org.eclipse.syson.sysml.ConstraintUsage} owned by a {@link org.eclipse.syson.sysml.RequirementConstraintMembership} with {@link org.eclipse.syson.sysml.RequirementConstraintKind#REQUIREMENT}.
29+
*
30+
* @author gcoutable
31+
*/
32+
public class RequireConstraintCompartmentNodeDescription extends AbstractCompartmentNodeDescriptionProvider {
33+
34+
public static final String COMPARTMENT_NAME = " require";
35+
36+
public RequireConstraintCompartmentNodeDescription(EClass eClass, EReference eReference, IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) {
37+
super(eClass, eReference, colorProvider, descriptionNameGenerator);
38+
}
39+
40+
@Override
41+
protected String getCompartmentName() {
42+
return this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + COMPARTMENT_NAME;
43+
}
44+
@Override
45+
protected String getCustomCompartmentLabel() {
46+
return "require constraints";
47+
}
48+
49+
@Override
50+
public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) {
51+
cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentName(this.eClass, this.eReference) + COMPARTMENT_NAME).ifPresent(nodeDescription -> {
52+
cache.getNodeDescription(this.getDescriptionNameGenerator().getCompartmentItemName(this.eClass, this.eReference) + RequireConstraintCompartmentItemNodeDescription.COMPARTMENT_ITEM_NAME)
53+
.ifPresent(itemNodeDescription -> nodeDescription.getChildrenDescriptions().add(itemNodeDescription));
54+
nodeDescription.setPalette(this.createCompartmentPalette(cache));
55+
});
56+
}
57+
58+
@Override
59+
protected List<INodeToolProvider> getItemCreationToolProviders() {
60+
return List.of(new RequireConstraintNodeToolProvider());
61+
}
62+
63+
@Override
64+
protected List<NodeDescription> getDroppableNodes(IViewDiagramElementFinder cache) {
65+
return List.of();
66+
}
67+
}

backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,34 @@ public List<? extends Object> getConcernReferenceSelectionDialogChildren(Object
626626
return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getConcernUsage()));
627627
}
628628

629+
/**
630+
* Provides the root elements in the tree of the selection dialog for presenting all existing ConstraintUsage.
631+
*
632+
* @param editingContext
633+
* the (non-{@code null}) {@link IEditingContext}.
634+
* @return the (non-{@code null}) {@link List} of all {@link Resource} and {@link ISysONExplorerFragment} that
635+
* contain at least one {@link org.eclipse.syson.sysml.ConstraintUsage}.
636+
*/
637+
public List<Object> getConstraintReferenceSelectionDialogElements(IEditingContext editingContext) {
638+
return this.getAllResourcesWithInstancesOf(editingContext, List.of(SysmlPackage.eINSTANCE.getConstraintUsage()));
639+
}
640+
641+
/**
642+
* Provides the children of element in the tree of the selection dialog for presenting all existing ConstraiNtUsage.
643+
*
644+
* @param selectionDialogTreeElement
645+
* a (non-{@code null}) selection dialog tree element.
646+
* @param editingContext
647+
* the (non-{@code null}) {@link IEditingContext}.
648+
* @param expandedIds
649+
* the list of already expanded treeItems, by their Ids.
650+
* @return the (non-{@code null}) {@link List} of all children that contain (possibly indirectly) an
651+
* {@link org.eclipse.syson.sysml.ConstraintUsage}.
652+
*/
653+
public List<? extends Object> getConstraintReferenceSelectionDialogChildren(Object selectionDialogTreeElement, IEditingContext editingContext, List<String> expandedIds) {
654+
return this.getChildrenWithInstancesOf(selectionDialogTreeElement, editingContext, expandedIds, List.of(SysmlPackage.eINSTANCE.getConstraintUsage()));
655+
}
656+
629657

630658

631659
/**

0 commit comments

Comments
 (0)