diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 25a46ceb75..ae6f2de248 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -25,6 +25,7 @@ - https://github.com/eclipse-sirius/sirius-components/issues/1559[#1559] [view] It is now possible to specify the (computed) width and height separately for a _Node Style_ (instead of a single size before, which always resulted in square shapes). - https://github.com/eclipse-sirius/sirius-components/issues/1560[#1560] Remove unused `EditingContextCompletionProposalsDataFetcher` - https://github.com/eclipse-sirius/sirius-components/issues/1426[#1426] [view] Add missing data type on initialDirectEditLabelExpression +- https://github.com/eclipse-sirius/sirius-components/issues/1456[#1456] [diagram] Add new methods to the diagram rendering cache to compute the parent, ancestors, children and descendants of a given node identifier == v2023.1.0 diff --git a/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/components/NodeComponent.java b/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/components/NodeComponent.java index 3ac9b480b2..f35a7b766c 100644 --- a/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/components/NodeComponent.java +++ b/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/components/NodeComponent.java @@ -100,6 +100,7 @@ public Element render() { cache.put(nodeDescription.getId(), nodeElement); cache.put(semanticElement, nodeElement); + cache.put(nodeElement, this.props.getParentElementId()); } } diff --git a/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/renderer/DiagramRenderingCache.java b/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/renderer/DiagramRenderingCache.java index 0f186d5717..f363f4b820 100644 --- a/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/renderer/DiagramRenderingCache.java +++ b/packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/renderer/DiagramRenderingCache.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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 @@ -14,12 +14,13 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; +import org.eclipse.sirius.components.diagrams.elements.NodeElementProps; import org.eclipse.sirius.components.representations.Element; /** @@ -29,12 +30,18 @@ */ public class DiagramRenderingCache { - private final Map> nodeDescriptionIdToNodes = new HashMap<>(); + private final Map> nodeDescriptionIdToNodes = new LinkedHashMap<>(); + + private final Map nodeIdToNode = new LinkedHashMap<>(); private final Map nodeToObject = new LinkedHashMap<>(); private final Map> objectToNodes = new LinkedHashMap<>(); + private final Map nodeToParentElementId = new LinkedHashMap<>(); + + private final Map> nodeIdToChildren = new LinkedHashMap<>(); + public void put(UUID nodeDescriptionId, Element nodeElement) { this.nodeDescriptionIdToNodes.computeIfAbsent(nodeDescriptionId, id -> new ArrayList<>()).add(nodeElement); } @@ -44,6 +51,17 @@ public void put(Object object, Element nodeElement) { this.objectToNodes.computeIfAbsent(object, obj -> new ArrayList<>()).add(nodeElement); } + public void put(Element node, String parentNodeId) { + if (node.getProps() instanceof NodeElementProps nodeElementProps) { + this.nodeIdToNode.put(nodeElementProps.getId(), node); + this.nodeToParentElementId.put(node, parentNodeId); + + var children = this.nodeIdToChildren.getOrDefault(parentNodeId, new ArrayList<>()); + children.add(node); + this.nodeIdToChildren.put(parentNodeId, children); + } + } + public Map> getNodeDescriptionIdToNodes() { return this.nodeDescriptionIdToNodes; } @@ -52,11 +70,52 @@ public Map getNodeToObject() { return this.nodeToObject; } + public Map> getObjectToNodes() { + return this.objectToNodes; + } + public List getElementsRepresenting(Object semanticObject) { return this.objectToNodes.getOrDefault(semanticObject, Collections.emptyList()); } - public Map> getObjectToNodes() { - return this.objectToNodes; + public Optional getParent(String nodeId) { + // @formatter:off + return Optional.ofNullable(this.nodeIdToNode.get(nodeId)) + .map(this.nodeToParentElementId::get) + .map(this.nodeIdToNode::get); + // @formatter:on } + + public List getAncestors(String nodeId) { + List ancestors = new ArrayList<>(); + + var parent = this.getParent(nodeId).orElse(null); + while (parent != null) { + ancestors.add(parent); + if (parent.getProps() instanceof NodeElementProps nodeElementProps) { + parent = this.getParent(nodeElementProps.getId()).orElse(null); + } + } + + return ancestors; + } + + public List getChildren(String nodeId) { + return Optional.ofNullable(this.nodeIdToChildren.get(nodeId)).orElse(List.of()); + } + + public List getDescendants(String nodeId) { + List descendants = new ArrayList<>(); + + var children = this.getChildren(nodeId); + children.forEach(child -> { + descendants.add(child); + if (child.getProps() instanceof NodeElementProps nodeElementProps) { + descendants.addAll(this.getDescendants(nodeElementProps.getId())); + } + }); + + return descendants; + } + }