X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.interop%2Fsrc%2Forg%2Fsimantics%2Finterop%2Ftest%2FGraphChanges.java;h=f9065070fe095f8e3c247c12bf03011f8db811cd;hb=a43434a612fa0aafd0d4f17ebed2b770c4b1d585;hp=facb75abce9ac752eea6f1229a5f656d685b64fd;hpb=4399a40e11996b9a373f522af995a19a05493dd3;p=simantics%2Finterop.git 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 facb75a..f906507 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java @@ -1,95 +1,360 @@ -package org.simantics.interop.test; - -import java.util.List; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.Statement; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.exception.ServiceException; -import org.simantics.db.exception.ValidationException; -import org.simantics.utils.datastructures.BijectionMap; -import org.simantics.utils.datastructures.Pair; - -public class GraphChanges { - - private Resource r1; - private Resource r2; - private List deletions; - private List additions; - private List> modifications; - - private BijectionMap comparable; - - public GraphChanges(Resource r1, Resource r2, List deletions, List additions, - List> modifications, BijectionMap comparable) { - super(); - this.r1 = r1; - this.r2 = r2; - this.deletions = deletions; - this.additions = additions; - this.modifications = modifications; - this.comparable = comparable; - } - - public Resource getResource1() { - return r1; - } - - public Resource getResource2() { - return r2; - } - - public List getAdditions() { - return additions; - } - - public List getDeletions() { - return deletions; - } - - public List> getModifications() { - return modifications; - } - - public BijectionMap getComparable() { - return comparable; - } - - public String toString(ReadGraph graph) throws ValidationException, ServiceException { - StringBuilder sb = new StringBuilder(); - sb.append("Del:\n"); - for (Statement stm : deletions) { - sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+ - NameUtils.getSafeName(graph, stm.getPredicate()) + " " + - NameUtils.getSafeName(graph, stm.getObject()) + " (" + - stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n"); - } - sb.append("Add:\n"); - for (Statement stm : additions) { - sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+ - NameUtils.getSafeName(graph, stm.getPredicate()) + " " + - NameUtils.getSafeName(graph, stm.getObject()) + " (" + - stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n"); - } - sb.append("Mod:\n"); - for (Pair mod :modifications) { - { - Statement stm = mod.first; - sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+ - NameUtils.getSafeName(graph, stm.getPredicate()) + " " + - NameUtils.getSafeName(graph, stm.getObject()) + " (" + - stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n"); - } - { - Statement stm = mod.second; - sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+ - NameUtils.getSafeName(graph, stm.getPredicate()) + " " + - NameUtils.getSafeName(graph, stm.getObject()) + " (" + - stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n"); - } - } - return sb.toString(); - } - -} +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; + +public class GraphChanges { + + private Resource r1; + private Resource r2; + private List deletions; + private List additions; + private List modifications; + + private BijectionMap comparable; + + public static class Modification { + Resource leftSub; + Resource rightSub; + Statement leftStm; + Statement rightStm; + + + int hashCode; + + public Modification(Resource leftSub, Resource rightSub, Statement leftStm, Statement rightStm) { + this.leftSub = leftSub; + this.rightSub = rightSub; + this.leftStm = leftStm; + this.rightStm = rightStm; + + hashCode = leftSub.hashCode() + rightSub.hashCode(); + if (leftStm != null) + hashCode += leftStm.hashCode(); + if (rightStm != null) + hashCode += rightStm.hashCode(); + } + + public boolean isLeftAsserted() { + return leftStm != null && !leftSub.equals(leftStm.getSubject()); + } + + public boolean isRightAsserted() { + return rightStm != null && !rightSub.equals(rightStm.getSubject()); + } + + public Resource getLeftSub() { + return leftSub; + } + + public void setLeftSub(Resource leftSub) { + this.leftSub = leftSub; + } + + public Resource getRightSub() { + return rightSub; + } + + public void setRightSub(Resource rightSub) { + this.rightSub = rightSub; + } + + public Statement getLeftStm() { + return leftStm; + } + + public void setLeftStm(Statement leftStm) { + this.leftStm = leftStm; + } + + public Statement getRightStm() { + return rightStm; + } + + public void setRightStm(Statement rightStm) { + this.rightStm = rightStm; + } + + public Resource getPredicate() { + if (leftStm != null) + return leftStm.getPredicate(); + return rightStm.getPredicate(); + } + + @Override + public boolean equals(Object obj) { + if (obj.getClass() != this.getClass()) + return false; + Modification other = (Modification)obj; + if (!leftSub.equals(other.leftSub)) + return false; + if (!rightSub.equals(other.rightSub)) + return false; + if (leftStm != null) { + if (!leftStm.equals(other.leftStm)) + return false; + } else if (other.leftStm != null) + return false; + if (rightStm != null) { + if (!rightStm.equals(other.rightStm)) + return false; + } else if (other.rightStm != null) + return false; + return true; + } + + @Override + public int hashCode() { + return hashCode; + } + + } + + public GraphChanges(Resource r1, Resource r2, List deletions, List additions, + List modifications, BijectionMap comparable) { + super(); + this.r1 = r1; + this.r2 = r2; + this.deletions = deletions; + this.additions = additions; + this.modifications = modifications; + this.comparable = comparable; + } + + public Resource getResource1() { + return r1; + } + + public Resource getResource2() { + return r2; + } + + public List getAdditions() { + return additions; + } + + public List getDeletions() { + return deletions; + } + + public List getModifications() { + return modifications; + } + + public BijectionMap getComparable() { + return comparable; + } + + public String toString(ReadGraph graph) throws DatabaseException { + StringBuilder sb = new StringBuilder(); + sb.append("Del:\n"); + for (Statement stm : deletions) { + sb.append(toString(graph, stm)); + sb.append("\n"); + } + sb.append("Add:\n"); + for (Statement stm : additions) { + sb.append(toString(graph, stm)); + sb.append("\n"); + } + sb.append("Mod:\n"); + for (Modification mod :modifications) { + sb.append(toString(graph, mod)); + sb.append("\n"); + } + return sb.toString(); + } + + public static String toString(ReadGraph graph, Statement stm) throws DatabaseException{ + return NameUtils.getSafeName(graph, stm.getSubject()) + " "+ + NameUtils.getSafeName(graph, stm.getPredicate()) + " " + + NameUtils.getSafeName(graph, stm.getObject()) + " (" + + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject(); + } + + public static String toString(ReadGraph graph, Modification mod) throws DatabaseException{ + StringBuilder sb = new StringBuilder(); + { + Statement stm = mod.getLeftStm(); + if (stm != null) { + sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+ + NameUtils.getSafeName(graph, stm.getPredicate()) + " " + + truncate(NameUtils.getSafeName(graph, stm.getObject())) + " (" + + mod.getLeftSub() + " " + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n"); + } else { + sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+ mod.getLeftSub() + " N/A\n"); + } + } + { + Statement stm = mod.getRightStm(); + if (stm != null) { + sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+ + NameUtils.getSafeName(graph, stm.getPredicate()) + " " + + truncate(NameUtils.getSafeName(graph, stm.getObject())) + " (" + + mod.getRightSub() + " " + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")"); + } else { + sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+ mod.getRightSub() + " N/A"); + } + + } + return sb.toString(); + } + + public static String truncate(String s) { + if (s.length() < 100) + return s; + return s.substring(0, 100)+"..."; + } + + public String comparableToString(ReadGraph graph) throws DatabaseException { + StringBuilder sb = new StringBuilder(); + sb.append("Comparable:\n"); + for (Entry entry : comparable.getEntries()) { + sb.append(NameUtils.getSafeName(graph, entry.getKey()) + " "+ + NameUtils.getSafeName(graph, entry.getValue()) + " (" + + entry.getKey() + " " +entry.getValue() + ")\n"); + + } + 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); + Resource p1 = del != null ? del.getPredicate() : mod.getPredicate(); + Resource p2 = bijection.getComparable().getRight(p1); + if (p2 == null) + p2 = p1; + Resource o1 = del != null ? del.getObject() : null; + Resource o2 = bijection.getComparable().getRight(o1); + + if (mod.isLeftAsserted()) { + if (sub2 == null) + sub2 = sub1; + + } + if (o2 == null && p2 != null) + o2 = graph.getPossibleObject(sub2, p2); + if (mod.isLeftAsserted()) { + if (o2 == null) + o2 = o1; + } + if (sub2 == null || p2 == null) { + throw new DatabaseException("Did not find matching statement from bijection for (" + sub1 +","+p1+","+o1+"), got (" + sub2 +","+p2+","+o2+")"); + } + if (del == null) { + Modification mod2 = new Modification(sub2, mod.rightSub, null, mod.rightStm); + modifications.add(mod2); + } else { + Collection stms = graph.getStatements(sub2, 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 (" + sub1 +","+p1+","+o1+"), got (" + sub2 +","+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 (" + sub1 +","+p1+","+o1+"), got (" + sub2 +","+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); + } + +}