From 25c2db3c0f8b13af613a0f73b79ff27a3dc6feaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Sp=C3=B6nemann?= Date: Mon, 27 Sep 2021 16:02:56 +0200 Subject: [PATCH] #781: Clone properties to avoid sharing mutable values in multiple elements --- .../eclipse/elk/core/LayoutConfigurator.java | 21 ++++++++++++------- .../org/eclipse/elk/core/util/ElkUtil.java | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/LayoutConfigurator.java b/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/LayoutConfigurator.java index 9c95e9a8b6..32d8582a91 100644 --- a/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/LayoutConfigurator.java +++ b/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/LayoutConfigurator.java @@ -27,6 +27,7 @@ import org.eclipse.elk.graph.properties.IPropertyHolder; import org.eclipse.elk.graph.properties.MapPropertyHolder; import org.eclipse.elk.graph.properties.Property; +import org.eclipse.elk.graph.util.ElkReflect; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -218,16 +219,20 @@ public void visit(final ElkGraphElement element) { @SuppressWarnings("unchecked") protected void applyProperties(final ElkGraphElement element, final IPropertyHolder properties) { if (properties != null) { - if (!optionFilters.isEmpty()) { - for (Map.Entry, Object> entry : properties.getAllProperties().entrySet()) { - boolean accept = optionFilters.stream() - .allMatch(filter -> filter.accept(element, entry.getKey())); - if (accept) { - element.setProperty((IProperty) entry.getKey(), entry.getValue()); + List filters = getFilters(); + for (Map.Entry, Object> entry : properties.getAllProperties().entrySet()) { + boolean accept = filters.stream() + .allMatch(filter -> filter.accept(element, entry.getKey())); + if (accept) { + Object value = entry.getValue(); + if (value instanceof Cloneable) { + Object clone = ElkReflect.clone(value); + if (clone != null) { + value = clone; + } } + element.setProperty((IProperty) entry.getKey(), value); } - } else { - element.copyProperties(properties); } } } diff --git a/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/util/ElkUtil.java b/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/util/ElkUtil.java index 3a03c2153f..f553f34518 100644 --- a/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/util/ElkUtil.java +++ b/plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/util/ElkUtil.java @@ -347,7 +347,7 @@ public static KVector effectiveMinSizeConstraintFor(final ElkNode node) { if (sizeConstraint.contains(SizeConstraint.MINIMUM_SIZE)) { Set sizeOptions = node.getProperty(CoreOptions.NODE_SIZE_OPTIONS); - KVector minSize = node.getProperty(CoreOptions.NODE_SIZE_MINIMUM); + KVector minSize = new KVector(node.getProperty(CoreOptions.NODE_SIZE_MINIMUM)); // If minimum width or height are not set, maybe default to default values if (sizeOptions.contains(SizeOptions.DEFAULT_MINIMUM_SIZE)) {