X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.interop%2Fsrc%2Forg%2Fsimantics%2Finterop%2Ftest%2FGraphComparator.java;h=82b7bfbb2a136177db43fcc08a5dbb3faf20b817;hb=a51a513af1e519f4317b425529e8fb9bb35e3935;hp=c84a8f9f540449f91f8a7ab7de50e86542499227;hpb=7ec38c9ede219eeaf7b55d2d529fc66f098de5dc;p=simantics%2Finterop.git 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 c84a8f9..82b7bfb 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.simantics.interop.test; -import java.math.MathContext; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -30,6 +29,7 @@ import org.simantics.db.Statement; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.DoesNotContainValueException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; import org.simantics.db.exception.ServiceException; import org.simantics.db.exception.ValidationException; import org.simantics.layer0.Layer0; @@ -53,6 +53,7 @@ public class GraphComparator { private Resource r1; private Resource r2; + private Set strong = new HashSet(); // List of relations that identify object, if subject is already identified. private List traversed = new ArrayList(); // list of relations that are traversed (and tested) private List tested = new ArrayList(); // list of relations that are tested, but not traversed private List nonTraversed = new ArrayList(); // list of relations that are not traversed @@ -151,6 +152,14 @@ public class GraphComparator { comparableResources.addAll(matching); } + public void addStrong(Resource r) { + strong.add(r); + } + + public void addStrong(Collection rels) { + strong.addAll(rels); + } + public void clearRels() { traversed.clear(); tested.clear(); @@ -169,20 +178,59 @@ public class GraphComparator { objectsRight.push(r2); + + + Set unreliableLeft = new HashSet(); + Set unreliableRight = new HashSet(); + + while (true) { + if (objectsLeft.isEmpty()) + break; + + + // process compares objects that are identified and searches for more resources to process. + process(objectsLeft, objectsRight, unreliableLeft, unreliableRight); + // process unreliable handles cases where unidentified statements subject and object have been identified + processUnreliable(unreliableLeft, unreliableRight); + // process unreliable handles cases where unidentified resources have path of length one to identified resource + processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight); + if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) { + // comparison is ending, but we have still unprocessed unidentified resources left. + // These cases have longer path than one to identified objects. + processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight); + } + + } + for (Statement s : unreliableLeft) { + if (!comparableStatements.containsLeft(s)) + addDeletion(s); + } + for (Statement s : unreliableRight) { + if (!comparableStatements.containsRight(s)) + addAddition(s); + } + + + } + + private void process(Stack objectsLeft, Stack objectsRight, Set unreliableLeft, Set unreliableRight) throws DatabaseException { List ss1 = new ArrayList(); List ss2 = new ArrayList(); - Stack unreliableLeft = new Stack(); - Stack unreliableRight = new Stack(); - while (!objectsLeft.isEmpty()) { Resource r1 = objectsLeft.pop(); Resource r2 = objectsRight.pop(); + + if (r1.equals(r2)) + continue; if (comparableResources.contains(r1, r2)) { //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2)); continue; } + if (comparableResources.containsLeft(r1) || comparableResources.containsRight(r2)) { + throw new DatabaseException("Comparator error: Trying to map " + r1 + " to " + r2 + " while mappings " + r1 + " to " + comparableResources.getRight(r1) + " and " + comparableResources.getLeft(r2) + " to " + r2 + " exist."); + } comparableResources.map(r1, r2); //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2)); @@ -214,6 +262,52 @@ public class GraphComparator { } } + } + + private void processUnreliable(Set unreliableLeft, Set unreliableRight) { + MapList subjectLeft = new MapList(); + MapList subjectRight = new MapList(); + MapList objectLeft = new MapList(); + MapList objectRight = new MapList(); + + for (Statement s : unreliableLeft) { + subjectLeft.add(s.getSubject(),s); + objectLeft.add(s.getObject(),s); + } + for (Statement s : unreliableRight) { + subjectRight.add(s.getSubject(),s); + objectRight.add(s.getObject(),s); + } + + for (Resource left : subjectLeft.getKeys()) { + if (!comparableResources.containsLeft(left)) + continue; + Resource right = comparableResources.getRight(left); + for (Statement leftS : subjectLeft.getValues(left)) { + Resource leftO = leftS.getObject(); + if (!comparableResources.containsLeft(leftO)) + continue; + if (!unreliableLeft.contains(leftS)) + continue; + Resource rightO = comparableResources.getRight(leftO); + for (Statement rightS : subjectRight.getValues(right)) { + if (!rightS.getObject().equals(rightO)) + continue; + if (!unreliableRight.contains(rightS)) + continue; + if (leftS.getPredicate().equals(rightS.getPredicate()) || + comparableResources.contains(leftS.getPredicate(), rightS.getPredicate())) { + unreliableLeft.remove(leftS); + unreliableRight.remove(rightS); + comparableStatements.map(leftS, rightS); + } + } + } + + } + } + + private void processUnreliable(Set unreliableLeft, Set unreliableRight, Stack objectsLeft, Stack objectsRight) { MapList subjectLeft = new MapList(); MapList subjectRight = new MapList(); MapList objectLeft = new MapList(); @@ -308,29 +402,140 @@ public class GraphComparator { List right = matchingOR.getValues(or); Pair indices = matchingStatements.get(or); - comparableResources.map(ol, or); + //comparableResources.map(ol, or); + objectsLeft.add(ol); + objectsRight.add(or); for (int l = 0; l < left.size(); l++) { int r = indices.first[l]; - comparableStatements.map(left.get(l), right.get(r)); + Statement sl = left.get(l); + Statement sr = right.get(r); + addComparable(sl, sr, true); + unreliableLeft.remove(sl); + unreliableRight.remove(sr); } } } + + } + + private void processUnreliableDeep(Set unreliableLeft, Set unreliableRight, Stack objectsLeft, Stack objectsRight) throws ManyObjectsForFunctionalRelationException, ServiceException { + MapList subjectLeft = new MapList(); + MapList subjectRight = new MapList(); + MapList objectLeft = new MapList(); + MapList objectRight = new MapList(); + for (Statement s : unreliableLeft) { - if (!comparableStatements.containsLeft(s)) - addDeletion(s); + subjectLeft.add(s.getSubject(),s); + objectLeft.add(s.getObject(),s); } for (Statement s : unreliableRight) { - if (!comparableStatements.containsRight(s)) - addAddition(s); + subjectRight.add(s.getSubject(),s); + objectRight.add(s.getObject(),s); + } + for (Resource ol : objectLeft.getKeys()) { + Set pathsLeft = new HashSet(); + for (Resource rel : traversed) { + pathsLeft.addAll(Path.create(g.getStatements(ol, rel))); + } + while (true) { + expand(pathsLeft); + if (pathsLeft.size() == 0) + break; + Collection endPaths = new ArrayList(1); + for (Path p : pathsLeft) { + if (comparableResources.containsLeft(p.getEnd())) { + endPaths.add(p); + } + } + if (endPaths.size() > 0) { + pathsLeft.clear(); + pathsLeft.addAll(endPaths); + break; + } + } + if (pathsLeft.size() > 0) { + Resource sl = objectLeft.getValues(ol).get(0).getSubject(); + Resource sr = comparableResources.getRight(sl); + Collection possibleOR = new ArrayList(); + for (Statement s : subjectRight.getValues(sr)) { + possibleOR.add(s.getObject()); + } + Map> matchingPaths = new HashMap>(); + for (Resource or : possibleOR) { + Set possiblePathsRight = new HashSet(); + for (Path leftPath : pathsLeft) { + possiblePathsRight.addAll(findComparableRight(leftPath, or)); + } + if (possiblePathsRight.size() == pathsLeft.size()) { + matchingPaths.put(or, possiblePathsRight); + } + } + if (matchingPaths.size() > 0) { + if (matchingPaths.size() == 1) { + Resource or = matchingPaths.keySet().iterator().next(); + objectsLeft.add(ol); + objectsRight.add(or); + Collection statementsLeft = objectLeft.getValues(ol); + Collection statementsRight = objectRight.getValues(or); + unreliableLeft.removeAll(statementsLeft); + unreliableRight.removeAll(statementsRight); + System.out.println(); + } else { + System.out.println(); + } + } + } + } + } + + private void expand(Set paths) throws ManyObjectsForFunctionalRelationException, ServiceException { + Set stepPathsLeft = new HashSet(); + if (paths.size() == 0) + return; + int length = paths.iterator().next().getLength() + 1; + for (Path p : paths) { + for (Resource rel : traversed) { + stepPathsLeft.addAll(Path.expand(p,g.getStatements(p.getEnd(), rel))); + } + } + paths.clear(); + for (Path p : stepPathsLeft) { + if (p.getLength() == length) + paths.add(p); + } + } + + private Collection findComparableRight(Path leftPath, Resource beginRight) throws ManyObjectsForFunctionalRelationException, ServiceException { + Set rightPaths = new HashSet(); + rightPaths.addAll(Path.create(g.getStatements(beginRight, getRight(leftPath.getStatements().get(0).getPredicate())))); + for (int i = 1; i < leftPath.getLength(); i++) { + if (rightPaths.size() == 0) + return rightPaths; + Set stepPaths = new HashSet(); + for (Path p : rightPaths) { + stepPaths.addAll(Path.expand(p, g.getStatements(p.getEnd(), getRight(leftPath.getStatements().get(i).getPredicate())))); + } + rightPaths.clear(); + for (Path p : stepPaths) + if (p.getLength() == i+1) + rightPaths.add(p); + } + return rightPaths; - } + } + private Resource getRight(Resource r) { + if (comparableResources.containsLeft(r)) + return comparableResources.getRight(r); + return r; + } + public BijectionMap getComparableStatements() { return comparableStatements; @@ -340,7 +545,14 @@ public class GraphComparator { return new GraphChanges(r1,r2,changes1,changes2,modifications,comparableResources); } - private List filterAsserted(Resource r, Collection in) throws ServiceException { + private void addComparable(Statement left, Statement right, boolean process) { + comparableStatements.map(left, right); + if (!process) { + comparableResources.map(left.getObject(), right.getObject()); + } + } + + public List filterAsserted(Resource r, Collection in) throws ServiceException { List out = new ArrayList(); for (Statement s : in) { if (!s.isAsserted(r)) @@ -349,7 +561,7 @@ public class GraphComparator { } return out; } - + private String printStatement(ReadGraph graph, Statement s) throws ValidationException, ServiceException { return NameUtils.getSafeName(graph, s.getSubject()) + " " + NameUtils.getSafeName(graph, s.getPredicate()) + " " + NameUtils.getSafeName(graph, s.getObject()); } @@ -480,11 +692,10 @@ public class GraphComparator { } } js++; - } } - private void compareStatements(List ss1, List ss2, Stack objectsLeft, Stack objectsRight,Stack unreliableLeft, Stack unreliableRight) throws DatabaseException { + private void compareStatements(List ss1, List ss2, Stack objectsLeft, Stack objectsRight, Collection unreliableLeft, Collection unreliableRight) throws DatabaseException { sortStatement(ss1, ss2); int i1 = 0; @@ -532,61 +743,10 @@ public class GraphComparator { i2 += same2; } - } } - private void compareUnreliableStatements(List ss1, List ss2) throws DatabaseException { - sortStatement(ss1, ss2); - - int i1 = 0; - int i2 = 0; - - while (true) { - if (i1 >= ss1.size()) { - if (i2 >= ss2.size()) { - break; - } else { - while (i2 < ss2.size()) { - System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2))); - - addAddition(ss2.get(i2)); - i2++; - } - break; - } - } else if (i2 >= ss2.size()) { - while (i1 < ss1.size()) { - System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1))); - addDeletion(ss1.get(i1)); - i1++; - } - break; - } - int same1 = sameRel(ss1, i1); - int same2 = sameRel(ss2, i2); - int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate()); - if (c == 0) { - compareStatements(ss1, i1, same1, ss2, i2, same2,null, null, null, null); - i1+=same1; - i2+=same2; - } else if (c < 0) { - for (int i = 0; i < same1; i++) { - System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1))); - addDeletion(ss1.get(i+i1)); - } - i1 += same1; - } else { - for (int i = 0; i < same2; i++) { - System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2))); - addAddition(ss2.get(i+i2)); - } - - i2 += same2; - } - - } - } + private int sameRel(List statements, int off) { if (statements.size() <= off) @@ -604,6 +764,8 @@ public class GraphComparator { } private int compareObject(Resource o1, Resource o2) throws DatabaseException { + if (o1.equals(o2)) + return -1; if (comparableResources.contains(o1, o2)) return (-1); if (comparableResources.containsLeft(o1)) @@ -613,7 +775,7 @@ public class GraphComparator { return comparator.compare(g, o1, o2); } - private void compareStatements(List ss1, int off1, int len1, List ss2, int off2, int len2, Stack objectsLeft, Stack objectsRight, Stack unreliableLeft, Stack unreliableRight) throws DatabaseException { + private void compareStatements(List ss1, int off1, int len1, List ss2, int off2, int len2, Collection objectsLeft, Collection objectsRight, Collection unreliableLeft, Collection unreliableRight) throws DatabaseException { boolean[] used1 = new boolean[len1]; for (int i = 0; i < used1.length; i++) { used1[i] = false; @@ -632,6 +794,14 @@ public class GraphComparator { for (int i2 = off2; i2 < off2 + len2; i2++) { Statement s2 = ss2.get(i2); int d = compareObject(s1.getObject(), s2.getObject()); + if (d == 0) { + for (Resource t : strong) { + if (s1.getPredicate().equals(t) || g.isSubrelationOf(s1.getPredicate(), t)) { + d = 1; + break; + } + } + } diff.add(d); } differences.add(diff); @@ -652,28 +822,7 @@ public class GraphComparator { if (pri == Integer.MAX_VALUE) { } else if (pri == 0) { - Set s1s = new HashSet(); - Set s2s = new HashSet(); - List i1s = priorities.getValues(pri); - for (Integer i1 : i1s) { - - List i2diff = differences.get(i1); - for (int i2 = 0; i2 < i2diff.size(); i2++) { - if (i2diff.get(i2) == pri) { - used1[i1] = true; - used2[i2] = true; - Statement s1 = ss1.get(i1+off1); - Statement s2 = ss2.get(i2+off2); - s1s.add(s1); - s2s.add(s2); - } - } - } - if (unreliableLeft != null) { - unreliableLeft.addAll(s1s); - unreliableRight.addAll(s2s); - } - continue; + } else { List i1s = priorities.getValues(pri); for (Integer i1 : i1s) { @@ -690,19 +839,52 @@ public class GraphComparator { Statement s2 = ss2.get(i2+off2); if (objectsLeft != null) { - - objectsLeft.add(s1.getObject()); - objectsRight.add(s2.getObject()); - + objectsLeft.add(s1.getObject()); + objectsRight.add(s2.getObject()); } - comparableStatements.map(s1, s2); - //comparableResources.map(s1.getObject(), s2.getObject()); + addComparable(s1, s2, true); break; } } } } } + + for (Integer pri : pris) { + if (pri != 0) + continue; + Set s1s = new HashSet(); + Set s2s = new HashSet(); + Set s1i = new HashSet(); + Set s2i = new HashSet(); + List i1s = priorities.getValues(pri); + for (Integer i1 : i1s) { + if (used1[i1]) + continue; + List i2diff = differences.get(i1); + for (int i2 = 0; i2 < i2diff.size(); i2++) { + if (i2diff.get(i2) == pri) { + if (used2[i2]) + continue; + Statement s1 = ss1.get(i1+off1); + Statement s2 = ss2.get(i2+off2); + s1s.add(s1); + s2s.add(s2); + s1i.add(i1); + s2i.add(i2); + } + } + } + if (unreliableLeft != null) { + unreliableLeft.addAll(s1s); + unreliableRight.addAll(s2s); + } + for (Integer i : s1i) + used1[i] = true; + for (Integer i : s2i) + used2[i] = true; + + } for (int i1 = off1; i1 < off1 + len1; i1++) { if (!used1[i1-off1]) { System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1))); @@ -733,8 +915,6 @@ public class GraphComparator { ss1.addAll(g.getStatements(r1, b.HasProperty)); ss2.addAll(g.getStatements(r2, b.HasProperty)); sortStatement(ss1, ss2); -// Collections.sort(ss1, scomp); -// Collections.sort(ss2, scomp); int i1 = 0; int i2 = 0; @@ -763,47 +943,44 @@ public class GraphComparator { Statement s2 = ss2.get(i2); int c = scomp.compare(s1, s2); switch (c) { - case 0:{ - boolean b1 = g.hasValue(s1.getObject()); - boolean b2 = g.hasValue(s2.getObject()); - if (b1 == b2) { - if (b1) { - Object v1 = g.getValue(s1.getObject()); - Object v2 = g.getValue(s2.getObject()); - boolean eq = compareValue(v1, v2); - if (!eq) { - addModification(s1, s2); - comparableStatements.map(s1, s2); - comparableResources.map(s1.getObject(),s2.getObject()); + case 0:{ + boolean b1 = g.hasValue(s1.getObject()); + boolean b2 = g.hasValue(s2.getObject()); + if (b1 == b2) { + if (b1) { + Object v1 = g.getValue(s1.getObject()); + Object v2 = g.getValue(s2.getObject()); + boolean eq = compareValue(v1, v2); + if (!eq) { + addModification(s1, s2); + addComparable(s1, s2, false); + } + } else { + compareProps(s1.getObject(), s2.getObject()); } } else { - compareProps(s1.getObject(), s2.getObject()); + addModification(s1, s2); + addComparable(s1, s2, false); } - } else { - addModification(s1, s2); - comparableStatements.map(s1, s2); - comparableResources.map(s1.getObject(),s2.getObject()); + i1++; + i2++; + break; + } + case -1:{ + System.out.println("Compare Prop diff1s " + printStatement(g,s1)); + addDeletion(s1); + i1++; + break; + } + + case 1:{ + System.out.println("Compare Prop diff2s " + printStatement(g,s2)); + addAddition(s2); + i2++; + break; } - i1++; - i2++; - break; - } - case -1:{ - System.out.println("Compare Prop diff1s " + printStatement(g,s1)); - addDeletion(s1); - i1++; - break; - } - - case 1:{ - System.out.println("Compare Prop diff2s " + printStatement(g,s2)); - addAddition(s2); - i2++; - break; - } } - - + } ss1.clear(); @@ -811,7 +988,6 @@ public class GraphComparator { } - public static boolean compareValue(Object v1, Object v2) { if (v1 instanceof Object[] && v2 instanceof Object[]) return Arrays.deepEquals((Object[])v1, (Object[])v2); @@ -832,7 +1008,6 @@ public class GraphComparator { } - public class PredicateComparator implements Comparator { @Override public int compare(Statement o1, Statement o2) { @@ -891,8 +1066,6 @@ public class GraphComparator { } } - - public class ResComparator implements Comparator { @Override public int compare(Resource o1, Resource o2) { @@ -905,6 +1078,5 @@ public class GraphComparator { return 0; } } - - + }