diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c51503887..5d76eb75c 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -113,6 +113,7 @@ The tool now works correctly on packages, and doesn't render sibling elements wh - https://github.com/eclipse-syson/syson/issues/540[#540] [syson] Allow the creation of sub-Packages in the model explorer - https://github.com/eclipse-syson/syson/issues/542[#542] [tests] Enable Action's sub-node creation tests for free form items These tests were de-activated because of an issue in https://github.com/eclipse-syson/syson/issues/542[Sirius Web]. +- https://github.com/eclipse-syson/syson/issues/538[#538] [general-view] Add actions in PartUsage and PartDefinition === New features diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeCreationTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeCreationTests.java index 6cd1e66bf..555ab80e5 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeCreationTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVSubNodeCreationTests.java @@ -174,7 +174,7 @@ private static Stream itemDefinitionChildNodeParameters() { private static Stream itemUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), 3)) .map(TestNameGenerator::namedArguments); } @@ -197,8 +197,8 @@ private static Stream packageChildNodeParameters() { Arguments.of(SysmlPackage.eINSTANCE.getItemDefinition(), ownedMember, 2), // A package doesn't have a compartment: it is handled as a custom node Arguments.of(SysmlPackage.eINSTANCE.getPackage(), ownedMember, 0), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), ownedMember, 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartDefinition(), ownedMember, 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), ownedMember, 5), + Arguments.of(SysmlPackage.eINSTANCE.getPartDefinition(), ownedMember, 5), Arguments.of(SysmlPackage.eINSTANCE.getAllocationUsage(), ownedMember, 2), Arguments.of(SysmlPackage.eINSTANCE.getAllocationDefinition(), ownedMember, 2), Arguments.of(SysmlPackage.eINSTANCE.getInterfaceUsage(), ownedMember, 3), @@ -234,7 +234,7 @@ private static Stream partDefinitionChildNodeParameters() { private static Stream partDefinitionSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 5)) .map(TestNameGenerator::namedArguments); } @@ -249,14 +249,14 @@ private static Stream partUsageChildNodeParameters() { private static Stream partUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedUsage(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedUsage(), 5)) .map(TestNameGenerator::namedArguments); } private static Stream allocationUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedUsage(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedUsage(), 5)) .map(TestNameGenerator::namedArguments); } @@ -270,7 +270,7 @@ private static Stream allocationUsageChildNodeParameters() { private static Stream allocationDefinitionSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 5)) .map(TestNameGenerator::namedArguments); } @@ -283,7 +283,7 @@ private static Stream allocationDefinitionChildNodeParameters() { private static Stream interfaceUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedUsage(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedUsage(), 5)) .map(TestNameGenerator::namedArguments); } @@ -307,7 +307,7 @@ private static Stream interfaceDefinitionChildNodeParameters() { private static Stream portUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3)) .map(TestNameGenerator::namedArguments); } @@ -322,7 +322,7 @@ private static Stream portUsageChildNodeParameters() { private static Stream portDefinitionSiblingNodeParameters() { return Stream.of( - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedItem(), 3)) .map(TestNameGenerator::namedArguments); } @@ -345,7 +345,7 @@ private static Stream acceptActionUsagePayloadParameters() { private static Stream actionUsageSiblingNodeParameters() { return Stream.of( - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getAttributeUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), 3), Arguments.of(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), 3)) .map(TestNameGenerator::namedArguments); @@ -389,7 +389,7 @@ private static Stream constraintUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getAttributeUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), 3), Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), 3)) .map(TestNameGenerator::namedArguments); } @@ -403,7 +403,7 @@ private static Stream constraintUsageChildNodeParameters() { private static Stream constraintDefinitionSiblingNodeParameters() { return Stream.of( - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedUsage(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedUsage(), 5)) .map(TestNameGenerator::namedArguments); } @@ -417,7 +417,7 @@ private static Stream constraintDefinitionChildNodeParameters() { private static Stream requirementUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), 3), Arguments.of(SysmlPackage.eINSTANCE.getRequirementUsage(), SysmlPackage.eINSTANCE.getUsage_NestedRequirement(), 5)) .map(TestNameGenerator::namedArguments); @@ -441,7 +441,7 @@ private static Stream useCaseUsageSiblingNodeParameters() { return Stream.of( Arguments.of(SysmlPackage.eINSTANCE.getAttributeUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), 3), Arguments.of(SysmlPackage.eINSTANCE.getItemUsage(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPart(), 5), Arguments.of(SysmlPackage.eINSTANCE.getPortUsage(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), 3)) .map(TestNameGenerator::namedArguments); } @@ -467,7 +467,7 @@ private static Stream occurrenceUsageChildNodeParameters() { private static Stream occurrenceDefinitionSiblingNodeParameters() { return Stream.of( - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 3)) + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getDefinition_OwnedPart(), 5)) .map(TestNameGenerator::namedArguments); } diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java index e16335646..a628f4a77 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVTopNodeCreationTests.java @@ -116,8 +116,8 @@ private static Stream topNodeParameters() { Arguments.of(SysmlPackage.eINSTANCE.getItemDefinition(), 2), // A package doesn't have a compartment: it is handled as a custom node Arguments.of(SysmlPackage.eINSTANCE.getPackage(), 0), - Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), 3), - Arguments.of(SysmlPackage.eINSTANCE.getPartDefinition(), 3), + Arguments.of(SysmlPackage.eINSTANCE.getPartUsage(), 5), + Arguments.of(SysmlPackage.eINSTANCE.getPartDefinition(), 5), Arguments.of(SysmlPackage.eINSTANCE.getAllocationUsage(), 2), Arguments.of(SysmlPackage.eINSTANCE.getAllocationDefinition(), 2), Arguments.of(SysmlPackage.eINSTANCE.getInterfaceUsage(), 3), diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java index cb5bef938..f2ad82d4b 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractDefinitionOwnedUsageEdgeDescriptionProvider.java @@ -18,6 +18,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramContext; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.ChangeContextBuilder; import org.eclipse.sirius.components.view.builder.providers.IColorProvider; @@ -76,6 +77,8 @@ public EdgeDescription create() { .style(this.createEdgeStyle()) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) .targetNodesExpression(AQLConstants.AQL_SELF + "." + this.eReference.getName()) + .preconditionExpression(AQLConstants.AQL + "not " + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_SOURCE + ".isAncestorOf(" + + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_TARGET + "," + IDiagramContext.DIAGRAM_CONTEXT + ")") .build(); } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java index 5a119b540..3d74e1356 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/edges/AbstractUsageNestedUsageEdgeDescriptionProvider.java @@ -18,6 +18,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EReference; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramContext; import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder; import org.eclipse.sirius.components.view.builder.generated.ChangeContextBuilder; import org.eclipse.sirius.components.view.builder.providers.IColorProvider; @@ -78,6 +79,8 @@ public EdgeDescription create() { .style(this.createEdgeStyle()) .synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED) .targetNodesExpression(AQLConstants.AQL_SELF + "." + this.eReference.getName()) + .preconditionExpression(AQLConstants.AQL + "not " + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_SOURCE + ".isAncestorOf(" + + org.eclipse.sirius.components.diagrams.description.EdgeDescription.GRAPHICAL_EDGE_TARGET + "," + IDiagramContext.DIAGRAM_CONTEXT + ")") .build(); } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java index 8235bdfcf..2da9bac47 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewCreateService.java @@ -479,7 +479,7 @@ private Package getClosestContainingPackageFrom(Element element) { public Element createAcceptAction(Element ownerElement) { Feature acceptSubActionsStdAction = this.utilService.findByName(ownerElement, "Actions::Action::acceptSubactions"); - if (ownerElement instanceof ActionUsage || ownerElement instanceof ActionDefinition && acceptSubActionsStdAction != null) { + if (this.isPart(ownerElement) || this.isAction(ownerElement) && acceptSubActionsStdAction != null) { var featureMember = SysmlFactory.eINSTANCE.createFeatureMembership(); var acceptAction = SysmlFactory.eINSTANCE.createAcceptActionUsage(); this.elementInitializerSwitch.doSwitch(acceptAction); @@ -770,7 +770,7 @@ public Element removeStartAction(Node selectedNode, IEditingContext editingConte */ public Element createJoinAction(Element ownerElement) { Feature joinsStdAction = this.utilService.findByName(ownerElement, "Actions::Action::joins"); - if (ownerElement instanceof ActionUsage || ownerElement instanceof ActionDefinition && joinsStdAction != null) { + if (this.isPart(ownerElement) || this.isAction(ownerElement) && joinsStdAction != null) { var featureMember = SysmlFactory.eINSTANCE.createFeatureMembership(); var join = SysmlFactory.eINSTANCE.createJoinNode(); this.elementInitializerSwitch.doSwitch(join); @@ -795,7 +795,7 @@ public Element createJoinAction(Element ownerElement) { */ public Element createForkAction(Element ownerElement) { Feature forksStdAction = this.utilService.findByName(ownerElement, "Actions::Action::forks"); - if (ownerElement instanceof ActionUsage || ownerElement instanceof ActionDefinition && forksStdAction != null) { + if (this.isPart(ownerElement) || this.isAction(ownerElement) && forksStdAction != null) { var featureMember = SysmlFactory.eINSTANCE.createFeatureMembership(); var fork = SysmlFactory.eINSTANCE.createForkNode(); this.elementInitializerSwitch.doSwitch(fork); @@ -820,7 +820,7 @@ public Element createForkAction(Element ownerElement) { */ public Element createMergeAction(Element ownerElement) { Feature mergesStdAction = this.utilService.findByName(ownerElement, "Actions::Action::merges"); - if (ownerElement instanceof ActionUsage || ownerElement instanceof ActionDefinition && mergesStdAction != null) { + if (this.isPart(ownerElement) || this.isAction(ownerElement) && mergesStdAction != null) { var featureMember = SysmlFactory.eINSTANCE.createFeatureMembership(); var merge = SysmlFactory.eINSTANCE.createMergeNode(); this.elementInitializerSwitch.doSwitch(merge); @@ -845,7 +845,7 @@ public Element createMergeAction(Element ownerElement) { */ public Element createDecisionAction(Element ownerElement) { Feature decisionsStdAction = this.utilService.findByName(ownerElement, "Actions::Action::decisions"); - if (ownerElement instanceof ActionUsage || ownerElement instanceof ActionDefinition && decisionsStdAction != null) { + if (this.isPart(ownerElement) || this.isAction(ownerElement) && decisionsStdAction != null) { var featureMember = SysmlFactory.eINSTANCE.createFeatureMembership(); var decision = SysmlFactory.eINSTANCE.createDecisionNode(); this.elementInitializerSwitch.doSwitch(decision); @@ -945,4 +945,12 @@ public Element createPerformAction(Element ownerElement) { ownerElement.getOwnedRelationship().add(featureMember); return perform; } + + private boolean isPart(Element element) { + return element instanceof PartUsage || element instanceof PartDefinition; + } + + private boolean isAction(Element element) { + return element instanceof ActionUsage || element instanceof ActionDefinition; + } } diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java index ab37b19c0..405ba67c4 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java @@ -24,10 +24,13 @@ import org.eclipse.sirius.components.collaborative.diagrams.DiagramContext; import org.eclipse.sirius.components.collaborative.diagrams.DiagramService; import org.eclipse.sirius.components.collaborative.diagrams.DiagramServices; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramContext; import org.eclipse.sirius.components.core.api.IEditingContext; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.diagrams.components.NodeIdProvider; import org.eclipse.sirius.components.diagrams.description.NodeDescription; +import org.eclipse.sirius.components.diagrams.elements.NodeElementProps; import org.eclipse.syson.services.NodeDescriptionService; import org.eclipse.syson.services.UtilService; import org.eclipse.syson.sysml.ActionDefinition; @@ -35,6 +38,8 @@ import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.Membership; import org.eclipse.syson.sysml.Namespace; +import org.eclipse.syson.sysml.PartDefinition; +import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.PerformActionUsage; import org.eclipse.syson.sysml.ReferenceSubsetting; import org.eclipse.syson.sysml.SysmlPackage; @@ -137,7 +142,7 @@ public boolean isHiddenByDefault(Element self, String referenceName) { } public List getAllStandardStartActions(Namespace self) { - if (self instanceof ActionUsage || self instanceof ActionDefinition) { + if (this.isPart(self) || this.isAction(self)) { return self.getOwnedRelationship().stream() .filter(Membership.class::isInstance) .map(Membership.class::cast) @@ -150,7 +155,7 @@ public List getAllStandardStartActions(Namespace self) { } public List getAllStandardDoneActions(Namespace self) { - if (self instanceof ActionUsage || self instanceof ActionDefinition) { + if (this.isPart(self) || this.isAction(self)) { return self.getOwnedRelationship().stream() .filter(Membership.class::isInstance) .map(Membership.class::cast) @@ -192,6 +197,87 @@ public List getAllReferencingPerformActionUsages(Element sel .toList(); } + /** + * Returns {@code true} if {@code parentNodeElement} is an ancestor of {@code childNodeElement}. + *

