From: Tuukka Lehtonen Date: Thu, 17 Sep 2020 11:45:47 +0000 (+0300) Subject: Fix CopyAdvisorUtil.copy2 to copy IsRelatedTo-statements left out before X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=99395a7780ef1626d3ae97183ef4ae717f32b215 Fix CopyAdvisorUtil.copy2 to copy IsRelatedTo-statements left out before This implementation works so that it copies any IsRelatedTo statements where both the subject and object have been copied during the normal (old) copy process. The statements are marked as pending during the copy and post-processed after everything else has been copied. gitlab #607 Change-Id: I9170a448c127e0c7de6eae4260db5799ad7644bb --- diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java index ab28463e8..bbf9a8e5b 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.simantics.diagram.synchronization.graph; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import java.util.Set; import java.util.function.BiFunction; @@ -46,6 +44,10 @@ import org.simantics.diagram.synchronization.SynchronizationHints; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.BinaryFunction; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; /** * This class contains utility methods for the basic cut/copy operations @@ -82,6 +84,15 @@ public class CopyAdvisorUtil { public static final boolean DEBUG_COPY = DebugPolicy.DEBUG_COPY_PASTE; + private static class Statement4 { + public final Statement stm; + public final Resource inverse; + public Statement4(Statement stm, Resource inverse) { + this.stm = stm; + this.inverse = inverse; + } + } + /** * @param context a synchronization context instance, such as * {@link GraphToDiagramSynchronizer} @@ -364,8 +375,10 @@ public class CopyAdvisorUtil { * @throws DatabaseException */ public static Resource copy2(WriteGraph graph, Resource source, - BiFunction advisor) throws DatabaseException { - return copy2(graph, source, 0, advisor, new THashMap()); + BiFunction advisor) + throws DatabaseException + { + return copy2(graph, source, advisor, new THashMap<>()); } /** @@ -380,13 +393,52 @@ public class CopyAdvisorUtil { * @throws DatabaseException */ public static Resource copy2(WriteGraph graph, Resource source, - BiFunction advisor, Map copyMap) - throws DatabaseException { - return copy2(graph, source, 0, advisor, copyMap); + BiFunction advisor, + Map copyMap) + throws DatabaseException + { + Set pendingStatements = new THashSet<>(); + Resource result = copy2(graph, source, 0, advisor, copyMap, pendingStatements); + postProcessStatements(graph, copyMap, pendingStatements); + return result; + } + + /** + * Post-process pending statement + * + * Rule: If both the subject and object of a pending source statement have + * been copied, then the pending statement should also be copied. + */ + private static void postProcessStatements( + WriteGraph graph, + Map copyMap, + Set pendingStatements) + throws DatabaseException + { + if (pendingStatements.isEmpty()) + return; + + if (DEBUG_COPY) + System.out.println("post processing " + pendingStatements.size() + " pending statements"); + for (Statement4 srcStm : pendingStatements) { + // At this point, it is certain that srcStm subject has been copied + // but test it anyway. + Resource subjectCopy = (Resource) copyMap.get(srcStm.stm.getSubject()); + Resource objectCopy = (Resource) copyMap.get(srcStm.stm.getObject()); + if (subjectCopy == null || objectCopy == null) { + if (DEBUG_COPY) + System.out.println("skipping pending statement: " + NameUtils.toString(graph, srcStm.stm)); + continue; + } + if (DEBUG_COPY) + System.out.println("copying pending statement: " + NameUtils.toString(graph, srcStm.stm)); + graph.claim(subjectCopy, srcStm.stm.getPredicate(), srcStm.inverse, objectCopy); + } } private static Resource copy2(final WriteGraph graph, final Resource source, final int level, - BiFunction advisor, Map copyMap) + BiFunction advisor, Map copyMap, + Set pendingSourceStatements) throws DatabaseException { if (DEBUG_COPY) System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")"); @@ -497,12 +549,18 @@ public class CopyAdvisorUtil { if (DEBUG_COPY) System.out.println("[" + level + "]\t\tcopy whole object"); - Resource clone = copy2(graph, obj, level + 1, advisor, copyMap); + Resource clone = copy2(graph, obj, level + 1, advisor, copyMap, pendingSourceStatements); graph.claim(copy, relation, inverse, clone); } } else { - if (DEBUG_COPY) - System.out.println("[" + level + "]\t\tskipping statement"); + if (graph.isSubrelationOf(relation, L0.IsRelatedTo)) { + if (DEBUG_COPY) + System.out.println("[" + level + "]\t\tmarking statement as pending for post-processing"); + pendingSourceStatements.add(new Statement4(stm, inverse)); + } else { + if (DEBUG_COPY) + System.out.println("[" + level + "]\t\tskipping weak statement"); + } } } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java index 3e6e9c1b9..021ecc436 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java @@ -32,7 +32,6 @@ import org.simantics.modeling.ModelingUtils; import org.simantics.modeling.services.ComponentNamingUtil; import org.simantics.modeling.services.NamingException; import org.simantics.project.IProject; -import org.simantics.structural.stubs.StructuralResource2; import gnu.trove.map.hash.THashMap; @@ -58,7 +57,6 @@ public class ComponentCopyAdvisor extends GraphCopyAdvisor { @Override public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer, Resource targetContainer, Map map) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource copy = CopyAdvisorUtil.copy2(graph, source, null, map); Layer0 L0 = Layer0.getInstance(graph);