]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java
Adapt GraphChanges to copied model.
[simantics/interop.git] / org.simantics.interop / src / org / simantics / interop / test / GraphChanges.java
index a68890651f2a38b522ce6ef13066f7b5df89a8fe..3fe74177a2b93bcc71f09e90656b8ffc09858d74 100644 (file)
@@ -1,11 +1,15 @@
 package org.simantics.interop.test;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map.Entry;
 
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.Session;
 import org.simantics.db.Statement;
+import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.utils.datastructures.BijectionMap;
@@ -30,12 +34,14 @@ public class GraphChanges {
                int hashCode;
                
                public Modification(Resource leftSub, Resource rightSub, Statement leftStm, Statement rightStm) {
-                       super();
                        this.leftSub = leftSub;
                        this.rightSub = rightSub;
                        this.leftStm = leftStm;
                        this.rightStm = rightStm;
                        
+                       if (leftSub.getResourceId() < 0)
+                               System.out.println();
+                       
                        hashCode = leftSub.hashCode() + rightSub.hashCode();
                        if (leftStm != null)
                                hashCode += leftStm.hashCode();
@@ -225,5 +231,128 @@ public class GraphChanges {
                }
                return sb.toString();
        }
+       
+       /**
+        * Adapts GraphChanges between A1 and B to A2 and B, when A2 is copy of A1.
+        * @param changes changes between A1 and B
+        * @param bijection changes between A1 and A2. Expected to be a bijection, so no additions or removals.
+        * @return
+        * @throws DatabaseException
+        */
+       public static GraphChanges adapt(Session session, GraphChanges changes, GraphChanges bijection) throws DatabaseException{
+               if (!changes.getResource1().equals(bijection.getResource1()))
+                       throw new DatabaseException("Left side model must be the same");
+               //if (bijection.getDeletions().size() > 0 || bijection.getAdditions().size() > 0)
+               //      throw new DatabaseException("Bijection change is not a bijection, it contains additions and/or removals");
+               BijectionMap<Resource, Resource> comparable = new BijectionMap<Resource, Resource>();
+               for (Entry<Resource, Resource> entry : changes.comparable.getEntries()) {
+                       if (entry.getKey().equals(entry.getValue())) {
+                               comparable.map(entry.getKey(), entry.getValue());
+                       } else {
+                               Resource nl = bijection.getComparable().getRight(entry.getKey());
+                               if (nl == null) {
+                                       // Matching literal resources are not included in bijection map.
+                                       // TODO : should we check that the resource is literal?
+                                       // throw new DatabaseException("Did not find matching resource from bijection for " + entry.getKey());
+                                       continue;
+                               }
+                               comparable.map(nl, entry.getValue());
+                       }
+               }
+               List<Statement> deletions = new ArrayList<Statement>(changes.getDeletions().size()); // Removals must be adapted from A1 to A2.
+               List<Statement> additions = new ArrayList<Statement>(changes.getAdditions()); // Additions can be copied, since they are statements in B.
+               session.syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               for (Statement del : changes.getDeletions()) {
+                                       Resource s1 = del.getSubject();
+                                       Resource s2 = bijection.getComparable().getRight(s1);
+                                       Resource p1 = del.getPredicate();
+                                       Resource p2 = bijection.getComparable().getRight(p1);
+                                       if (p2 == null)
+                                               p2 = p1;
+                                       Resource o1 = del.getObject();
+                                       Resource o2 = bijection.getComparable().getRight(o1);
+                                       
+                                       if (s2 == null || p2 == null || o2 == null) {
+                                               throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
+                                       }
+                                       Statement stm2 = null;
+                                       for (Statement s : graph.getStatements(s2, p2)) {
+                                               if (s.getObject().equals(o2)) {
+                                                       stm2 = s;
+                                                       break;
+                                               }
+                                       }
+                                       if (stm2 == null) {
+                                               throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+"), but it is not in DB!");
+                                       }
+                                       deletions.add(stm2);
+                               }
+                               
+                       }
+               });
+               
+               List<Modification> modifications = new ArrayList<GraphChanges.Modification>(changes.getModifications().size());
+               
+               session.syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               for (Modification mod : changes.getModifications()) {
+                                       Statement del = mod.leftStm;
+                                       Resource sub1 = mod.getLeftSub();
+                                       Resource sub2 = bijection.getComparable().getRight(sub1);
+                                       if (sub2 == null) {
+                                               throw new DatabaseException("Did not find matching resource from bijection for " + sub1);
+                                       }
+                                       Resource s1 = del.getSubject();
+                                       Resource s2 = bijection.getComparable().getRight(s1);
+                                       Resource p1 = del.getPredicate();
+                                       Resource p2 = bijection.getComparable().getRight(p1);
+                                       if (p2 == null)
+                                               p2 = p1;
+                                       Resource o1 = del.getObject();
+                                       Resource o2 = bijection.getComparable().getRight(o1);
+                                       if (mod.isLeftAsserted()) {
+                                               if (s2 == null)
+                                                       s2 = s1;
+                                               if (o2 == null)
+                                                       o2 = o1;
+                                       } 
+                                       
+                                       if (s2 == null || p2 == null) {
+                                               throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
+                                       }
+                                       Collection<Statement> stms = graph.getStatements(s2, p2);
+                                       Statement stm2 = null;
+                                       if (o2 == null) {
+                                               // Matching literal resources are not included in bijection map.
+                                               if (stms.size() == 1) {
+                                                        stm2 = stms.iterator().next();
+                                               } else {
+                                                        throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
+                                               }
+                                       } else {
+                                               for (Statement s : stms) {
+                                                       if (s.getObject().equals(o2)) {
+                                                               stm2 = s;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if (stm2 == null) {
+                                               throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+"), but it is not in DB!");
+                                       }
+                                       Modification mod2 = new Modification(sub2, mod.rightSub, stm2, mod.rightStm);
+                                       modifications.add(mod2);
+                               }
+                               
+                       }
+               });
+               
+               return new GraphChanges(bijection.r2, changes.r2, deletions, additions, modifications, comparable);
+       }
 
 }