]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Manually merged commit f2f1f3fe changes to release/1.28.1 branch. 66/1266/1
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 28 Nov 2017 08:52:29 +0000 (10:52 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 28 Nov 2017 08:52:29 +0000 (10:52 +0200)
Without these changes using copy-paste on diagrams will cause large
amounts of overlapping GUID identifiers for diagram elements to
accumulate in models.

refs #7348

Change-Id: I1b5bc5d06e8815bf5a50f234e793a1bbef0e5fb7

bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
bundles/org.simantics.diagram/src/org/simantics/diagram/handler/Paster.java
bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/CompositeCopyHandler.java
bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ElementCopyAdvisor.java

index adc51c16d88ef0f74f1f849f421e9156398c69f1..3a24102b25ace39a7760022da4bee0b22c5b36c4 100644 (file)
@@ -54,6 +54,7 @@ import org.simantics.databoard.type.StringType;
 import org.simantics.databoard.type.UnionType;
 import org.simantics.databoard.type.VariantType;
 import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.datatypes.literal.GUID;
 import org.simantics.db.ChangeSetIdentifier;
 import org.simantics.db.Operation;
 import org.simantics.db.ReadGraph;
@@ -1378,4 +1379,47 @@ public class Layer0Utils {
        
     }
 
+    /**
+     * Adds a random {@link GUID} as a value for <code>L0.identifier</code>
+     * 
+     * @param graph
+     * @param component
+     *            for which the identifier is added
+     * @param add
+     *            <code>true</code> to invoke addLiteral, <code>false</code> to
+     *            invoke claimLiteral
+     * @throws DatabaseException
+     */
+    public static void claimNewIdentifier(WriteGraph graph, Resource component, boolean add) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        GUID guid = GUID.random();
+        if (add)
+            graph.addLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, guid, GUID.BINDING);
+        else
+            graph.claimLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, guid, GUID.BINDING);
+    }
+
+    /**
+     * Sets a new random unique identifier for the specified entity if it already
+     * has an identifier. If the entity does not have a previous identifier, nothing
+     * is done.
+     * 
+     * @param graph
+     * @param entity
+     *            for which the identifier is added
+     * @return <code>true</code> if the identifier was renewed, <code>false</code>
+     *         otherwise
+     * @throws DatabaseException
+     * @see {@link #claimNewIdentifier(WriteGraph, Resource, boolean)}
+     */
+    public static boolean renewIdentifier(WriteGraph graph, Resource entity) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        Statement stm = graph.getPossibleStatement(entity, L0.identifier);
+        if (stm != null) {
+            graph.claimValue(stm.getObject(), GUID.random(), GUID.BINDING);
+            return true;
+        }
+        return false;
+    }
+
 }
index 03edda6bdbc428762fc84516f52404c1eeb2aea2..41b369ed630323eeafc612f0abb1ef7d6a15e7b4 100644 (file)
@@ -28,6 +28,7 @@ import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.common.utils.OrderedSetUtils;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
 import org.simantics.db.layer0.util.RemoverUtil;
 import org.simantics.db.request.Write;
 import org.simantics.diagram.content.ConnectionUtil;
@@ -863,6 +864,11 @@ public class Paster {
                 graph.claim(copy, L0.ConsistsOf, L0.PartOf, relationCopy);
                 graph.claim(copy, MOD.HasReferenceRelation, MOD.HasReferenceRelation_Inverse, relationCopy);
 
+                // #7348: renew reference relation GUID identifiers properly
+                Layer0Utils.renewIdentifier(graph, relationCopy);
+                for (Resource invRel : graph.getObjects(relationCopy, L0.ConsistsOf))
+                    Layer0Utils.renewIdentifier(graph, invRel);
+
                 return copy;
             }
 
index ae65e87f88476bf6b2059e8899d5a63266816fee..6167334fdd79815ad98a60cb1db1762d611a116f 100644 (file)
@@ -22,6 +22,7 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.PossibleIndexRoot;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.function.DbConsumer;
 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;
 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
