]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
Better handling of unidentified resources (resources that have no name, or other...
authorluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 27 Sep 2011 10:07:32 +0000 (10:07 +0000)
committerMarko Luukkainen <marko.luukkainen@vtt.fi>
Thu, 2 Feb 2017 09:22:16 +0000 (11:22 +0200)
- This fixes connection synchronization

git-svn-id: https://www.simantics.org/svn/simantics/interoperability/trunk@22426 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
org.simantics.interop/src/org/simantics/interop/test/ResourceComparator.java [moved from org.simantics.interop/src/org/simantics/interop/test/ObjectComparator.java with 74% similarity]
org.simantics.interop/src/org/simantics/interop/test/TypeComparator.java

index 4fb9cf24e88e9f2b8078c5e3036019445aec2a8d..c84a8f9f540449f91f8a7ab7de50e86542499227 100644 (file)
  *******************************************************************************/\r
 package org.simantics.interop.test;\r
 \r
+import java.math.MathContext;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
 import java.util.Collection;\r
 import java.util.Collections;\r
 import java.util.Comparator;\r
+import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.List;\r
+import java.util.Map;\r
 import java.util.Set;\r
 import java.util.Stack;\r
 \r
@@ -66,10 +69,10 @@ public class GraphComparator {
        private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();\r
        \r
        \r
-       private ObjectComparator comparator;\r
+       private ResourceComparator comparator;\r
        \r
        private Comparator<Statement> scomp = new PredicateComparator();\r
-       private Comparator<Resource> rcomp = new ResourceComparator();\r
+       private Comparator<Resource> rcomp = new ResComparator();\r
        \r
        // runtime attributes\r
        \r
@@ -82,7 +85,7 @@ public class GraphComparator {
                comparator = new TypeComparator();\r
        }\r
        \r
-       public GraphComparator(Resource r1, Resource r2, ObjectComparator comparator) {\r
+       public GraphComparator(Resource r1, Resource r2, ResourceComparator comparator) {\r
                this.r1 = r1;\r
                this.r2 = r2;\r
                this.comparator = comparator;\r
@@ -160,18 +163,21 @@ public class GraphComparator {
                this.b = Layer0.getInstance(g);\r
                comparator.setComparator(this);\r
                \r
-               Stack<Resource> stack1 = new Stack<Resource>();\r
-               Stack<Resource> stack2 = new Stack<Resource>();\r
-               stack1.push(r1);\r
-               stack2.push(r2);\r
+               Stack<Resource> objectsLeft = new Stack<Resource>();\r
+               Stack<Resource> objectsRight = new Stack<Resource>();\r
+               objectsLeft.push(r1);\r
+               objectsRight.push(r2);\r
                \r
                \r
                List<Statement> ss1 = new ArrayList<Statement>();\r
                List<Statement> ss2 = new ArrayList<Statement>();\r
                \r
-               while (!stack1.isEmpty()) {\r
-                       Resource r1 = stack1.pop();\r
-                       Resource r2 = stack2.pop();\r
+               Stack<Statement> unreliableLeft = new Stack<Statement>();\r
+               Stack<Statement> unreliableRight = new Stack<Statement>();\r
+               \r
+               while (!objectsLeft.isEmpty()) {\r
+                       Resource r1 = objectsLeft.pop();\r
+                       Resource r2 = objectsRight.pop();\r
                \r
                        if (comparableResources.contains(r1, r2)) {\r
                                //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
@@ -192,7 +198,7 @@ public class GraphComparator {
                                ss1 = filterNonTested(ss1);\r
                                ss2 = filterNonTested(ss2);\r
                                \r
-                               compareStatements(ss1, ss2, null, null);\r
+                               compareStatements(ss1, ss2, null, null,null,null);\r
                                ss1.clear();\r
                                ss2.clear();\r
                        }\r
@@ -202,11 +208,126 @@ public class GraphComparator {
                                ss2.addAll(g.getStatements(r2, rel));\r
                                ss1 = filterAsserted(r1, ss1);\r
                                ss2 = filterAsserted(r2, ss2);\r
-                               compareStatements(ss1, ss2, stack1, stack2);\r
+                               compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
                                ss1.clear();\r
                                ss2.clear();\r
+                               \r
                        }\r
                }\r
+               MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
+               MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
+               MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
+               MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
+               \r
+               for (Statement s : unreliableLeft) {\r
+                       subjectLeft.add(s.getSubject(),s);\r
+                       objectLeft.add(s.getObject(),s);\r
+               }\r
+               for (Statement s : unreliableRight) {\r
+                       subjectRight.add(s.getSubject(),s);\r
+                       objectRight.add(s.getObject(),s);\r
+               }\r
+               \r
+               for (Resource ol : objectLeft.getKeys()) {\r
+\r
+                       // all statements to the left side object\r
+                       List<Statement> left = objectLeft.getValues(ol);\r
+                       // all subjects that have statements to the left side object (ol)\r
+                       Set<Resource> sLeft = new HashSet<Resource>();\r
+                       // all matching subjects on the right side\r
+                       Set<Resource> sRight = new HashSet<Resource>();\r
+                       for (Statement s : left) {\r
+                               sLeft.add(s.getSubject());\r
+                               sRight.add(comparableResources.getRight(s.getSubject()));\r
+                       }\r
+                       // all objects that subjects on the right side point to. Object left has its matching resource among these, if it has matching resource\r
+                       MapList<Resource,Statement> possibleOR = new MapList<Resource, Statement>();\r
+                       for (Resource sr : sRight) {\r
+                               for (Statement s : subjectRight.getValues(sr))\r
+                                       possibleOR.add(s.getObject(),s);\r
+                       }\r
+                       \r
+                       // filter possible right side objects to those that have same amount of statements as the left side object\r
+                       for (Resource or : possibleOR.getKeys().toArray(new Resource[possibleOR.getKeys().size()])) {\r
+                               List<Statement> right = possibleOR.getValues(or);\r
+                               if (right.size() != left.size())\r
+                                       possibleOR.remove(or);\r
+                                       \r
+                       }\r
+                       \r
+                       // check for matching statements (comparable subjects, matching predicates)\r
+                       MapList<Resource,Statement> matchingOR = new MapList<Resource, Statement>(); // list of objects that have matching statements\r
+                       Map<Resource,Pair<int[], int[]>> matchingStatements = new HashMap<Resource, Pair<int[], int[]>>(); // matching statements\r
+                       for (Resource or : possibleOR.getKeys()) {\r
+                               List<Statement> right = possibleOR.getValues(or);\r
+                               int iLeft[] = new int[left.size()];\r
+                               int iRight[] = new int[right.size()];\r
+                               \r
+                               for (int i = 0; i < left.size(); i++) {\r
+                                       iLeft[i] = -1;\r
+                                       iRight[i] = -1;\r
+                               }\r
+                               \r
+                               for (int l = 0; l < left.size(); l++) {\r
+                                       Statement ls = left.get(l);\r
+                                       for (int r = 0; r < right.size(); r++) {\r
+                                               if (iRight[r] >= 0)\r
+                                                       continue;\r
+                                               Statement rs = right.get(r);\r
+                                               if (!comparableResources.contains(ls.getSubject(), rs.getSubject()))\r
+                                                       continue;\r
+                                               if (rcomp.compare(ls.getPredicate(),rs.getPredicate()) == 0) {\r
+                                                       iLeft[l] = r;\r
+                                                       iRight[r] = l;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       \r
+                               }\r
+                               boolean success = true;\r
+                               for (int i = 0; i < left.size(); i++) {\r
+                                       if (iLeft[i] < 0) {\r
+                                               success = false;\r
+                                               break;\r
+                                       }\r
+                                       if (iRight[i] < 0) {\r
+                                               success = false;\r
+                                               break;\r
+                                       }\r
+                                               \r
+                               }\r
+                               if (success) {\r
+                                       for (Statement s : right) \r
+                                               matchingOR.add(or,s);\r
+                                       matchingStatements.put(or, new Pair<int[], int[]>(iLeft, iRight));\r
+                               }\r
+                       }\r
+                       // if there is only one matching right side object, we have found a match \r
+                       if (matchingOR.getKeySize() == 1) {\r
+                               Resource or = matchingOR.getKeys().iterator().next();\r
+                               List<Statement> right = matchingOR.getValues(or);\r
+                               Pair<int[], int[]> indices = matchingStatements.get(or);\r
+                               \r
+                               comparableResources.map(ol, or);\r
+                               for (int l = 0; l < left.size(); l++) {\r
+                                       int r = indices.first[l];\r
+                                       comparableStatements.map(left.get(l), right.get(r));\r
+                               }\r
+                               \r
+                       }\r
+\r
+               }\r
+               \r
+               for (Statement s : unreliableLeft) {\r
+                       if (!comparableStatements.containsLeft(s))\r
+                               addDeletion(s);\r
+               }\r
+               for (Statement s : unreliableRight) {\r
+                       if (!comparableStatements.containsRight(s))\r
+                               addAddition(s);\r
+               }\r
+               \r
+               \r
        }\r
        \r
        \r
@@ -285,6 +406,10 @@ public class GraphComparator {
        }\r
        \r
        public void sortStatement(List<Statement> list1, List<Statement> list2) {\r
+               sortStatement(list1, list2, scomp);\r
+       }\r
+       \r
+       public void sortStatement(List<Statement> list1, List<Statement> list2, Comparator<Statement> scomp) {\r
                Collections.sort(list1,scomp);\r
                Collections.sort(list2,scomp);\r
                \r
@@ -359,10 +484,8 @@ public class GraphComparator {
                }\r
        }\r
        \r
-       private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> stack1, Stack<Resource> stack2) throws DatabaseException {\r
+       private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight,Stack<Statement> unreliableLeft, Stack<Statement> unreliableRight) throws DatabaseException {\r
                sortStatement(ss1, ss2);\r
-//             Collections.sort(ss1, scomp);\r
-//             Collections.sort(ss2, scomp);\r
                \r
                int i1 = 0;\r
                int i2 = 0;\r
@@ -392,7 +515,59 @@ public class GraphComparator {
                        int same2 = sameRel(ss2, i2);\r
                        int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
                        if (c == 0) {\r
-                               compareStatements(ss1, i1, same1, ss2, i2, same2,stack1,stack2);\r
+                               compareStatements(ss1, i1, same1, ss2, i2, same2,objectsLeft,objectsRight,unreliableLeft,unreliableRight);\r
+                               i1+=same1;\r
+                               i2+=same2;\r
+                       } else if (c < 0) {\r
+                               for (int i = 0; i < same1; i++) {\r
+                                       System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1)));\r
+                                       addDeletion(ss1.get(i+i1));\r
+                               }\r
+                               i1 += same1;\r
+                       } else {\r
+                               for (int i = 0; i < same2; i++) {\r
+                                       System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2)));\r
+                                       addAddition(ss2.get(i+i2));\r
+                               }\r
+                               \r
+                               i2 += same2;\r
+                       }\r
+                       \r
+               }\r
+       }\r
+       \r
+       private void compareUnreliableStatements(List<Statement> ss1, List<Statement> ss2) throws DatabaseException {\r
+               sortStatement(ss1, ss2);\r
+               \r
+               int i1 = 0;\r
+               int i2 = 0;\r
+               \r
+               while (true) {\r
+                       if (i1 >= ss1.size()) {\r
+                               if (i2 >= ss2.size()) {\r
+                                       break;\r
+                               } else {\r
+                                       while (i2 < ss2.size()) {\r
+                                               System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
+                                               \r
+                                               addAddition(ss2.get(i2));\r
+                                               i2++;\r
+                                       }\r
+                                       break;\r
+                               }\r
+                       } else if (i2 >= ss2.size()) {\r
+                               while (i1 < ss1.size()) {\r
+                                       System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
+                                       addDeletion(ss1.get(i1));\r
+                                       i1++;\r
+                               }\r
+                               break;\r
+                       }\r
+                       int same1 = sameRel(ss1, i1);\r
+                       int same2 = sameRel(ss2, i2);\r
+                       int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
+                       if (c == 0) {\r
+                               compareStatements(ss1, i1, same1, ss2, i2, same2,null, null, null, null);\r
                                i1+=same1;\r
                                i2+=same2;\r
                        } else if (c < 0) {\r
@@ -431,10 +606,14 @@ public class GraphComparator {
        private int compareObject(Resource o1, Resource o2) throws DatabaseException {\r
                if (comparableResources.contains(o1, o2))\r
                        return (-1);\r
+               if (comparableResources.containsLeft(o1))\r
+                       return Integer.MAX_VALUE;\r
+               if (comparableResources.containsRight(o2))\r
+                       return Integer.MAX_VALUE;\r
                return comparator.compare(g, o1, o2);\r
        }\r
        \r
-       private void compareStatements(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Stack<Resource> stack1, Stack<Resource> stack2) throws DatabaseException {\r
+       private void compareStatements(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Stack<Statement> unreliableLeft, Stack<Statement> unreliableRight) throws DatabaseException {\r
                boolean[] used1 = new boolean[len1];\r
                for (int i = 0; i < used1.length; i++) {\r
                        used1[i] = false;\r
@@ -452,7 +631,8 @@ public class GraphComparator {
                        List<Integer> diff = new ArrayList<Integer>();\r
                        for (int i2 = off2; i2 < off2 + len2; i2++) {\r
                                Statement s2 = ss2.get(i2);\r
-                               diff.add(compareObject(s1.getObject(), s2.getObject()));\r
+                               int d = compareObject(s1.getObject(), s2.getObject());\r
+                               diff.add(d);\r
                        }\r
                        differences.add(diff);\r
                }\r
@@ -469,43 +649,56 @@ public class GraphComparator {
                Arrays.sort(pris);\r
                \r
                for (Integer pri : pris) {\r
-                       if (pri == Integer.MAX_VALUE)\r
+                       if (pri == Integer.MAX_VALUE) {\r
+\r
+                       } else if (pri == 0) {\r
+                               Set<Statement> s1s = new HashSet<Statement>();\r
+                               Set<Statement> s2s = new HashSet<Statement>();\r
+                               List<Integer> i1s = priorities.getValues(pri);\r
+                               for (Integer i1 : i1s) {\r
+\r
+                                       List<Integer> i2diff = differences.get(i1);\r
+                                       for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
+                                               if (i2diff.get(i2) == pri) {\r
+                                                       used1[i1] = true;\r
+                                                       used2[i2] = true;\r
+                                                       Statement s1  = ss1.get(i1+off1);\r
+                                                       Statement s2  = ss2.get(i2+off2);\r
+                                                       s1s.add(s1);\r
+                                                       s2s.add(s2);\r
+                                               }\r
+                                       }\r
+                               }\r
+                               if (unreliableLeft != null) {\r
+                                       unreliableLeft.addAll(s1s);\r
+                                       unreliableRight.addAll(s2s);\r
+                               }\r
                                continue;\r
-                       List<Integer> i1s = priorities.getValues(pri);\r
-                       for (Integer i1 : i1s) {\r
-                               if (used1[i1])\r
-                                       continue;\r
-                               List<Integer> i2diff = differences.get(i1);\r
-                               for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
-                                       if (i2diff.get(i2) == pri) {\r
-                                               if (used2[i2])\r
-                                                       continue;\r
-                                               used1[i1] = true;\r
-                                               used2[i2] = true;\r
-                                               Statement s1  = ss1.get(i1+off1);\r
-                                               Statement s2  = ss2.get(i2+off2);\r
-                                               \r
-                                               if (stack1 != null) {\r
-                                                       \r
-                                                               stack1.add(s1.getObject());\r
-                                                               stack2.add(s2.getObject());\r
-                                                       \r
-                                               } else {\r
-                                                       // TODO : how should we report non traversed differences\r
-                                                       // using compareProps assumes that referenced objects are the same (references are not different)\r
-                                                       // using propsDiffCount assumes that objects are different, and cannot report changes in referred object.\r
-                                                       \r
+                       } else {\r
+                               List<Integer> i1s = priorities.getValues(pri);\r
+                               for (Integer i1 : i1s) {\r
+                                       if (used1[i1])\r
+                                               continue;\r
+                                       List<Integer> i2diff = differences.get(i1);\r
+                                       for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
+                                               if (i2diff.get(i2) == pri) {\r
+                                                       if (used2[i2])\r
+                                                               continue;\r
+                                                       used1[i1] = true;\r
+                                                       used2[i2] = true;\r
+                                                       Statement s1  = ss1.get(i1+off1);\r
+                                                       Statement s2  = ss2.get(i2+off2);\r
                                                        \r
-//                                                     int diff = propsDiffCount(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject());\r
-//                                                     if (diff != 0) {\r
-//                                                             //changes1.add(ss1.get(i1+off1));\r
-//                                                             //changes2.add(ss2.get(i2+off2));\r
-//                                                             modifies.add(new Pair<Statement, Statement>(ss1.get(i1+off1), ss2.get(i2+off2)));\r
-//                                                     }\r
+                                                       if (objectsLeft != null) {\r
+                                                               \r
+                                                                       objectsLeft.add(s1.getObject());\r
+                                                                       objectsRight.add(s2.getObject());\r
+                                                               \r
+                                                       } \r
+                                                       comparableStatements.map(s1, s2);\r
+                                                       //comparableResources.map(s1.getObject(), s2.getObject());\r
+                                                       break;\r
                                                }\r
-                                               comparableStatements.map(s1, s2);\r
-                                               //comparableResources.map(s1.getObject(), s2.getObject());\r
-                                               break;\r
                                        }\r
                                }\r
                        }\r
@@ -653,6 +846,32 @@ public class GraphComparator {
                }\r
        }\r
        \r
+       public class SubjectComparator implements Comparator<Statement> {\r
+               @Override\r
+               public int compare(Statement o1, Statement o2) {\r
+                       if (comparableResources.contains(o1.getSubject(), o2.getSubject()))\r
+                               return 0;\r
+                       if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
+                               return -1;\r
+                       if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
+                               return 1;\r
+                       return 0;\r
+               }\r
+       }\r
+       \r
+       public class ObjectComparator implements Comparator<Statement> {\r
+               @Override\r
+               public int compare(Statement o1, Statement o2) {\r
+                       if (comparableResources.contains(o1.getObject(), o2.getObject()))\r
+                               return 0;\r
+                       if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
+                               return -1;\r
+                       if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
+                               return 1;\r
+                       return 0;\r
+               }\r
+       }\r
+       \r
        public static class FullStatementComparator implements Comparator<Statement> {\r
                @Override\r
                public int compare(Statement o1, Statement o2) {\r
@@ -674,7 +893,7 @@ public class GraphComparator {
        \r
 \r
        \r
-       public class ResourceComparator implements Comparator<Resource> {\r
+       public class ResComparator implements Comparator<Resource> {\r
                @Override\r
                public int compare(Resource o1, Resource o2) {\r
                        if (comparableResources.contains(o1, o2))\r
similarity index 74%
rename from org.simantics.interop/src/org/simantics/interop/test/ObjectComparator.java
rename to org.simantics.interop/src/org/simantics/interop/test/ResourceComparator.java
index 059d4f8d9f64696bb2e298665e307232ce76776d..3d31d22b2568c8fe2280ea477d9d28464d3d7763 100644 (file)
@@ -9,7 +9,7 @@ import org.simantics.db.exception.DatabaseException;
  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
  *\r
  */\r
-public abstract class ObjectComparator {\r
+public abstract class ResourceComparator {\r
        \r
        private GraphComparator comparator;\r
        \r
@@ -22,7 +22,11 @@ public abstract class ObjectComparator {
        }\r
        \r
        /**\r
-        * Compares two resources and returns numeric value of differences. Result value is Integer.MAX_VALUE if objects are not comparable. \r
+        * Compares two resources and returns numeric value of differences, minimum value is 1. \r
+        * \r
+        * Special values:\r
+        * Integer.MAX_VALUE: Objects are not comparable.\r
+        * 0 (zero): Object comparison is not reliable. \r
         * @param g\r
         * @param o1\r
         * @param o2\r
index fc0268ec6372a4258d05ea43c902a0b52ebc43b6..96ef6101c3c91087a936c47fe989eeaa28f9c9a0 100644 (file)
@@ -21,7 +21,7 @@ import org.simantics.layer0.Layer0;
  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
  *\r
  */\r
-public class TypeComparator extends ObjectComparator {\r
+public class TypeComparator extends ResourceComparator {\r
 \r
        \r
        ArrayList<Resource> rs1 = new ArrayList<Resource>();\r
@@ -69,11 +69,14 @@ public class TypeComparator extends ObjectComparator {
                ss1.addAll(g.getStatements(r1, l0.HasProperty));\r
                ss2.addAll(g.getStatements(r2, l0.HasProperty));\r
                \r
+               if (ss1.size() == 0 && ss2.size() == 0)\r
+                       return 0;\r
+               \r
                Comparator<Statement> scomp = getComparator().getStatementComparator();\r
                \r
                getComparator().sortStatement(ss1, ss2);\r
                \r
-               int count = 0;\r
+               int count = 1;\r
                \r
                int i1 = 0; \r
                int i2 = 0;\r