import java.util.Set;
import java.util.Stack;
+import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.Session;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.interop.test.GraphChanges.Modification;
import org.simantics.layer0.Layer0;
import org.simantics.utils.datastructures.BijectionMap;
import org.simantics.utils.datastructures.MapList;
private Resource r1;
private Resource r2;
- private Set<Resource> strong = new HashSet<Resource>(); // List of relations that identify object, if subject is already identified.
- private List<Resource> traversed = new ArrayList<Resource>(); // list of relations that are traversed (and tested)
- private List<Resource> tested = new ArrayList<Resource>(); // list of relations that are tested, but not traversed
- private List<Resource> nonTraversed = new ArrayList<Resource>(); // list of relations that are not traversed
- private List<Resource> nonTested = new ArrayList<Resource>(); // list of relations that are not tested
-
- private List<Statement> changes1 = new ArrayList<Statement>();
- private List<Statement> changes2 = new ArrayList<Statement>();
- private List<Pair<Statement,Statement>> modifications = new ArrayList<Pair<Statement,Statement>>();
- private Set<Statement> changes1Set = new HashSet<Statement>();
- private Set<Statement> changes2Set = new HashSet<Statement>();
- private Set<Pair<Statement,Statement>> modificationsSet = new HashSet<Pair<Statement,Statement>>();
+ private Set<Resource> strong = new HashSet<>(); // List of relations that identify object, if subject is already identified.
+ private List<Resource> traversed = new ArrayList<>(); // list of relations that are traversed (and tested)
+ private List<Resource> tested = new ArrayList<>(); // list of relations that are tested, but not traversed
+ private List<Resource> nonTraversed = new ArrayList<>(); // list of relations that are not traversed
+ private List<Resource> nonTested = new ArrayList<>(); // list of relations that are not tested
+
+ private List<Statement> changes1 = new ArrayList<>();
+ private List<Statement> changes2 = new ArrayList<>();
+ private List<Modification> modifications = new ArrayList<>();
+ private Set<Statement> changes1Set = new HashSet<>();
+ private Set<Statement> changes2Set = new HashSet<>();
+ private Set<Modification> modificationsSet = new HashSet<>();
- private BijectionMap<Statement, Statement> comparableStatements = new BijectionMap<Statement, Statement>();
- private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();
+ private BijectionMap<Statement, Statement> comparableStatements = new BijectionMap<>();
+ private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<>();
private Set<Resource> processedResources = new HashSet<Resource>();
}
public void addComparableResources(Resource r1, Resource r2) {
+ if (DEBUG)
+ System.out.println("Preset " + r1 + " = " + r2);
comparableResources.map(r1, r2);
}
public void addComparableResources(BijectionMap<Resource, Resource> matching) {
+ if (DEBUG) {
+ for (Entry<Resource, Resource> entry : matching.getEntries())
+ System.out.println("Preset " + entry.getKey() + " = " + entry.getValue());
+ }
comparableResources.addAll(matching);
}
this.g = g;
this.b = Layer0.getInstance(g);
comparator.setComparator(this);
+ comparator.initialize(g, r1, r2);
Stack<Resource> objectsLeft = new Stack<Resource>();
Stack<Resource> objectsRight = new Stack<Resource>();
comparator.setComparator(this);
+ session.syncRequest(new ReadRequest() {
+
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ comparator.initialize(graph, r1, r2);
+ }
+ });
+
addComparable(r1, r2);
final Stack<Resource> objectsLeft = new Stack<Resource>();
// These cases have longer path than one to identified objects.
processUnreliableDeep(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))
- if (s.getObject().getResourceId() == 303248)
- System.out.println();
addDeletion(s);
}
for (Statement s : unreliableRight) {
if (r1.equals(r2))
continue;
-
if (processedResources.contains(r1))
continue;
processedResources.add(r1);
if (leftPath.getLength() != rightPath.getLength())
continue;
if (comparableResources.contains(leftPath.getEnd(), rightPath.getEnd())) {
- map.map(leftPath, rightPath);
- break;
+ boolean match = true;
+ for (int i = 0; i < leftPath.getLength(); i++) {
+ Statement sl = leftPath.getStatements().get(i);
+ Statement sr = rightPath.getStatements().get(i);
+ if (!sl.getPredicate().equals(sr.getPredicate()) && !comparableResources.contains(sl.getPredicate(), sr.getPredicate())) {
+ match = false;
+ break;
+ }
+ if ((getComparableResources().containsLeft(sl.getObject()) || getComparableResources().containsRight(sr.getObject())) && !getComparableResources().contains(sl.getObject(), sr.getObject())) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ map.map(leftPath, rightPath);
+ break;
+ }
}
}
}
throw new DatabaseException("Comparator error: Trying to map " + left + " to " + right + " while mappings " + left + " to " + comparableResources.getRight(left) + " and " + comparableResources.getLeft(right) + " to " + right + " exist.");
} else {
if (DEBUG) System.out.println(left + " = " + right);
- comparableResources.map(left, right);
- //if (left.getResourceId() == 313071 && right.getResourceId() == 325324)
- if (left.getResourceId() == 313231 && right.getResourceId() == 337775)
- System.out.println();
+ comparableResources.map(left, right);
}
}
return out;
}
+ public List<Statement> filterAssertedDuplicates(Resource r, List<Statement> in) throws DatabaseException {
+ List<Statement> out = new ArrayList<Statement>();
+ for (int i = 0; i < in.size(); i++) {
+ Statement s = in.get(i);
+ if (!s.isAsserted(r))
+ out.add(s);
+ else {
+ boolean has = false;
+ if (i > 1 && in.get(i-1).getPredicate().equals(s.getPredicate()))
+ has = true;
+ else if (i < in.size()-1 && in.get(i+1).getPredicate().equals(s.getPredicate()))
+ has = true;
+ if (!has)
+ out.add(s);
+ }
+
+ }
+ for (Statement s : in) {
+ if (!s.isAsserted(r))
+ out.add(s);
+
+ }
+ return out;
+ }
+
private String printStatement(ReadGraph graph, Statement s) throws DatabaseException {
}
}
- private void addModification(Statement s1, Statement s2) {
- Pair<Statement, Statement> mod = new Pair<Statement, Statement>(s1,s2);
+ private void addModification(Resource left, Statement leftstm, Resource right, Statement rightstm) {
+ Modification mod = new Modification(left, right, leftstm, rightstm);
if (!modificationsSet.contains(mod)) {
modificationsSet.add(mod);
modifications.add(mod);
ss1 = filterNonTested(ss1);
ss2 = filterNonTested(ss2);
sortStatement(ss1, ss2);
+ // getStatements(r1, b.HasProperty) returns both instance and asserted statements for the same property relation.
+ ss1 = filterAssertedDuplicates(r1, ss1);
+ ss2 = filterAssertedDuplicates(r2, ss2);
int i1 = 0;
int i2 = 0;
break;
else {
while (i2 < ss2.size()) {
- if (DEBUG) System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));
- addAddition(ss2.get(i2));
+ Statement s = ss2.get(i2);
+ if (DEBUG) System.out.println("Compare Prop diff2 " + printStatement(g,s));
+ if (!s.isAsserted(r2))
+ addAddition(s);
i2++;
}
break;
}
} else if (i2 >= ss2.size()) {
while (i1 < ss1.size()) {
- if (DEBUG) System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));
- addDeletion(ss1.get(i1));
+ Statement s = ss1.get(i1);
+ if (DEBUG) System.out.println("Compare Prop diff1 " + printStatement(g,s));
+ if (!s.isAsserted(r1))
+ addDeletion(s);
i1++;
}
break;
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);
+ // Literals
+ boolean eq = compareValue(g,b,s1.getObject(), s2.getObject());
if (!eq) {
- addModification(s1, s2);
- addComparable(s1, s2);
+ addModification(r1,s1,r2,s2);
+ if (!s1.isAsserted(r1) && !s2.isAsserted(r2))
+ addComparable(s1, s2);
}
} else {
- if (!s1.getObject().equals(s1.getSubject()) && !s2.getObject().equals(s2.getSubject()))
- compareProps(s1.getObject(), s2.getObject());
+ // Non literal properties.
+ if (comparator.compare(g, s1.getObject(), s2.getObject()) != ResourceComparator.NO_MATCH) {
+ if (!s1.getObject().equals(s1.getSubject()) && !s2.getObject().equals(s2.getSubject()))
+ // TODO compare props matches objects, so this is questionable.
+ compareProps(s1.getObject(), s2.getObject());
+ else
+ addModification(r1,s1,r2,s2);
+ } else {
+ addModification(r1,s1,r2,s2);
+ }
}
} else {
- addModification(s1, s2);
- addComparable(s1, s2);
+ addModification(r1,s1,r2,s2);
+ if (!s1.isAsserted(r1) && !s2.isAsserted(r2))
+ addComparable(s1, s2);
}
i1++;
i2++;
}
+ public static boolean compareValue(ReadGraph g, Layer0 b, Resource r1, Resource r2) throws DatabaseException {
+ Resource t1 = g.getSingleType(r1);
+ Resource t2 = g.getSingleType(r2);
+ if (!t1.equals(t2))
+ return false;
+ if (t1.equals(b.Integer)) {
+ int v1 = g.getValue(r1, Bindings.INTEGER);
+ int v2 = g.getValue(r2, Bindings.INTEGER);
+ return v1 == v2;
+ } else if (t1.equals(b.Float)) {
+ float v1 = g.getValue(r1, Bindings.FLOAT);
+ float v2 = g.getValue(r2, Bindings.FLOAT);
+ return v1 == v2;
+ } else if (t1.equals(b.Double)) {
+ double v1 = g.getValue(r1, Bindings.DOUBLE);
+ double v2 = g.getValue(r2, Bindings.DOUBLE);
+ return v1 == v2;
+ } else if (t1.equals(b.String)) {
+ String v1 = g.getValue(r1, Bindings.STRING);
+ String v2 = g.getValue(r2, Bindings.STRING);
+ return v1.equals(v2);
+ } else if (t1.equals(b.Boolean)) {
+ boolean v1 = g.getValue(r1, Bindings.BOOLEAN);
+ boolean v2 = g.getValue(r2, Bindings.BOOLEAN);
+ return v1 == v2;
+ } else if (t1.equals(b.Byte)) {
+ byte v1 = g.getValue(r1, Bindings.BYTE);
+ byte v2 = g.getValue(r2, Bindings.BYTE);
+ return v1 == v2;
+ } else if (t1.equals(b.Long)) {
+ long v1 = g.getValue(r1, Bindings.LONG);
+ long v2 = g.getValue(r2, Bindings.LONG);
+ return v1 == v2;
+ } else if (t1.equals(b.IntegerArray)) {
+ int[] v1 = g.getValue(r1, Bindings.INT_ARRAY);
+ int[] v2 = g.getValue(r2, Bindings.INT_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else if (t1.equals(b.FloatArray)) {
+ float[] v1 = g.getValue(r1, Bindings.FLOAT_ARRAY);
+ float[] v2 = g.getValue(r2, Bindings.FLOAT_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else if (t1.equals(b.DoubleArray)) {
+ double[] v1 = g.getValue(r1, Bindings.DOUBLE_ARRAY);
+ double[] v2 = g.getValue(r2, Bindings.DOUBLE_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else if (t1.equals(b.StringArray)) {
+ String[] v1 = g.getValue(r1, Bindings.STRING_ARRAY);
+ String[] v2 = g.getValue(r2, Bindings.STRING_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else if (t1.equals(b.BooleanArray)) {
+ boolean[] v1 = g.getValue(r1, Bindings.BOOLEAN_ARRAY);
+ boolean[] v2 = g.getValue(r2, Bindings.BOOLEAN_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else if (t1.equals(b.ByteArray)) {
+ byte[] v1 = g.getValue(r1, Bindings.BYTE_ARRAY);
+ byte[] v2 = g.getValue(r2, Bindings.BYTE_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else if (t1.equals(b.LongArray)) {
+ long[] v1 = g.getValue(r1, Bindings.LONG_ARRAY);
+ long[] v2 = g.getValue(r2, Bindings.LONG_ARRAY);
+ return Arrays.equals(v1,v2);
+ } else {
+ Object v1 = g.getValue(r1);
+ Object v2 = g.getValue(r2);
+ return compareValue(v1, v2);
+ }
+
+ }
+
public static boolean compareValue(Object v1, Object v2) {
if (v1 instanceof Object[] && v2 instanceof Object[])
return Arrays.deepEquals((Object[])v1, (Object[])v2);