From 1b3fe1c5f30f4c373cd55df131d3774fe33150ab Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Thu, 24 Feb 2022 11:32:54 +0200 Subject: [PATCH] Adapt GraphChanges to copied model. gitlab #38 Change-Id: Id6113850b69960388bbd4fc1e6b99e8c9665ddb8 --- .../interop/update/model/ModelUpdate.java | 24 ++++ .../simantics/interop/test/GraphChanges.java | 131 +++++++++++++++++- .../interop/test/GraphComparator.java | 4 +- 3 files changed, 156 insertions(+), 3 deletions(-) diff --git a/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java b/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java index 51cd1eb..6e51757 100644 --- a/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java +++ b/org.simantics.interop.update/src/org/simantics/interop/update/model/ModelUpdate.java @@ -169,6 +169,30 @@ public abstract class ModelUpdate { init = true; } + public void setInput(Resource oldModel, Resource newModel, GraphChanges changes, IProgressMonitor monitor) throws DatabaseException{ + if (!oldModel.equals(changes.getResource1()) || + !newModel.equals(changes.getResource2())) { + throw new DatabaseException("GraphChanges does not match input models"); + } + this.changes = getSession().syncRequest(createFilterRead(changes, filters)); + Pair chg = createChangeObjects(changes, monitor); + if (chg == null) { + dispose(); + return; + } + updateTree = chg.first; + updateList = chg.second; + if (userFilters.size() != 0) { + refreshUserFilters(); + } + + + if (originalModel != null) { + defaultSelections(); + } + init = true; + } + public void addFilter(ChangeFilter filter) { if (init) throw new IllegalStateException("ModelUpdate has been initialized, adjusting filters is no longer possible."); diff --git a/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java b/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java index a688906..3fe7417 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java @@ -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 comparable = new BijectionMap(); + for (Entry 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 deletions = new ArrayList(changes.getDeletions().size()); // Removals must be adapted from A1 to A2. + List additions = new ArrayList(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 modifications = new ArrayList(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 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); + } } diff --git a/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java b/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java index 9ad2061..d8750b2 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java @@ -1450,9 +1450,9 @@ public class GraphComparator { boolean eq = compareValue(g,b,s1.getObject(), s2.getObject()); if (!eq) { addModification(r1,s1,r2,s2); - if (!a1 && !a2) - addComparable(s1, s2); } + if (!a1 && !a2) + addComparable(s1, s2); } else { // Non literal properties. int comp = comparator.compare(g, s1.getObject(), s2.getObject()); -- 2.47.1