From 6f66967403916102ef5cb0d564cb357206fb3c69 Mon Sep 17 00:00:00 2001 From: luukkainen Date: Thu, 18 Aug 2011 15:21:44 +0000 Subject: [PATCH] Comparator bug fixes. git-svn-id: https://www.simantics.org/svn/simantics/interoperability/trunk@21822 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.interop/META-INF/MANIFEST.MF | 3 +- .../simantics/interop/test/GraphChanges.java | 34 +++ .../interop/test/GraphComparator.java | 286 +++++++++++++----- .../interop/test/GraphComparatorViewer.java | 70 ++++- 4 files changed, 303 insertions(+), 90 deletions(-) create mode 100644 org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java diff --git a/org.simantics.interop/META-INF/MANIFEST.MF b/org.simantics.interop/META-INF/MANIFEST.MF index d11a186..75bed0e 100644 --- a/org.simantics.interop/META-INF/MANIFEST.MF +++ b/org.simantics.interop/META-INF/MANIFEST.MF @@ -21,4 +21,5 @@ Require-Bundle: org.eclipse.ui, Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: org.simantics.interop.issues, - org.simantics.interop.stubs + org.simantics.interop.stubs, + org.simantics.interop.test diff --git a/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java b/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java new file mode 100644 index 0000000..871be6d --- /dev/null +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java @@ -0,0 +1,34 @@ +package org.simantics.interop.test; + +import java.util.List; + +import org.simantics.db.Statement; +import org.simantics.utils.datastructures.Pair; + +public class GraphChanges { + + private List deletions; + private List additions; + private List> modifications; + + public GraphChanges(List deletions, List additions, + List> modifications) { + super(); + this.deletions = deletions; + this.additions = additions; + this.modifications = modifications; + } + + public List getAdditions() { + return additions; + } + + public List getDeletions() { + return deletions; + } + + public List> getModifications() { + return modifications; + } + +} 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 d9d2657..dff6672 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java @@ -16,20 +16,23 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.Stack; 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.DoesNotContainValueException; import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; import org.simantics.db.exception.ServiceException; import org.simantics.db.exception.ValidationException; import org.simantics.layer0.Layer0; -import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.utils.datastructures.BijectionMap; import org.simantics.utils.datastructures.MapList; +import org.simantics.utils.datastructures.Pair; /** * Compares two subgraphs and reports differences. @@ -48,10 +51,15 @@ public class GraphComparator { 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 private List changes1 = new ArrayList(); private List changes2 = new ArrayList(); + private List> modifications = new ArrayList>(); + private Set changes1Set = new HashSet(); + private Set changes2Set = new HashSet(); + private Set> modificationsSet = new HashSet>(); + private BijectionMap comparable = new BijectionMap(); @@ -64,7 +72,7 @@ public class GraphComparator { ArrayList rs2 = new ArrayList(); ArrayList ss1 = new ArrayList(); ArrayList ss2 = new ArrayList(); - Comparator scomp = new StatementComparator(); + Comparator scomp = new PredicateComparator(); Comparator rcomp = new ResourceComparator(); @@ -76,6 +84,14 @@ public class GraphComparator { traversed.addAll(rels); } + public void addNonTraversed(Resource rel) { + nonTraversed.add(rel); + } + + public void addNonTraversed(Collection rels) { + nonTraversed.addAll(rels); + } + public void addTested(Resource rel) { tested.add(rel); } @@ -93,27 +109,35 @@ public class GraphComparator { this.g = g; this.b = Layer0.getInstance(g); + changes1Set.clear(); + changes2Set.clear(); + modificationsSet.clear(); changes1.clear(); changes2.clear(); + modifications.clear(); Stack stack1 = new Stack(); Stack stack2 = new Stack(); stack1.push(r1); stack2.push(r2); - ArrayList ss1 = new ArrayList(); - ArrayList ss2 = new ArrayList(); + List ss1 = new ArrayList(); + List ss2 = new ArrayList(); while (!stack1.isEmpty()) { r1 = stack1.pop(); r2 = stack2.pop(); - System.out.println("test " + GraphUtils.getReadableName(g, r1) + " " + GraphUtils.getReadableName(g, r2)); + System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2)); compareProps(r1, r2); for (Resource rel : tested) { - filterTraversed(g.getStatements(r1, rel), ss1); - filterTraversed(g.getStatements(r2, rel), ss2); + ss1.addAll(g.getStatements(r1, rel)); + ss2.addAll(g.getStatements(r2, rel)); + ss1 = filterAsserted(r1, ss1); + ss2 = filterAsserted(r2, ss2); + ss1 = filterTraversed(ss1); + ss2 = filterTraversed(ss2); compareStatement(ss1, ss2, null, null); ss1.clear(); @@ -123,6 +147,8 @@ public class GraphComparator { for (Resource rel : traversed) { ss1.addAll(g.getStatements(r1, rel)); ss2.addAll(g.getStatements(r2, rel)); + ss1 = filterAsserted(r1, ss1); + ss2 = filterAsserted(r2, ss2); compareStatement(ss1, ss2, stack1, stack2); ss1.clear(); ss2.clear(); @@ -130,19 +156,39 @@ public class GraphComparator { } } - public Collection getChanges1() { - return changes1; - } - public Collection getChanges2() { - return changes2; - } public BijectionMap getComparable() { return comparable; } - private void filterTraversed(Collection in, Collection out) throws ServiceException { + public GraphChanges getChanges() { +// List deletions = new ArrayList(); +// List additions = new ArrayList(); +// deletions.addAll(changes1); +// additions.addAll(changes2); +// Collections.sort(deletions, new FullStatementComparator()); +// Collections.sort(additions, new FullStatementComparator()); +// return new GraphChanges(deletions, additions, modifications); + return new GraphChanges(changes1,changes2,modifications); + } + + private List filterAsserted(Resource r, Collection in) throws ServiceException { + List out = new ArrayList(); + for (Statement s : in) { + if (!s.isAsserted(r)) + out.add(s); + + } + 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()); + } + + private List filterTraversed(Collection in) throws ServiceException { + List out = new ArrayList(); for (Statement s : in) { boolean usable = true; for (Resource r : traversed) { @@ -156,6 +202,30 @@ public class GraphComparator { } } + return out; + } + + + private void addDeletion(Statement s) { + if (!changes1Set.contains(s)) { + changes1Set.add(s); + changes1.add(s); + } + } + + private void addAddition(Statement s) { + if (!changes2Set.contains(s)) { + changes2Set.add(s); + changes2.add(s); + } + } + + private void addModification(Statement s1, Statement s2) { + Pair mod = new Pair(s1,s2); + if (!modificationsSet.contains(mod)) { + modificationsSet.add(mod); + modifications.add(mod); + } } private void compareStatement(List ss1, List ss2, Stack stack1, Stack stack2) throws ServiceException, DoesNotContainValueException, ValidationException { @@ -171,14 +241,17 @@ public class GraphComparator { break; } else { while (i2 < ss2.size()) { - changes2.add(ss2.get(i2)); + System.out.println("Compare Statement diff2 " + printStatement(g,ss2.get(i2))); + + addAddition(ss2.get(i2)); i2++; } break; } } else if (i2 >= ss2.size()) { while (i1 < ss1.size()) { - changes1.add(ss1.get(i1)); + System.out.println("Compare Statement diff1 " + printStatement(g,ss1.get(i1))); + addDeletion(ss1.get(i1)); i1++; } break; @@ -192,13 +265,16 @@ public class GraphComparator { i2+=same2; } else if (c < 0) { for (int i = 0; i < same1; i++) { - changes1.add(ss1.get(i+i1)); + System.out.println("Compare Statement diff1 " + printStatement(g,ss1.get(i+i1))); + addDeletion(ss1.get(i+i1)); } i1 += same1; - } else { - for (int i = 0; i < same2; i++) { - changes2.add(ss2.get(i+i2)); + } else { + for (int i = 0; i < same2; i++) { + System.out.println("Compare Statement diff2 " + printStatement(g,ss2.get(i+i2))); + addAddition(ss2.get(i+i2)); } + i2 += same2; } @@ -271,7 +347,7 @@ public class GraphComparator { for (int i2 = 0; i2 < i2diff.size(); i2++) { if (i2diff.get(i2) == pri) { if (used2[i2]) - break; + continue; used1[i1] = true; used2[i2] = true; if (stack1 != null) { @@ -282,24 +358,30 @@ public class GraphComparator { // using compareProps assumes that referenced objects are the same (references are not different) // using propsDiffCount assumes that objects are different, and cannot report changes in referred object. - //compareProps(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject()); - int diff = propsDiffCount(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject()); - if (diff != 0) { - changes1.add(ss1.get(i1+off1)); - changes2.add(ss2.get(i2+off2)); - } + +// int diff = propsDiffCount(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject()); +// if (diff != 0) { +// //changes1.add(ss1.get(i1+off1)); +// //changes2.add(ss2.get(i2+off2)); +// modifies.add(new Pair(ss1.get(i1+off1), ss2.get(i2+off2))); +// } } + break; } } } } for (int i1 = off1; i1 < off1 + len1; i1++) { - if (!used1[i1-off1]) - changes1.add(ss1.get(i1)); + if (!used1[i1-off1]) { + System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1))); + addDeletion(ss1.get(i1)); + } } for (int i2 = off2; i2 < off2 + len2; i2++) { - if (!used2[i2-off2]) - changes2.add(ss2.get(i2)); + if (!used2[i2-off2]) { + System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2))); + addAddition(ss2.get(i2)); + } } } @@ -332,11 +414,11 @@ public class GraphComparator { * compares properties, assumes functional relations * @param r1 * @param r2 - * @throws ManyObjectsForFunctionalRelationException * @throws ServiceException * @throws DoesNotContainValueException + * @throws ValidationException */ - private void compareProps(Resource r1, Resource r2) throws ManyObjectsForFunctionalRelationException, ServiceException, DoesNotContainValueException { + private void compareProps(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException { ArrayList ss1 = new ArrayList(); ArrayList ss2 = new ArrayList(); ss1.addAll(g.getStatements(r1, b.HasProperty)); @@ -353,14 +435,16 @@ public class GraphComparator { break; else { while (i2 < ss2.size()) { - changes2.add(ss2.get(i2)); + System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2))); + addAddition(ss2.get(i2)); i2++; } break; } } else if (i2 >= ss2.size()) { while (i1 < ss1.size()) { - changes1.add(ss1.get(i1)); + System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1))); + addDeletion(ss1.get(i1)); i1++; } break; @@ -379,19 +463,33 @@ public class GraphComparator { boolean eq = false; if (v1 instanceof Object[] && v2 instanceof Object[]) eq = Arrays.deepEquals((Object[])v1, (Object[])v2); + else if (v1 instanceof int[] && v2 instanceof int[]) + eq = Arrays.equals((int[])v1, (int[])v2); + else if (v1 instanceof float[] && v2 instanceof float[]) + eq = Arrays.equals((float[])v1, (float[])v2); + else if (v1 instanceof double[] && v2 instanceof double[]) + eq = Arrays.equals((double[])v1, (double[])v2); + else if (v1 instanceof long[] && v2 instanceof long[]) + eq = Arrays.equals((long[])v1, (long[])v2); + else if (v1 instanceof byte[] && v2 instanceof byte[]) + eq = Arrays.equals((byte[])v1, (byte[])v2); + else if (v1 instanceof boolean[] && v2 instanceof boolean[]) + eq = Arrays.equals((boolean[])v1, (boolean[])v2); else eq = v1.equals(v2); if (!eq) { - changes1.add(s1); - changes2.add(s2); + //changes1.add(s1); + //changes2.add(s2); + addModification(s1, s2); comparable.map(s1, s2); } } else { compareProps(s1.getObject(), s2.getObject()); } } else { - changes1.add(s1); - changes2.add(s2); + //changes1.add(s1); + //changes2.add(s2); + addModification(s1, s2); comparable.map(s1, s2); } i1++; @@ -399,13 +497,15 @@ public class GraphComparator { break; } case -1:{ - changes1.add(s1); + System.out.println("Compare Prop diff1s " + printStatement(g,s1)); + addDeletion(s1); i1++; break; } case 1:{ - changes2.add(s2); + System.out.println("Compare Prop diff2s " + printStatement(g,s2)); + addAddition(s2); i2++; break; } @@ -455,46 +555,57 @@ 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 = false; - if (v1 instanceof Object[] && v2 instanceof Object[]) - eq = Arrays.deepEquals((Object[])v1, (Object[])v2); - else - eq = v1.equals(v2); - if (!eq) { - count++; + 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 = false; + if (v1 instanceof Object[] && v2 instanceof Object[]) + eq = Arrays.deepEquals((Object[])v1, (Object[])v2); + else if (v1 instanceof int[] && v2 instanceof int[]) + eq = Arrays.equals((int[])v1, (int[])v2); + else if (v1 instanceof float[] && v2 instanceof float[]) + eq = Arrays.equals((float[])v1, (float[])v2); + else if (v1 instanceof double[] && v2 instanceof double[]) + eq = Arrays.equals((double[])v1, (double[])v2); + else if (v1 instanceof long[] && v2 instanceof long[]) + eq = Arrays.equals((long[])v1, (long[])v2); + else if (v1 instanceof byte[] && v2 instanceof byte[]) + eq = Arrays.equals((byte[])v1, (byte[])v2); + else if (v1 instanceof boolean[] && v2 instanceof boolean[]) + eq = Arrays.equals((boolean[])v1, (boolean[])v2); + else + eq = v1.equals(v2); + if (!eq) { + count++; + } + //System.out.println("Prop count values " + v1 + " " + v2); + } else { + count += propsDiffCount(s1.getObject(), s2.getObject()); } - //System.out.println("Prop count values " + v1 + " " + v2); } else { - count += propsDiffCount(s1.getObject(), s2.getObject()); + //System.out.println("Props count structural vs literal"); + count++; } - } else { - //System.out.println("Props count structural vs literal"); + i1++; + i2++; + break; + } + case -1:{ count++; + i1++; + break; + } + + case 1:{ + count++; + i2++; + break; } - i1++; - i2++; - break; - } - case -1:{ - count++; - i1++; - break; - } - - case 1:{ - count++; - i2++; - break; - } } - } @@ -505,13 +616,32 @@ public class GraphComparator { - public class StatementComparator implements Comparator { + public class PredicateComparator implements Comparator { + @Override + public int compare(Statement o1, Statement o2) { + if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId()) + return -1; + if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId()) + return 1; + return 0; + } + } + + public class FullStatementComparator implements Comparator { @Override public int compare(Statement o1, Statement o2) { + if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId()) + return -1; + if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId()) + return 1; if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId()) return -1; if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId()) return 1; + if (o1.getObject().getResourceId() < o2.getObject().getResourceId()) + return -1; + if (o1.getObject().getResourceId() > o2.getObject().getResourceId()) + return 1; return 0; } } @@ -523,7 +653,7 @@ public class GraphComparator { public int compare(Resource o1, Resource o2) { if (o1.getResourceId() < o2.getResourceId()) return -1; - if (o2.getResourceId() > o2.getResourceId()) + if (o1.getResourceId() > o2.getResourceId()) return 1; return 0; } diff --git a/org.simantics.interop/src/org/simantics/interop/test/GraphComparatorViewer.java b/org.simantics.interop/src/org/simantics/interop/test/GraphComparatorViewer.java index fa65da4..3f51089 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphComparatorViewer.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphComparatorViewer.java @@ -39,6 +39,7 @@ import org.simantics.db.Session; import org.simantics.db.Statement; import org.simantics.db.common.ResourceArray; import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidResourceReferenceException; import org.simantics.db.exception.ServiceException; @@ -46,13 +47,13 @@ import org.simantics.db.exception.ValidationException; import org.simantics.db.request.Read; import org.simantics.db.service.SerialisationSupport; import org.simantics.layer0.Layer0; -import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.ui.SimanticsUI; import org.simantics.ui.dnd.LocalObjectTransfer; import org.simantics.ui.dnd.ResourceReferenceTransfer; import org.simantics.ui.dnd.ResourceTransferUtils; import org.simantics.ui.utils.ResourceAdaptionUtils; import org.simantics.utils.datastructures.BijectionMap; +import org.simantics.utils.datastructures.Pair; /** * Simple multi line text viewer for seeing differences in two subgraphs. @@ -131,14 +132,61 @@ public class GraphComparatorViewer extends ViewPart{ BijectionMap map = comparator.getComparable(); Map indices = new HashMap(); final StringBuilder sb1 = new StringBuilder(); + final StringBuilder sb2 = new StringBuilder(); int index = 0; - for (Statement s : comparator.getChanges1()) { + + GraphChanges changes = comparator.getChanges(); + + for (Pair mod : changes.getModifications()) { + { + String sub; + try { + Statement s = mod.first; + sub = NameUtils.getSafeName(graph, s.getSubject()); + String pre = NameUtils.getSafeName(graph, s.getPredicate()); + String obj = NameUtils.getSafeName(graph, s.getObject()); + if (map.containsLeft(s)) { + index++; + indices.put(s, index); + sb1.append("["+index + "] "); + } + sb1.append(sub + " - " + pre + " - " + obj); + sb1.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]"); + sb1.append("\n"); + } catch (ValidationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } + } + { + String sub; + try { + Statement s = mod.second; + sub = NameUtils.getSafeName(graph, s.getSubject()); + String pre = NameUtils.getSafeName(graph, s.getPredicate()); + String obj = NameUtils.getSafeName(graph, s.getObject()); + if (map.containsRight(s)) { + index = indices.get(map.getLeft(s)); + sb2.append("["+index + "] "); + } + sb2.append(sub + " - " + pre + " - " + obj); + sb2.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]"); + sb2.append("\n"); + } catch (ValidationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } + } + } + for (Statement s : changes.getDeletions()) { String sub; try { - sub = GraphUtils.getReadableName(graph, s.getSubject()); - String pre = GraphUtils.getReadableName(graph, s.getPredicate()); - String obj = GraphUtils.getReadableName(graph, s.getObject()); + sub = NameUtils.getSafeName(graph, s.getSubject()); + String pre = NameUtils.getSafeName(graph, s.getPredicate()); + String obj = NameUtils.getSafeName(graph, s.getObject()); if (map.containsLeft(s)) { index++; indices.put(s, index); @@ -154,13 +202,13 @@ public class GraphComparatorViewer extends ViewPart{ } } - final StringBuilder sb2 = new StringBuilder(); - for (Statement s : comparator.getChanges2()) { + + for (Statement s : changes.getAdditions()) { String sub; try { - sub = GraphUtils.getReadableName(graph, s.getSubject()); - String pre = GraphUtils.getReadableName(graph, s.getPredicate()); - String obj = GraphUtils.getReadableName(graph, s.getObject()); + sub = NameUtils.getSafeName(graph, s.getSubject()); + String pre = NameUtils.getSafeName(graph, s.getPredicate()); + String obj = NameUtils.getSafeName(graph, s.getObject()); if (map.containsRight(s)) { index = indices.get(map.getLeft(s)); sb2.append("["+index + "] "); @@ -241,7 +289,7 @@ public class GraphComparatorViewer extends ViewPart{ @Override public String perform(ReadGraph graph) throws DatabaseException { - return GraphUtils.getReadableName(graph, r); + return NameUtils.getSafeName(graph, r); } })); } catch (DatabaseException e) { -- 2.47.1