Skip to content

Commit

Permalink
[269] Handle standard done action in both AFV and GV diagrams
Browse files Browse the repository at this point in the history
Bug: eclipse-syson#269
Signed-off-by: Jerome Gout <jerome.gout@obeosoft.com>
  • Loading branch information
jerome-obeo authored and AxelRICHARD committed Jun 4, 2024
1 parent 50e50e3 commit 5a99cc1
Show file tree
Hide file tree
Showing 19 changed files with 279 additions and 6 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
- https://github.com/eclipse-syson/syson/issues/298[#298] [syson] Add root Namespace to SysON models and libraries
- https://github.com/eclipse-syson/syson/issues/324[#324] [diagrams] Improve support for whitespaces, quotes, and special characters in direct edit
- https://github.com/eclipse-syson/syson/issues/307[#307] [diagrams] Fix parallel states tooling conditions
- https://github.com/eclipse-syson/syson/issues/269[#269] [diagrams] Handle action start and done nodes in Action Flow View & General View diagrams
- https://github.com/eclipse-syson/syson/issues/269[#269] [diagrams] Handle start and done actions in Action Flow View & General View diagrams
- https://github.com/eclipse-syson/syson/issues/344[#344] [metamodel] Improve implementation of getName and getShortName

=== New features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,18 @@ public ActionUsage retrieveStandardStartAction(Element eObject) {
return this.findByName(eObject, "Actions::Action::start");
}

/**
* Retrieve the done action defined inside the standard library <code>Actions</code>.
*
* @param eObject
* an object to access to the library resources.
*
* @return the standard done ActionUsage defined in the <code>Actions</code> library.
*/
public ActionUsage retrieveStandardDoneAction(Element eObject) {
return this.findByName(eObject, "Actions::Action::done");
}

