Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ The cache holding standard libraries can be invalidated for a specific test meth
- https://github.com/eclipse-syson/syson/issues/2154[#2154] [diagrams] Improve the _Duplicate Element_ diagram tool to support multi-selection in standard diagrams.
- https://github.com/eclipse-syson/syson/issues/2160[#2160] [diagrams] Improve the _View As_ diagram tool on graphical nodes to support multi-selection in standard diagrams.
- https://github.com/eclipse-syson/syson/issues/2148[#2148] [diagrams] Merge the two perform action creation tools into a single tool, leveraging the updated selection dialog.
- https://github.com/eclipse-syson/syson/issues/2152[#2152] [diagrams] Leverage the latest selection dialog changes to allow creating a sub action with and without associating the sub action with another `ActionUsage`.

=== New features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
* @author pcdavid
*/
@Transactional
@GivenSysONServer({ GeneralViewEmptyTestProjectData.SCRIPT_PATH })
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GVStateDoActionWithReferencedActionTests extends AbstractIntegrationTests {

Expand All @@ -84,8 +85,7 @@ private Flux<DiagramRefreshedEventPayload> givenSubscriptionToDiagram() {
var diagramEventInput = new DiagramEventInput(UUID.randomUUID(),
GeneralViewEmptyTestProjectData.EDITING_CONTEXT,
GeneralViewEmptyTestProjectData.GraphicalIds.DIAGRAM_ID);
var flux = this.givenDiagramSubscription.subscribe(diagramEventInput);
return flux;
return this.givenDiagramSubscription.subscribe(diagramEventInput);
}

@BeforeEach
Expand All @@ -94,7 +94,6 @@ public void beforeEach() {
}

@DisplayName("GIVEN a General View with a state and action, WHEN invoking do action with referenced action, THEN the PerformActionUsage is visible in the state")
@GivenSysONServer({ GeneralViewEmptyTestProjectData.SCRIPT_PATH })
@Test
public void checkPerformActionRevealInState() {
var flux = this.givenSubscriptionToDiagram();
Expand All @@ -107,19 +106,17 @@ public void checkPerformActionRevealInState() {
assertThat(newStateToolId).as("The tool 'New State' should exist on the diagram").isNotNull();
var newActionToolId = diagramDescriptionIdProvider.getDiagramCreationToolId("New Action");
assertThat(newActionToolId).as("The tool 'New Action' should exist on the diagram").isNotNull();
var newDoActionWithReferencedActionToolId = diagramDescriptionIdProvider.getNodeToolId(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getStateUsage()),
"New Do Action with referenced Action");
assertThat(newDoActionWithReferencedActionToolId).as("The tool 'New Do Action with referenced Action' should exist on State").isNotNull();
var newDoActionToolId = diagramDescriptionIdProvider.getNodeToolId(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getStateUsage()),
"New Do Action");
assertThat(newDoActionToolId).as("The tool 'New Do Action' should exist on State").isNotNull();

var diagramReference = new AtomicReference<Diagram>(null);
var stateNodeId = new AtomicReference<String>(null);
var actionId = new AtomicReference<String>(null);

Consumer<DiagramRefreshedEventPayload> initialDiagramContentConsumer = payload -> Optional.of(payload)
.map(DiagramRefreshedEventPayload::diagram)
.ifPresentOrElse(diagram -> {
diagramReference.set(diagram);
}, () -> fail("Missing diagram"));
.ifPresentOrElse(diagramReference::set, () -> fail("Missing diagram"));

Runnable createState = () -> this.toolTester.invokeTool(GeneralViewEmptyTestProjectData.EDITING_CONTEXT, diagramReference, newStateToolId);

Expand All @@ -128,9 +125,9 @@ public void checkPerformActionRevealInState() {
.ifPresentOrElse(diagram -> {
assertThat(diagram.getNodes()).hasSize(1);
diagram.getNodes().stream()
.filter(node -> node.getTargetObjectLabel().equals("state1"))
.filter(node -> node.getDescriptionId().equals(diagramDescriptionIdProvider.getNodeDescriptionId(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getStateUsage()))))
.findFirst()
.ifPresentOrElse(node -> stateNodeId.set(node.getId()), () -> fail("Node 'state1' not found"));
.ifPresentOrElse(node -> stateNodeId.set(node.getId()), () -> fail("Node state not found"));
}, () -> fail("Missing diagram"));

Runnable createAction = () -> this.toolTester.invokeTool(GeneralViewEmptyTestProjectData.EDITING_CONTEXT, diagramReference, newActionToolId);
Expand All @@ -140,13 +137,13 @@ public void checkPerformActionRevealInState() {
.ifPresentOrElse(diagram -> {
assertThat(diagram.getNodes()).hasSize(2);
diagram.getNodes().stream()
.filter(node -> node.getTargetObjectLabel().equals("action1"))
.filter(node -> node.getDescriptionId().equals(diagramDescriptionIdProvider.getNodeDescriptionId(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getActionUsage()))))
.findFirst()
.ifPresentOrElse(node -> actionId.set(node.getTargetObjectId()), () -> fail("Node 'action1' not found"));
.ifPresentOrElse(node -> actionId.set(node.getTargetObjectId()), () -> fail("Node action not found"));
}, () -> fail("Missing diagram"));

Runnable createDoActionWithReference = () -> {
this.toolTester.invokeTool(GeneralViewEmptyTestProjectData.EDITING_CONTEXT, diagramReference.get().getId(), stateNodeId.get(), newDoActionWithReferencedActionToolId,
this.toolTester.invokeTool(GeneralViewEmptyTestProjectData.EDITING_CONTEXT, diagramReference.get().getId(), stateNodeId.get(), newDoActionToolId,
List.of(new ToolVariable("selectedObject", actionId.get(), ToolVariableType.OBJECT_ID)));
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import static org.eclipse.sirius.components.diagrams.tests.DiagramEventPayloadConsumer.assertRefreshedDiagramThat;

import java.time.Duration;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
Expand All @@ -27,8 +26,6 @@
import org.eclipse.emf.ecore.EReference;
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput;
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload;
import org.eclipse.sirius.components.collaborative.diagrams.dto.ToolVariable;
import org.eclipse.sirius.components.collaborative.diagrams.dto.ToolVariableType;
import org.eclipse.sirius.components.core.api.IIdentityService;
import org.eclipse.sirius.components.core.api.IObjectSearchService;
import org.eclipse.sirius.components.diagrams.Diagram;
Expand Down Expand Up @@ -66,7 +63,6 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import jakarta.validation.constraints.NotNull;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;

Expand Down Expand Up @@ -200,37 +196,31 @@ public void setUp() {
@MethodSource("stateSubactionsParameters")
public void createStateUsageSubactionNode(StateSubactionKind kind) {
String toolName = "New " + StringUtils.capitalize(kind.getName()) + " Action";

this.createStateSubactionNode(kind, SysmlPackage.eINSTANCE.getStateUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_USAGE_ID, toolName);
}

@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
@ParameterizedTest
@MethodSource("stateSubactionsParameters")
public void createStateUsageSubactionWithReferencedActionNode(StateSubactionKind kind) {
String toolName = "New " + StringUtils.capitalize(kind.getName()) + " Action with referenced Action";
var params = List.of(new ToolVariable("selectedObject", GeneralViewWithTopNodesTestProjectData.SemanticIds.ACTION_USAGE_ID, ToolVariableType.OBJECT_ID));

this.createStateSubactionWithReferencedActionNode(kind, SysmlPackage.eINSTANCE.getStateUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_USAGE_ID, toolName, params);
String toolName = "New " + StringUtils.capitalize(kind.getName()) + " Action";
this.createStateSubactionWithReferencedActionNode(kind, SysmlPackage.eINSTANCE.getStateUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_USAGE_ID, toolName, GeneralViewWithTopNodesTestProjectData.SemanticIds.ACTION_USAGE_ID);
}

@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
@ParameterizedTest
@MethodSource("stateSubactionsParameters")
public void createStateDefinitionSubactionNode(StateSubactionKind kind) {
String toolName = "New " + StringUtils.capitalize(kind.getName()) + " Action";

this.createStateSubactionNode(kind, SysmlPackage.eINSTANCE.getStateDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_DEFINITION_ID, toolName);
}

@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
@ParameterizedTest
@MethodSource("stateSubactionsParameters")
public void createStateDefinitionSubactionWithReferencedActionNode(StateSubactionKind kind) {
String toolName = "New " + StringUtils.capitalize(kind.getName()) + " Action with referenced Action";
var params = List.of(new ToolVariable("selectedObject", GeneralViewWithTopNodesTestProjectData.SemanticIds.ACTION_USAGE_ID, ToolVariableType.OBJECT_ID));

this.createStateSubactionWithReferencedActionNode(kind, SysmlPackage.eINSTANCE.getStateDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_DEFINITION_ID, toolName, params);
String toolName = "New " + StringUtils.capitalize(kind.getName()) + " Action";
this.createStateSubactionWithReferencedActionNode(kind, SysmlPackage.eINSTANCE.getStateDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.STATE_DEFINITION_ID, toolName, GeneralViewWithTopNodesTestProjectData.SemanticIds.ACTION_USAGE_ID);
}

private void createStateSubactionNode(StateSubactionKind kind, EClass parentEClass, String targetObjectId, String toolName) {
Expand All @@ -243,7 +233,7 @@ private void createStateSubactionNode(StateSubactionKind kind, EClass parentECla
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);

Runnable createNodeRunnable = this.creationTestsService.createNode(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, toolName);
Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithoutSelectionProvided(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, toolName);

String[] subActionId = new String[1];
Consumer<Object> diagramCheck = assertRefreshedDiagramThat(newDiagram -> {
Expand Down Expand Up @@ -276,7 +266,7 @@ private void createStateSubactionNode(StateSubactionKind kind, EClass parentECla
.verify(Duration.ofSeconds(10));
}

private void createStateSubactionWithReferencedActionNode(StateSubactionKind kind, EClass parentEClass, String targetObjectId, String toolName, List<@NotNull ToolVariable> params) {
private void createStateSubactionWithReferencedActionNode(StateSubactionKind kind, EClass parentEClass, String targetObjectId, String toolName, String selectedObject) {
var flux = this.givenSubscriptionToDiagram();

AtomicReference<Diagram> diagram = new AtomicReference<>();
Expand All @@ -286,7 +276,7 @@ private void createStateSubactionWithReferencedActionNode(StateSubactionKind kin
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);

Runnable createNodeRunnable = this.creationTestsService.createNode(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, toolName, params);
Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithSingleSelection(diagramDescriptionIdProvider, diagram, parentEClass, targetObjectId, toolName, selectedObject);

String[] subActionId = new String[1];
Consumer<Object> diagramCheck = assertRefreshedDiagramThat(newDiagram -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

package org.eclipse.syson.diagram.common.view.tools;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext;
import org.eclipse.sirius.components.core.api.IEditingContext;
Expand All @@ -29,9 +31,11 @@
import org.eclipse.syson.diagram.common.view.services.ViewToolService;
import org.eclipse.syson.diagram.services.aql.DiagramMutationAQLService;
import org.eclipse.syson.sysml.StateSubactionKind;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.AQLConstants;
import org.eclipse.syson.util.AQLUtils;
import org.eclipse.syson.util.ServiceMethod;
import org.eclipse.syson.util.SysMLMetamodelHelper;

/**
* Node Tool of StateUsage and StateDefinition to create StateSubaction child elements.
Expand All @@ -46,63 +50,60 @@ public class StateSubactionNodeToolProvider implements INodeToolProvider {

private final StateSubactionKind kind;

private final boolean isReferencing;

public StateSubactionNodeToolProvider(StateSubactionKind kind, boolean isReferencing) {
this.kind = kind;
this.isReferencing = isReferencing;
public StateSubactionNodeToolProvider(StateSubactionKind kind) {
this.kind = Objects.requireNonNull(kind);
}

@Override
public NodeTool create(IViewDiagramElementFinder cache) {

var tool = this.diagramBuilderHelper.newNodeTool()
return this.diagramBuilderHelper.newNodeTool()
.name(this.getNodeToolLabel())
.iconURLsExpression("/icons/full/obj16/PerformActionUsage.svg")
.body(this.getCreateSubactionOperation())
.preconditionExpression(ServiceMethod.of1(ViewCreateService::isEmptyOfActionKindCompartment).aqlSelf(AQLUtils.aqlString(this.kind.getLiteral())));

if (this.isReferencing) {
tool.dialogDescription(this.getExistingActionSelectionDialog());
}

return tool.build();
.preconditionExpression(ServiceMethod.of1(ViewCreateService::isEmptyOfActionKindCompartment).aqlSelf(AQLUtils.aqlString(this.kind.getLiteral())))
.dialogDescription(this.getExistingActionSelectionDialog())
.build();
}

private String getNodeToolLabel() {
String result = "New " + StringUtils.capitalize(this.kind.getName()) + " Action";
if (this.isReferencing) {
result += " with referenced Action";
}
return result;
return "New " + StringUtils.capitalize(this.kind.getName()) + " Action";
}

private ChangeContext getCreateSubactionOperation() {
var revealOperation = this.viewBuilderHelper.newChangeContext()
.expression(ServiceMethod.of4(DiagramMutationAQLService::revealCompartment).aql(Node.SELECTED_NODE, AQLConstants.SELF, DiagramContext.DIAGRAM_CONTEXT, IEditingContext.EDITING_CONTEXT,
ViewDiagramDescriptionConverter.CONVERTED_NODES_VARIABLE));

var performedAction = "selectedObject";
if (!this.isReferencing) {
performedAction = "null";
}
return this.viewBuilderHelper.newChangeContext()
.expression(ServiceMethod.of2(ViewCreateService::createStateSubaction).aqlSelf(performedAction, AQLUtils.aqlString(this.kind.getLiteral())))
.expression(ServiceMethod.of2(ViewCreateService::createStateSubaction).aqlSelf("selectedObject", AQLUtils.aqlString(this.kind.getLiteral())))
.children(revealOperation.build())
.build();
}

private DialogDescription getExistingActionSelectionDialog() {
String actionUsageType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getActionUsage());

var selectionDialogTree = this.diagramBuilderHelper.newSelectionDialogTreeDescription()
.isSelectableExpression(AQLConstants.AQL_SELF + ".oclIsKindOf(" + actionUsageType + ")")
.elementsExpression(ServiceMethod.of0(ViewToolService::getActionReferenceSelectionDialogElements).aql(IEditingContext.EDITING_CONTEXT))
.childrenExpression(ServiceMethod.of0(ViewToolService::getActionReferenceSelectionDialogChildren).aqlSelf())
.build();

var actionKind = StringUtils.capitalize(this.kind.getName());
var selectExistingActionUsage = this.diagramBuilderHelper.newSelectionDialogDescription()
.selectionDialogTreeDescription(selectionDialogTree)
.defaultTitleExpression(this.getNodeToolLabel())
.descriptionExpression("Select an existing Action to associate to the " + StringUtils.capitalize(this.kind.getName()) + " action you want to create:")
.optional(false);
.noSelectionTitleExpression(this.getNodeToolLabel())
.withSelectionTitleExpression(this.getNodeToolLabel())
.descriptionExpression("Create a " + actionKind + " Action:")
.noSelectionActionLabelExpression("Create a new " + actionKind + " Action")
.noSelectionActionDescriptionExpression("Create a new " + actionKind + " Action without reference to an existing Action")
.withSelectionActionLabelExpression("Select an existing Action referenced by the " + actionKind + " Action you want to create")
.withSelectionActionDescriptionExpression("Create a new " + actionKind + " Action referencing the selected Action")
.noSelectionActionStatusMessageExpression("It will create a new " + actionKind + " Action without reference to an existing Action")
.selectionRequiredWithoutSelectionStatusMessageExpression("Select an Action referenced by the new " + actionKind + " Action")
.selectionRequiredWithSelectionStatusMessageExpression(AQLConstants.AQL + "'It will create a " + actionKind + " Action referencing ' + selectedObjects->first().name")
.optional(true);

return selectExistingActionUsage.build();
}
Expand Down
Loading
Loading