+ * This method checks if {@code parentNodeElement} contains (directly or indirectly) {@code childNodeElement} in the + * provided {@code diagramContext}. It is typically called in edge preconditions to prevent the creation of + * containment edges that are not necessary because the node is graphically contained in its parent. + *

+ * + * @param parentNodeElement + * the element representing the parent node + * @param childNodeElement + * the element representing the child node + * @param diagramContext + * the diagram context + * @return {@code true} if {@code parentNodeElement} is an ancestor of {@code childNodeElement} + */ + public boolean isAncestorOf(org.eclipse.sirius.components.representations.Element parentNodeElement, org.eclipse.sirius.components.representations.Element childNodeElement, + IDiagramContext diagramContext) { + boolean result = false; + if (parentNodeElement.getProps() instanceof NodeElementProps parentNodeProps + && childNodeElement.getProps() instanceof NodeElementProps childNodeProps) { + Optional optChildNode = this.getNodeOrParent(childNodeProps.getId(), diagramContext); + NodeFinder nodeFinder = new NodeFinder(diagramContext.getDiagram()); + if (optChildNode.isPresent()) { + Node childNode = optChildNode.get(); + Object parent = nodeFinder.getParent(childNode); + // Check if we haven't yet found the parent, this may be the case if the child element doesn't exist yet + // and we are working with its parent. + boolean foundParent = Objects.equals(childNode.getId(), parentNodeProps.getId()); + while (parent != null && !foundParent) { + if (parent instanceof Node parentNode) { + if (Objects.equals(parentNode.getId(), parentNodeProps.getId())) { + foundParent = true; + } else { + parent = nodeFinder.getParent(parentNode); + } + } else { + // The parent isn't a Node, we can't continue to look up the parent hierarchy. + parent = null; + } + } + result = foundParent; + } + + } else { + this.logger.warn("Cannot check graphical containment between {} and {}", parentNodeElement, childNodeElement); + } + return result; + } + + /** + * Returns the node with {@code nodeId} in {@code diagramContext} if it exist, or its parent if it doesn't. + *

+ * This method is typically used in hierarchy computation (see + * {@link #isAncestorOf(org.eclipse.sirius.components.representations.Element, org.eclipse.sirius.components.representations.Element, IDiagramContext)}) + * , where a node can be proxied by its parent. It returns an empty optional if it couldn't find the node nor its + * parent in the diagram. + *

+ * + * @param nodeId + * the identifier of the node to retrieve + * @param diagramContext + * the diagram context + * @return the node with {@code nodeId} if it exist, or its parent if it doesn't + */ + private Optional getNodeOrParent(String nodeId, IDiagramContext diagramContext) { + NodeFinder nodeFinder = new NodeFinder(diagramContext.getDiagram()); + Optional optNode = nodeFinder.getOneNodeMatching(n -> Objects.equals(n.getId(), nodeId)); + if (optNode.isEmpty()) { + // The node doesn't exist in the diagram, we try to retrieve its parent to check the containment hierarchy + // from it. + optNode = diagramContext.getViewCreationRequests().stream() + .filter(creationRequest -> Objects.equals(nodeId, + new NodeIdProvider().getNodeId(creationRequest.getParentElementId(), creationRequest.getDescriptionId(), creationRequest.getContainmentKind(), + creationRequest.getTargetObjectId()))) + .findFirst() + .flatMap(creationRequest -> nodeFinder.getOneNodeMatching(n -> Objects.equals(n.getId(), creationRequest.getParentElementId()))); + } + return optNode; + } + private boolean isReferencingPerformActionUsage(PerformActionUsage pau) { // the given PerformActionUsage is a referencing PerformActionUsage if it contains a reference subsetting // pointing to an action. @@ -199,4 +285,12 @@ private boolean isReferencingPerformActionUsage(PerformActionUsage pau) { return referenceSubSetting != null && referenceSubSetting.getReferencedFeature() instanceof ActionUsage perfomedAction; } + private boolean isPart(Element element) { + return element instanceof PartUsage || element instanceof PartDefinition; + } + + private boolean isAction(Element element) { + return element instanceof ActionUsage || element instanceof ActionDefinition; + } + } diff --git a/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/GeneralViewDiagramDescriptionProvider.java b/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/GeneralViewDiagramDescriptionProvider.java index 0d6864747..a8c42f8bf 100644 --- a/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/GeneralViewDiagramDescriptionProvider.java +++ b/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/GeneralViewDiagramDescriptionProvider.java @@ -59,6 +59,7 @@ import org.eclipse.syson.diagram.general.view.edges.SubsettingEdgeDescriptionProvider; import org.eclipse.syson.diagram.general.view.edges.SuccessionEdgeDescriptionProvider; import org.eclipse.syson.diagram.general.view.edges.TransitionEdgeDescriptionProvider; +import org.eclipse.syson.diagram.general.view.edges.UsageNestedActionUsageEdgeDescriptionProvider; import org.eclipse.syson.diagram.general.view.edges.UsageNestedUsageEdgeDescriptionProvider; import org.eclipse.syson.diagram.general.view.nodes.ActionsCompartmentNodeDescriptionProvider; import org.eclipse.syson.diagram.general.view.nodes.AllocationDefinitionEndsCompartmentNodeDescriptionProvider; @@ -133,7 +134,9 @@ public class GeneralViewDiagramDescriptionProvider implements IRepresentationDes Map.entry(SysmlPackage.eINSTANCE.getItemDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute())), Map.entry(SysmlPackage.eINSTANCE.getMetadataDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedReference())), Map.entry(SysmlPackage.eINSTANCE.getOccurrenceDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedOccurrence())), - Map.entry(SysmlPackage.eINSTANCE.getPartDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort())), + Map.entry(SysmlPackage.eINSTANCE.getPartDefinition(), + List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort(), + SysmlPackage.eINSTANCE.getDefinition_OwnedAction())), Map.entry(SysmlPackage.eINSTANCE.getPortDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedPort(), SysmlPackage.eINSTANCE.getDefinition_OwnedReference())), Map.entry(SysmlPackage.eINSTANCE.getRequirementDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getDefinition_OwnedAttribute(), SysmlPackage.eINSTANCE.getDefinition_OwnedRequirement(), SysmlPackage.eINSTANCE.getRequirementDefinition_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementDefinition_RequiredConstraint())), Map.entry(SysmlPackage.eINSTANCE.getStateDefinition(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation())), @@ -146,7 +149,9 @@ public class GeneralViewDiagramDescriptionProvider implements IRepresentationDes Map.entry(SysmlPackage.eINSTANCE.getInterfaceUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), Map.entry(SysmlPackage.eINSTANCE.getItemUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedReference())), Map.entry(SysmlPackage.eINSTANCE.getOccurrenceUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedOccurrence())), - Map.entry(SysmlPackage.eINSTANCE.getPartUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedPort())), + Map.entry(SysmlPackage.eINSTANCE.getPartUsage(), + List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedPort(), + SysmlPackage.eINSTANCE.getUsage_NestedAction())), Map.entry(SysmlPackage.eINSTANCE.getPerformActionUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedItem(), SysmlPackage.eINSTANCE.getUsage_NestedAction())), Map.entry(SysmlPackage.eINSTANCE.getPortUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getUsage_NestedReference())), Map.entry(SysmlPackage.eINSTANCE.getRequirementUsage(), List.of(SysmlPackage.eINSTANCE.getElement_Documentation(), SysmlPackage.eINSTANCE.getUsage_NestedAttribute(), SysmlPackage.eINSTANCE.getRequirementUsage_AssumedConstraint(), SysmlPackage.eINSTANCE.getRequirementUsage_RequiredConstraint())), @@ -241,6 +246,7 @@ public RepresentationDescription create(IColorProvider colorProvider) { diagramElementDescriptionProviders.add(new GeneralViewEmptyDiagramNodeDescriptionProvider(colorProvider)); diagramElementDescriptionProviders.add(new DefinitionOwnedActionUsageEdgeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); + diagramElementDescriptionProviders.add(new UsageNestedActionUsageEdgeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); this.addDefinitionOwnedUsageEdgeDescriptionProviders(colorProvider, diagramElementDescriptionProviders); this.addUsageCompositeEdgeProviders(colorProvider, diagramElementDescriptionProviders); this.addEdgeDescriptionProviders(colorProvider, diagramElementDescriptionProviders); @@ -321,6 +327,11 @@ private void addCustomNodeDescriptionProviders(IColorProvider colorProvider, colorProvider, this.getDescriptionNameGenerator())); diagramElementDescriptionProviders.add(new ActionFlowCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getPerformActionUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAction(), colorProvider, this.getDescriptionNameGenerator())); + diagramElementDescriptionProviders.add(new ActionFlowCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAction(), colorProvider, + this.getDescriptionNameGenerator())); + diagramElementDescriptionProviders + .add(new ActionFlowCompartmentNodeDescriptionProvider(SysmlPackage.eINSTANCE.getPartDefinition(), SysmlPackage.eINSTANCE.getDefinition_OwnedAction(), colorProvider, + this.getDescriptionNameGenerator())); diagramElementDescriptionProviders.add(new StartActionNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); diagramElementDescriptionProviders.add(new DoneActionNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); diagramElementDescriptionProviders.add(new JoinActionNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator())); diff --git a/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/nodes/FakeNodeDescriptionProvider.java b/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/nodes/FakeNodeDescriptionProvider.java index 89ef474bc..e06f103f0 100644 --- a/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/nodes/FakeNodeDescriptionProvider.java +++ b/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/nodes/FakeNodeDescriptionProvider.java @@ -76,6 +76,10 @@ protected List getChildrenDescription(IViewDiagramElementFinder .ifPresent(childrenNodes::add); cache.getNodeDescription(nameGenerator.getFreeFormCompartmentName(SysmlPackage.eINSTANCE.getPerformActionUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAction())) .ifPresent(childrenNodes::add); + cache.getNodeDescription(nameGenerator.getFreeFormCompartmentName(SysmlPackage.eINSTANCE.getPartUsage(), SysmlPackage.eINSTANCE.getUsage_NestedAction())) + .ifPresent(childrenNodes::add); + cache.getNodeDescription(nameGenerator.getFreeFormCompartmentName(SysmlPackage.eINSTANCE.getPartDefinition(), SysmlPackage.eINSTANCE.getDefinition_OwnedAction())) + .ifPresent(childrenNodes::add); return childrenNodes; } diff --git a/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/services/GeneralViewNodeToolSectionSwitch.java b/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/services/GeneralViewNodeToolSectionSwitch.java index 8b19fdab5..b0b349d05 100644 --- a/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/services/GeneralViewNodeToolSectionSwitch.java +++ b/backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/services/GeneralViewNodeToolSectionSwitch.java @@ -253,6 +253,9 @@ public List caseOccurrenceDefinition(OccurrenceDefinition objec public List casePartDefinition(PartDefinition object) { var createSection = this.createPartDefinitionElementsToolSection(); createSection.getNodeTools().addAll(this.createToolsForCompartmentItems(object)); + // Remove New Action tool, we use a custom New Action tool from ActionFlowCompartmentNodeToolProvider + createSection.getNodeTools().removeIf(nodeTool -> Objects.equals(nodeTool.getName(), "New Action")); + createSection.getNodeTools().add(new ActionFlowCompartmentNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(null)); return List.of(createSection, this.toolDescriptionService.addElementsNodeToolSection(true)); } @@ -260,6 +263,9 @@ public List casePartDefinition(PartDefinition object) { public List casePartUsage(PartUsage object) { var createSection = this.createPartUsageElementsToolSection(); createSection.getNodeTools().addAll(this.createToolsForCompartmentItems(object)); + // Remove New Action tool, we use a custom New Action tool from ActionFlowCompartmentNodeToolProvider + createSection.getNodeTools().removeIf(nodeTool -> Objects.equals(nodeTool.getName(), "New Action")); + createSection.getNodeTools().add(new ActionFlowCompartmentNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(null)); return List.of(createSection, this.toolDescriptionService.addElementsNodeToolSection(true)); } @@ -468,7 +474,16 @@ private NodeToolSection createPartDefinitionElementsToolSection() { this.toolDescriptionService.createNodeToolWithDirection(this.getNodeDescription(SysmlPackage.eINSTANCE.getItemUsage()), SysmlPackage.eINSTANCE.getItemUsage(), null, FeatureDirectionKind.INOUT), this.toolDescriptionService.createNodeToolWithDirection(this.getNodeDescription(SysmlPackage.eINSTANCE.getItemUsage()), SysmlPackage.eINSTANCE.getItemUsage(), - null, FeatureDirectionKind.OUT)); + null, FeatureDirectionKind.OUT), + new StartActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new DoneActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new JoinActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new ForkActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new MergeActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new DecisionActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new AcceptActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new ReferencingPerformActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache), + new PerformActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartDefinition(), this.descriptionNameGenerator).create(this.cache)); } private NodeToolSection createPartUsageElementsToolSection() { @@ -480,7 +495,17 @@ private NodeToolSection createPartUsageElementsToolSection() { null, FeatureDirectionKind.INOUT), this.toolDescriptionService.createNodeToolWithDirection(this.getNodeDescription(SysmlPackage.eINSTANCE.getItemUsage()), SysmlPackage.eINSTANCE.getItemUsage(), null, FeatureDirectionKind.OUT), - this.toolDescriptionService.createNodeTool(this.getNodeDescription(SysmlPackage.eINSTANCE.getPartUsage()), SysmlPackage.eINSTANCE.getPartUsage())); + this.toolDescriptionService.createNodeTool(this.getNodeDescription(SysmlPackage.eINSTANCE.getPartUsage()), SysmlPackage.eINSTANCE.getPartUsage()), + new StartActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new DoneActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new JoinActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new ForkActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new MergeActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new DecisionActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new AcceptActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new ReferencingPerformActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache), + new PerformActionNodeToolProvider(SysmlPackage.eINSTANCE.getPartUsage(), this.descriptionNameGenerator).create(this.cache) + ); } private NodeTool createPayloadNodeTool(EClass payloadType) {