/**
* Check if the given element is actually the standard start action defined by <code>Actions::Action::start</code>.
*
Expand All @@ -400,4 +412,22 @@ public boolean isStandardStartAction(Element element) {
}
return false;
}

/**
* Check if the given element is actually the standard done action defined by <code>Actions::Action::done</code>.
*
* @param element
* an element that could be the standard done action.
* @return <code>true</code> if the given element is the standard done action and <code>false</code> otherwise.
*/
public boolean isStandardDoneAction(Element element) {
var elt = element;
if (element instanceof Membership membership) {
elt = membership.getMemberElement();
}
if (elt instanceof ActionUsage au) {
return "0cdc3cd3-b06c-5c32-beda-0cf4ba164a64".equals(au.getElementId());
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.eclipse.syson.diagram.common.view.diagram.AbstractDiagramDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.ActionFlowCompartmentNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.CompartmentItemNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.DoneActionNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.tools.ToolSectionDescription;
import org.eclipse.syson.sysml.SysmlPackage;
Expand Down Expand Up @@ -118,6 +119,7 @@ public RepresentationDescription create(IColorProvider colorProvider) {
diagramElementDescriptionProviders.add(new ActionFlowViewEmptyDiagramNodeDescriptionProvider(colorProvider));
diagramElementDescriptionProviders.add(new PackageNodeDescriptionProvider(colorProvider));
diagramElementDescriptionProviders.add(new StartActionNodeDescriptionProvider(colorProvider, this.getNameGenerator()));
diagramElementDescriptionProviders.add(new DoneActionNodeDescriptionProvider(colorProvider, this.getNameGenerator()));

DEFINITIONS.forEach(definition -> {
diagramElementDescriptionProviders.add(new DefinitionNodeDescriptionProvider(definition, colorProvider));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.syson.diagram.actionflow.view.AFVDescriptionNameGenerator;
import org.eclipse.syson.diagram.actionflow.view.ActionFlowViewDiagramDescriptionProvider;
import org.eclipse.syson.diagram.common.view.edges.AbstractSuccessionEdgeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.DoneActionNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider;

/**
Expand Down Expand Up @@ -54,6 +55,9 @@ protected List<NodeDescription> getSourceNodes(IViewDiagramElementFinder cache)

@Override
protected List<NodeDescription> getTargetNodes(IViewDiagramElementFinder cache) {
return this.getAllUsages(cache);
var targets = this.getAllUsages(cache);
// the done node can be the target of a succession
cache.getNodeDescription(this.nameGenerator.getNodeName(DoneActionNodeDescriptionProvider.DONE_ACTION_NAME)).ifPresent(targets::add);
return targets;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.eclipse.syson.diagram.actionflow.view.ActionFlowViewDiagramDescriptionProvider;
import org.eclipse.syson.diagram.actionflow.view.services.ActionFlowViewNodeToolSectionSwitch;
import org.eclipse.syson.diagram.common.view.nodes.AbstractDefinitionNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.DoneActionNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider;
import org.eclipse.syson.sysml.SysmlPackage;

/**
Expand Down Expand Up @@ -61,6 +63,8 @@ protected List<NodeDescription> getAllNodeDescriptions(IViewDiagramElementFinder
ActionFlowViewDiagramDescriptionProvider.DEFINITIONS.forEach(definition -> cache.getNodeDescription(this.nameGenerator.getNodeName(definition)).ifPresent(allNodes::add));
ActionFlowViewDiagramDescriptionProvider.USAGES.forEach(usage -> cache.getNodeDescription(this.nameGenerator.getNodeName(usage)).ifPresent(allNodes::add));
cache.getNodeDescription(this.nameGenerator.getNodeName(SysmlPackage.eINSTANCE.getPackage())).ifPresent(allNodes::add);
cache.getNodeDescription(this.nameGenerator.getNodeName(StartActionNodeDescriptionProvider.START_ACTION_NAME)).ifPresent(allNodes::add);
cache.getNodeDescription(this.nameGenerator.getNodeName(DoneActionNodeDescriptionProvider.DONE_ACTION_NAME)).ifPresent(allNodes::add);
return allNodes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.eclipse.syson.diagram.actionflow.view.ActionFlowViewDiagramDescriptionProvider;
import org.eclipse.syson.diagram.actionflow.view.services.ActionFlowViewNodeToolSectionSwitch;
import org.eclipse.syson.diagram.common.view.nodes.AbstractUsageNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.DoneActionNodeDescriptionProvider;
import org.eclipse.syson.diagram.common.view.nodes.StartActionNodeDescriptionProvider;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.IDescriptionNameGenerator;

Expand Down Expand Up @@ -61,6 +63,8 @@ protected List<NodeDescription> getAllNodeDescriptions(IViewDiagramElementFinder
ActionFlowViewDiagramDescriptionProvider.DEFINITIONS.forEach(definition -> cache.getNodeDescription(this.nameGenerator.getNodeName(definition)).ifPresent(allNodes::add));
ActionFlowViewDiagramDescriptionProvider.USAGES.forEach(usage -> cache.getNodeDescription(this.nameGenerator.getNodeName(usage)).ifPresent(allNodes::add));
cache.getNodeDescription(this.nameGenerator.getNodeName(SysmlPackage.eINSTANCE.getPackage())).ifPresent(allNodes::add);
cache.getNodeDescription(this.nameGenerator.getNodeName(StartActionNodeDescriptionProvider.START_ACTION_NAME)).ifPresent(allNodes::add);
cache.getNodeDescription(this.nameGenerator.getNodeName(DoneActionNodeDescriptionProvider.DONE_ACTION_NAME)).ifPresent(allNodes::add);
return allNodes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.syson.diagram.common.view.tools.AcceptActionPortUsageReceiverToolNodeProvider;
import org.eclipse.syson.diagram.common.view.tools.ActionFlowCompartmentNodeToolProvider;
import org.eclipse.syson.diagram.common.view.tools.CompartmentNodeToolProvider;
import org.eclipse.syson.diagram.common.view.tools.DoneActionNodeToolProvider;
import org.eclipse.syson.diagram.common.view.tools.StartActionNodeToolProvider;
import org.eclipse.syson.sysml.AcceptActionUsage;
import org.eclipse.syson.sysml.ActionDefinition;
Expand Down Expand Up @@ -81,6 +82,7 @@ public List<NodeToolSection> caseAcceptActionUsage(AcceptActionUsage object) {
@Override
public List<NodeToolSection> caseActionUsage(ActionUsage object) {
var createSection = this.buildCreateSection(new StartActionNodeToolProvider(SysmlPackage.eINSTANCE.getActionUsage(), this.descriptionNameGenerator).create(this.cache));
createSection.getNodeTools().add(new DoneActionNodeToolProvider(SysmlPackage.eINSTANCE.getActionUsage(), this.descriptionNameGenerator).create(this.cache));
createSection.getNodeTools().add(new CompartmentNodeToolProvider(SysmlPackage.eINSTANCE.getUsage_NestedItem(), this.descriptionNameGenerator).create(this.cache));
createSection.getNodeTools().add(new ActionFlowCompartmentNodeToolProvider(SysmlPackage.eINSTANCE.getActionUsage(), this.descriptionNameGenerator).create(this.cache));
return List.of(createSection, this.addElementsToolSection());
Expand All @@ -89,6 +91,7 @@ public List<NodeToolSection> caseActionUsage(ActionUsage object) {
@Override
public List<NodeToolSection> caseActionDefinition(ActionDefinition object) {
var createSection = this.buildCreateSection(new StartActionNodeToolProvider(SysmlPackage.eINSTANCE.getActionDefinition(), this.descriptionNameGenerator).create(this.cache));
createSection.getNodeTools().add(new DoneActionNodeToolProvider(SysmlPackage.eINSTANCE.getActionDefinition(), this.descriptionNameGenerator).create(this.cache));
createSection.getNodeTools().add(new ActionFlowCompartmentNodeToolProvider(SysmlPackage.eINSTANCE.getActionDefinition(), this.descriptionNameGenerator).create(this.cache));
return List.of(createSection, this.addElementsToolSection());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.sirius.components.view.diagram.NodeToolSection;
import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy;
import org.eclipse.syson.diagram.common.view.tools.ActionFlowCompartmentNodeToolProvider;
import org.eclipse.syson.diagram.common.view.tools.DoneActionNodeToolProvider;
import org.eclipse.syson.diagram.common.view.tools.StartActionNodeToolProvider;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.AQLConstants;
Expand Down Expand Up @@ -75,6 +76,7 @@ public NodeDescription create() {
public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) {
cache.getNodeDescription(this.name).ifPresent(nodeDescription -> {
cache.getNodeDescription(this.descriptionNameGenerator.getNodeName(StartActionNodeDescriptionProvider.START_ACTION_NAME)).ifPresent(nodeDescription.getReusedChildNodeDescriptions()::add);
cache.getNodeDescription(this.descriptionNameGenerator.getNodeName(DoneActionNodeDescriptionProvider.DONE_ACTION_NAME)).ifPresent(nodeDescription.getReusedChildNodeDescriptions()::add);
cache.getNodeDescription(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getActionUsage())).ifPresent(nodeDescription.getReusedChildNodeDescriptions()::add);
nodeDescription.setPalette(this.createCompartmentPalette(cache));
});
Expand All @@ -99,6 +101,7 @@ private NodeToolSection createCreationToolSection(IViewDiagramElementFinder cach
nodeToolSection.getNodeTools().add(compartmentNodeToolProvider.create(cache));
}
nodeToolSection.getNodeTools().add(new StartActionNodeToolProvider(this.eClass, this.descriptionNameGenerator).create(cache));
nodeToolSection.getNodeTools().add(new DoneActionNodeToolProvider(this.eClass, this.descriptionNameGenerator).create(cache));
return nodeToolSection;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.syson.diagram.common.view.nodes;

import java.util.Objects;

import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder;
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
import org.eclipse.sirius.components.view.diagram.DiagramDescription;
import org.eclipse.sirius.components.view.diagram.NodeDescription;
import org.eclipse.sirius.components.view.diagram.NodePalette;
import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.AQLUtils;
import org.eclipse.syson.util.IDescriptionNameGenerator;
import org.eclipse.syson.util.SysMLMetamodelHelper;

/**
* Used to create the ending node description of an Action.
*
* @author Jerome Gout
*/
public class DoneActionNodeDescriptionProvider extends AbstractNodeDescriptionProvider {

public static final String DONE_ACTION_NAME = "DoneAction";

private final IDescriptionNameGenerator descriptionNameGenerator;

public DoneActionNodeDescriptionProvider(IColorProvider colorProvider, IDescriptionNameGenerator descriptionNameGenerator) {
super(colorProvider);
this.descriptionNameGenerator = Objects.requireNonNull(descriptionNameGenerator);
}

@Override
public NodeDescription create() {
String domainType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getMembership());
return this.diagramBuilderHelper.newNodeDescription()
.collapsible(false)
.domainType(domainType)
.defaultWidthExpression("36")
.defaultHeightExpression("36")
.name(this.descriptionNameGenerator.getNodeName(DONE_ACTION_NAME))
.semanticCandidatesExpression(AQLUtils.getSelfServiceCallExpression("getStandardDoneAction"))
.style(this.createImageNodeStyleDescription("images/done_action.svg"))
.userResizable(false)
.synchronizationPolicy(SynchronizationPolicy.UNSYNCHRONIZED)
.build();
}

@Override
public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) {
cache.getNodeDescription(this.descriptionNameGenerator.getNodeName(DONE_ACTION_NAME)).ifPresent(nodeDescription -> {
nodeDescription.setPalette(this.createNodePalette());
diagramDescription.getNodeDescriptions().add(nodeDescription);
});
}

private NodePalette createNodePalette() {
var changeContext = this.viewBuilderHelper.newChangeContext()
.expression(AQLUtils.getSelfServiceCallExpression("deleteFromModel"));

var deleteTool = this.diagramBuilderHelper.newDeleteTool()
.name("Remove Done")
.body(changeContext.build());

return this.diagramBuilderHelper.newNodePalette()
.deleteTool(deleteTool.build())
.toolSections(this.defaultToolsFactory.createDefaultHideRevealNodeToolSection())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,24 @@ public Membership addStartAction(Element ownerElement) {
return null;
}

/**
* Add the standard done action as the child of the given element.
*
* @param ownerElement
* an element that will own the standard done action.
* @return the {@link Membership} element containing the done action in its memberElement feature.
*/
public Membership addDoneAction(Element ownerElement) {
var standardDoneAction = this.utilService.retrieveStandardDoneAction(ownerElement);
if (standardDoneAction != null) {
var membership = SysmlFactory.eINSTANCE.createMembership();
membership.setMemberElement(standardDoneAction);
ownerElement.getOwnedRelationship().add(membership);
return membership;
}
return null;
}

/**
* Create a new action {@link ActionUsage} inside the given element which should be an {@link ActionUsage} or an
* {@link ActionDefintion}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public boolean checkTransitionEdgeTarget(Element source, Element target) {
return false;
}

public Element reconnectSourceSuccessionEdge(Succession succession, ActionUsage oldSource, ActionUsage newSource) {
public Element reconnectSourceSuccessionEdge(Succession succession, Element oldSource, Element newSource) {
succession.getSource().replaceAll(e -> {
if (Objects.equals(e, oldSource)) {
return newSource;
Expand All @@ -200,7 +200,7 @@ public Element reconnectSourceSuccessionEdge(Succession succession, ActionUsage
return succession;
}

public Element reconnectTargetSuccessionEdge(Succession succession, ActionUsage oldTarget, ActionUsage newTarget) {
public Element reconnectTargetSuccessionEdge(Succession succession, Element oldTarget, Element newTarget) {
succession.getTarget().replaceAll(e -> {
if (Objects.equals(e, oldTarget)) {
return newTarget;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.sirius.components.view.builder.generated.ViewBuilders;
import org.eclipse.sirius.components.view.diagram.EdgeTool;
import org.eclipse.sirius.components.view.diagram.NodeDescription;
import org.eclipse.syson.diagram.common.view.nodes.DoneActionNodeDescriptionProvider;
import org.eclipse.syson.sysml.AcceptActionUsage;
import org.eclipse.syson.sysml.ActionUsage;
import org.eclipse.syson.sysml.AllocationUsage;
Expand Down Expand Up @@ -105,7 +106,8 @@ public List<EdgeTool> caseActionUsage(ActionUsage object) {
private List<NodeDescription> getSuccessionEdgeTargets() {
return this.allNodeDescriptions.stream()
.filter(nodeDesc -> this.edgeToolService.isTheNodeDescriptionFor(nodeDesc, SysmlPackage.eINSTANCE.getActionUsage()) ||
this.edgeToolService.isTheNodeDescriptionFor(nodeDesc, SysmlPackage.eINSTANCE.getAcceptActionUsage()))
this.edgeToolService.isTheNodeDescriptionFor(nodeDesc, SysmlPackage.eINSTANCE.getAcceptActionUsage()) ||
this.nameGenerator.getNodeName(DoneActionNodeDescriptionProvider.DONE_ACTION_NAME).equals(nodeDesc.getName()))
.toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,30 @@ public Membership getStandardStartAction(Namespace self) {
}
return null;
}

/**
* Check if a Done Action can be added to the given element.
*
* @param self
* a {@link Namespace} element
* @return <code>true</code> if the Done action can be added to the given element or <code>false</code> otherwise.
*/
public boolean canAddDoneAction(Namespace self) {
// Check that self is an Action usage or definition and that there is not yet the done action displayed.
return this.getStandardDoneAction(self) == null;
}

public Membership getStandardDoneAction(Namespace self) {
if (self instanceof ActionUsage || self instanceof ActionDefinition) {
return self.getOwnedRelationship().stream()
.filter(Membership.class::isInstance)
.map(Membership.class::cast)
.filter(m -> {
return m.getMemberElement() instanceof ActionUsage au && this.utilService.isStandardDoneAction(au);
})
.findFirst()
.orElse(null);
}
return null;
}
}
Loading

0 comments on commit 5a99cc1

Please sign in to comment.