@@ -64,39 +65,63 @@ public class CompositeCopyHandler extends DefaultCopyHandler {
         if(indexRoot == null) throw new DatabaseException("Composite is not part of any index root");
         String indexRootUri = graph.getURI(indexRoot);
 
+        DbConsumer<Resource> identifierExcluder = r -> {
+            if (r != null)
+                exclusions.addAll(graph.getObjects(r, L0.identifier));
+        };
+
         for(Resource resource : resources) {
             // Process all connection joins.
             // This is the only way to access all of them.
             for (Resource diagram : graph.getObjects(resource, MOD.CompositeToDiagram)) {
-                for (Resource flag : graph.syncRequest(new ObjectsWithType(diagram, L0.ConsistsOf, DIA.Flag))) {
-                    for (Resource join : graph.getObjects(flag, DIA.FlagIsJoinedBy)) {
-                        // Joins with external references are omitted
-                        for (Resource comp : graph.getObjects(join, SR.JoinsComposite)) {
-                            if (!resourceSet.contains(comp))
-                                exclusions.add(join);
-                        }
-                        // This code excludes joins with flags to external
-                        // diagrams that are not connected (have no
-                        // configuration for the flag)
-                        for (Resource flag2 : graph.getObjects(join, DIA.JoinsFlag)) {
-                            Resource diagram2 = graph.getPossibleObject(flag2, L0.PartOf);
-                            if (diagram2 != null) {
-                                Resource comp = graph.getPossibleObject(diagram2, MOD.DiagramToComposite);
+                identifierExcluder.accept(diagram);
+
+                for (Resource element : graph.getObjects(diagram, L0.ConsistsOf)) {
+                    identifierExcluder.accept(element);
+
+                    Set<Resource> types = graph.getTypes(element);
+
+                    // Check all diagram flag elements for necessary exclusions.
+                    if (types.contains(DIA.Flag)) {
+                        for (Resource join : graph.getObjects(element, DIA.FlagIsJoinedBy)) {
+                            // Joins with external references are omitted
+                            for (Resource comp : graph.getObjects(join, SR.JoinsComposite)) {
                                 if (!resourceSet.contains(comp))
-                                    exclusions.add(join); 
+                                    exclusions.add(join);
+                            }
+                            // This code excludes joins with flags to external
+                            // diagrams that are not connected (have no
+                            // configuration for the flag)
+                            for (Resource flag2 : graph.getObjects(join, DIA.JoinsFlag)) {
+                                Resource diagram2 = graph.getPossibleObject(flag2, L0.PartOf);
+                                if (diagram2 != null) {
+                                    Resource comp = graph.getPossibleObject(diagram2, MOD.DiagramToComposite);
+                                    if (!resourceSet.contains(comp))
+                                        exclusions.add(join); 
+                                }
+                            }
+                        }
+                    }
+
+                    // Check all diagram monitor elements.
+                    // Any components referenced that are external to the exported diagrams must be excluded from the export.
+                    // This will leave the monitors without a monitored component but export and import will work anyway.
+                    if (types.contains(DIA.Monitor)) {
+                        for (Resource monitoredComponent : graph.getObjects(element, DIA.HasMonitorComponent)) {
+                            Resource monitoredComponentComposite = graph.getPossibleObject(monitoredComponent, L0.PartOf);
+                            if (monitoredComponentComposite != null && !resourceSet.contains(monitoredComponentComposite)) {
+                                exclusions.add(monitoredComponent);
                             }
                         }
                     }
-                }
 
-                // Check all diagram monitor elements.
-                // Any components referenced that are external to the exported diagrams must be excluded from the export.
-                // This will leave the monitors without a monitored component but export and import will work anyway.
-                for (Resource ref : graph.syncRequest(new ObjectsWithType(diagram, L0.ConsistsOf, DIA.Monitor))) {
-                    for (Resource monitoredComponent : graph.getObjects(ref, DIA.HasMonitorComponent)) {
-                        Resource monitoredComponentComposite = graph.getPossibleObject(monitoredComponent, L0.PartOf);
-                        if (monitoredComponentComposite != null && !resourceSet.contains(monitoredComponentComposite)) {
-                            exclusions.add(monitoredComponent);
+                    // Check all diagram reference elements for necessary exclusions.
+                    if (types.contains(MOD.ReferenceElement)) {
+                        for (Resource rel : graph.getObjects(element, L0.ConsistsOf)) {
+                            identifierExcluder.accept(rel);
+                            for (Resource invRel : graph.getObjects(rel, L0.ConsistsOf)) {
+                                identifierExcluder.accept(invRel);
+                            }
                         }
                     }
                 }
@@ -119,13 +144,11 @@ public class CompositeCopyHandler extends DefaultCopyHandler {
             // Include resource as root
             CompositeInfo info = CompositeInfo.fromResource(graph, resource);
             roots.add(new RootSpec(resource, info.getTGName(), true, typeId(graph, L0, indexRootUri, resource)));
-               Resource id = graph.getPossibleObject(resource, L0.identifier);
-               if(id != null) exclusions.add(id);
+            identifierExcluder.accept(resource);
             // Include components as roots
-            for(Resource child : graph.sync(new ObjectsWithType(resource, L0.ConsistsOf, SR.Component))) {
-               DiagramComponentInfo cinfo = DiagramComponentInfo.fromResource(graph, info, child);
-               id = graph.getPossibleObject(child, L0.identifier);
-               if(id != null) exclusions.add(id);
+            for (Resource child : graph.sync(new ObjectsWithType(resource, L0.ConsistsOf, SR.Component))) {
+                DiagramComponentInfo cinfo = DiagramComponentInfo.fromResource(graph, info, child);
+                identifierExcluder.accept(child);
                 roots.add(new RootSpec(child, cinfo.getTGName(info), true, typeId(graph, L0, indexRootUri, child)));
             }
         }
index 994aa1ab13feb132f6a9ce5ebaa5270c01bf6582..d666d63d5f24b9ba33b47a0fef6d363831dcecc3 100644 (file)
@@ -23,6 +23,7 @@ import org.simantics.db.common.utils.OrderedSetUtils;
 import org.simantics.db.exception.CancelTransactionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.request.PossibleModel;
+import org.simantics.db.layer0.util.Layer0Utils;
 import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.diagram.stubs.G2DResource;
 import org.simantics.diagram.synchronization.ISynchronizationContext;
@@ -89,6 +90,8 @@ public class ElementCopyAdvisor extends GraphCopyAdvisor {
         if (graph.hasStatement(sourceContainer, L0.ConsistsOf, source))
             graph.claim(targetContainer, L0.ConsistsOf, copy);
 
+        Layer0Utils.claimNewIdentifier(graph, copy, false);
+
         return copy;
     }