]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Fix CopyAdvisorUtil.copy2 to copy IsRelatedTo-statements left out before 73/4473/1
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 17 Sep 2020 11:45:47 +0000 (14:45 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 17 Sep 2020 11:55:57 +0000 (11:55 +0000)
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
(cherry picked from commit 99395a7780ef1626d3ae97183ef4ae717f32b215)

bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java
bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java

index 61d09acdd3cb18981d53c67e9300d255a3fc23d6..ae1fa2e63b39bfa726c035fa7a72ed768a74df05 100644 (file)
@@ -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;
@@ -45,6 +43,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
@@ -81,6 +83,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}
@@ -363,8 +374,10 @@ public class CopyAdvisorUtil {
      * @throws DatabaseException
      */
     public static Resource copy2(WriteGraph graph, Resource source,
-            BiFunction<ReadGraph, Statement, StatementEvaluation> advisor) throws DatabaseException {
-        return copy2(graph, source, 0, advisor, new THashMap<Object, Object>());
+            BiFunction<ReadGraph, Statement, StatementEvaluation> advisor)
+                    throws DatabaseException
+    {
+        return copy2(graph, source, advisor, new THashMap<>());
     }
 
     /**
@@ -379,13 +392,52 @@ public class CopyAdvisorUtil {
      * @throws DatabaseException 
      */
     public static Resource copy2(WriteGraph graph, Resource source,
-            BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
-            throws DatabaseException {
-        return copy2(graph, source, 0, advisor, copyMap);
+            BiFunction<ReadGraph, Statement, StatementEvaluation> advisor,
+            Map<Object, Object> copyMap)
+                    throws DatabaseException
+    {
+        Set<Statement4> 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<Object, Object> copyMap,
+            Set<Statement4> 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<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
+            BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap,
+            Set<Statement4> pendingSourceStatements)
     throws DatabaseException {
         if (DEBUG_COPY)
             System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")");
@@ -496,12 +548,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");
+                        }
                     }
                 }
             }
index 3e6e9c1b9527096cfa1835a50e43f6b2dfb97c7f..021ecc436b86c5d82af28d062cd45d4a88b38148 100644 (file)
@@ -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<Object, Object> map) throws DatabaseException {
-        StructuralResource2 STR = StructuralResource2.getInstance(graph);
         Resource copy = CopyAdvisorUtil.copy2(graph, source, null, map);
 
         Layer0 L0 = Layer0.getInstance(graph);