]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
git-svn-id: https://www.simantics.org/svn/simantics/interoperability/trunk@22477...
[simantics/interop.git] / org.simantics.interop / src / org / simantics / interop / test / GraphComparator.java
index c84a8f9f540449f91f8a7ab7de50e86542499227..163dda4917b82e3a34303938a56ce07d2b2e30d3 100644 (file)
@@ -11,7 +11,6 @@
  *******************************************************************************/\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
@@ -30,6 +29,7 @@ import org.simantics.db.Statement;
 import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.exception.DoesNotContainValueException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
 import org.simantics.db.exception.ServiceException;\r
 import org.simantics.db.exception.ValidationException;\r
 import org.simantics.layer0.Layer0;\r
@@ -53,6 +53,7 @@ public class GraphComparator {
 \r
        private Resource r1;\r
        private Resource r2;\r
+       private Set<Resource> strong = new HashSet<Resource>();       // List of relations that identify object, if subject is already identified. \r
        private List<Resource> traversed = new ArrayList<Resource>(); // list of relations that are traversed (and tested)\r
        private List<Resource> tested = new ArrayList<Resource>();    // list of relations that are tested, but not traversed\r
        private List<Resource> nonTraversed = new ArrayList<Resource>(); // list of relations that are not traversed\r
@@ -151,6 +152,10 @@ public class GraphComparator {
                comparableResources.addAll(matching);\r
        }\r
        \r
+       public void addStrong(Resource r) {\r
+               strong.add(r);\r
+       }\r
+       \r
        public void clearRels() {\r
                traversed.clear();\r
                tested.clear();\r
@@ -169,12 +174,42 @@ public class GraphComparator {
                objectsRight.push(r2);\r
                \r
                \r
+               \r
+               \r
+               Set<Statement> unreliableLeft = new HashSet<Statement>();\r
+               Set<Statement> unreliableRight = new HashSet<Statement>();\r
+               \r
+               while (true) {\r
+                       if (objectsLeft.isEmpty())\r
+                               break;\r
+                       \r
+                       // process compares objects that are identified and searches for more resources to process. \r
+                       process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);\r
+                       // process unreliable handles cases where unidentified resources have path of length one to identified resource\r
+                       processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);\r
+                       if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {\r
+                               // comparison is ending, but we have still unprocessed unidentified resources left.\r
+                               // These cases have longer path than one to identified objects.\r
+                               processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);\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
+       private void process(Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {\r
                List<Statement> ss1 = new ArrayList<Statement>();\r
                List<Statement> ss2 = new ArrayList<Statement>();\r
                \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
@@ -214,6 +249,8 @@ public class GraphComparator {
                                \r
                        }\r
                }\r
+       }\r
+       private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) {\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
@@ -308,29 +345,138 @@ public class GraphComparator {
                                List<Statement> right = matchingOR.getValues(or);\r
                                Pair<int[], int[]> indices = matchingStatements.get(or);\r
                                \r
-                               comparableResources.map(ol, or);\r
+                               //comparableResources.map(ol, or);\r
+                               objectsLeft.add(ol);\r
+                               objectsRight.add(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
+                                       unreliableLeft.remove(left.get(l));\r
+                                       unreliableRight.remove(right.get(r));\r
                                }\r
                                \r
                        }\r
 \r
                }\r
                \r
+               \r
+       }\r
+       \r
+       private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\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
-                       if (!comparableStatements.containsLeft(s))\r
-                               addDeletion(s);\r
+                       subjectLeft.add(s.getSubject(),s);\r
+                       objectLeft.add(s.getObject(),s);\r
                }\r
                for (Statement s : unreliableRight) {\r
-                       if (!comparableStatements.containsRight(s))\r
-                               addAddition(s);\r
+                       subjectRight.add(s.getSubject(),s);\r
+                       objectRight.add(s.getObject(),s);\r
+               }\r
+               for (Resource ol : objectLeft.getKeys()) {\r
+                       Set<Path> pathsLeft = new HashSet<Path>();\r
+                       for (Resource rel : traversed) {\r
+                               pathsLeft.addAll(Path.create(g.getStatements(ol, rel)));\r
+                       }\r
+                       while (true) {\r
+                               expand(pathsLeft);\r
+                               if (pathsLeft.size() == 0)\r
+                                       break;\r
+                               Collection<Path> endPaths = new ArrayList<Path>(1);\r
+                               for (Path p : pathsLeft) {\r
+                                       if (comparableResources.containsLeft(p.getEnd())) {\r
+                                               endPaths.add(p);\r
+                                       }\r
+                               }\r
+                               if (endPaths.size() > 0) {\r
+                                       pathsLeft.clear();\r
+                                       pathsLeft.addAll(endPaths);\r
+                                       break;\r
+                               }       \r
+                       }\r
+                       if (pathsLeft.size() > 0) {\r
+                               Resource sl = objectLeft.getValues(ol).get(0).getSubject();\r
+                               Resource sr = comparableResources.getRight(sl);\r
+                               Collection<Resource> possibleOR = new ArrayList<Resource>();\r
+                               for (Statement s : subjectRight.getValues(sr)) {\r
+                                       possibleOR.add(s.getObject());\r
+                               }\r
+                               Map<Resource,Set<Path>> matchingPaths = new HashMap<Resource, Set<Path>>();\r
+                               for (Resource or : possibleOR) {\r
+                                       Set<Path> possiblePathsRight = new HashSet<Path>();\r
+                                       for (Path leftPath : pathsLeft) {\r
+                                               possiblePathsRight.addAll(findComparableRight(leftPath, or));\r
+                                       }\r
+                                       if (possiblePathsRight.size() == pathsLeft.size()) {\r
+                                               matchingPaths.put(or, possiblePathsRight);\r
+                                       }\r
+                               }\r
+                               if (matchingPaths.size() > 0) {\r
+                                       if (matchingPaths.size() == 1) {\r
+                                               Resource or = matchingPaths.keySet().iterator().next();\r
+                                               objectsLeft.add(ol);\r
+                                               objectsRight.add(or);\r
+                                               Collection<Statement> statementsLeft = objectLeft.getValues(ol);\r
+                                               Collection<Statement> statementsRight = objectRight.getValues(or);\r
+                                               unreliableLeft.removeAll(statementsLeft);\r
+                                               unreliableRight.removeAll(statementsRight);\r
+                                               System.out.println();\r
+                                       } else {\r
+                                               System.out.println();\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
                }\r
                \r
+       }\r
+       \r
+       private void expand(Set<Path> paths) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+               Set<Path> stepPathsLeft = new HashSet<Path>();\r
+               if (paths.size() == 0)\r
+                       return;\r
+               int length = paths.iterator().next().getLength() + 1;\r
+               for (Path p : paths) {\r
+                       for (Resource rel : traversed) {\r
+                               stepPathsLeft.addAll(Path.expand(p,g.getStatements(p.getEnd(), rel)));\r
+                       }\r
+               }\r
+               paths.clear();\r
+               for (Path p : stepPathsLeft) {\r
+                       if (p.getLength() == length)\r
+                               paths.add(p);\r
+               }\r
+       }\r
+       \r
+       private Collection<Path> findComparableRight(Path leftPath, Resource beginRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+               Set<Path> rightPaths = new HashSet<Path>();\r
+               rightPaths.addAll(Path.create(g.getStatements(beginRight, getRight(leftPath.getStatements().get(0).getPredicate()))));\r
+               for (int i = 1; i < leftPath.getLength(); i++) {\r
+                       if (rightPaths.size() == 0)\r
+                               return rightPaths;\r
+                       Set<Path> stepPaths = new HashSet<Path>();\r
+                       for (Path p : rightPaths) {\r
+                               stepPaths.addAll(Path.expand(p, g.getStatements(p.getEnd(), getRight(leftPath.getStatements().get(i).getPredicate()))));\r
+                       }\r
+                       rightPaths.clear();\r
+                       for (Path p : stepPaths)\r
+                               if (p.getLength() == i+1) \r
+                                       rightPaths.add(p);\r
+               }\r
+               return rightPaths;\r
                \r
-       }\r
+       }\r
        \r
+       private Resource getRight(Resource r) {\r
+               if (comparableResources.containsLeft(r))\r
+                       return comparableResources.getRight(r);\r
+               return r;\r
+       }\r
        \r
+\r
        \r
        public BijectionMap<Statement, Statement> getComparableStatements() {\r
                return comparableStatements;\r
@@ -484,7 +630,7 @@ public class GraphComparator {
                }\r
        }\r
        \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
+       private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Collection<Statement> unreliableLeft, Collection<Statement> unreliableRight) throws DatabaseException {\r
                sortStatement(ss1, ss2);\r
                \r
                int i1 = 0;\r
@@ -536,57 +682,7 @@ public class GraphComparator {
                }\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
-                               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
        \r
        private int sameRel(List<Statement> statements, int off) {\r
                if (statements.size() <= off)\r
@@ -613,7 +709,7 @@ public class GraphComparator {
                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> objectsLeft, Stack<Resource> objectsRight, Stack<Statement> unreliableLeft, Stack<Statement> unreliableRight) throws DatabaseException {\r
+       private void compareStatements(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Collection<Resource> objectsLeft, Collection<Resource> objectsRight, Collection<Statement> unreliableLeft, Collection<Statement> unreliableRight) throws DatabaseException {\r
                boolean[] used1 = new boolean[len1];\r
                for (int i = 0; i < used1.length; i++) {\r
                        used1[i] = false;\r
@@ -632,6 +728,14 @@ public class GraphComparator {
                        for (int i2 = off2; i2 < off2 + len2; i2++) {\r
                                Statement s2 = ss2.get(i2);\r
                                int d = compareObject(s1.getObject(), s2.getObject());\r
+                               if (d == 0) {\r
+                                       for (Resource t : strong) {\r
+                                                if (s1.getPredicate().equals(t) || g.isSubrelationOf(s1.getPredicate(), t)) {\r
+                                                        d = 1;\r
+                                                        break;\r
+                                                }\r
+                                       }\r
+                               }\r
                                diff.add(d);\r
                        }\r
                        differences.add(diff);\r
@@ -652,28 +756,7 @@ public class GraphComparator {
                        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
+                               \r
                        } else {\r
                                List<Integer> i1s = priorities.getValues(pri);\r
                                for (Integer i1 : i1s) {\r
@@ -703,6 +786,42 @@ public class GraphComparator {
                                }\r
                        }\r
                }\r
+               \r
+               for (Integer pri : pris) {\r
+                       if (pri != 0)\r
+                               continue;\r
+                       Set<Statement> s1s = new HashSet<Statement>();\r
+                       Set<Statement> s2s = new HashSet<Statement>();\r
+                       Set<Integer> s1i = new HashSet<Integer>();\r
+                       Set<Integer> s2i = new HashSet<Integer>();\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
+                                               Statement s1  = ss1.get(i1+off1);\r
+                                               Statement s2  = ss2.get(i2+off2);\r
+                                               s1s.add(s1);\r
+                                               s2s.add(s2);\r
+                                               s1i.add(i1);\r
+                                               s2i.add(i2);\r
+                                       }\r
+                               }\r
+                       }\r
+                       if (unreliableLeft != null) {\r
+                               unreliableLeft.addAll(s1s);\r
+                               unreliableRight.addAll(s2s);\r
+                       }\r
+                       for (Integer i : s1i)\r
+                               used1[i] = true;\r
+                       for (Integer i : s2i)\r
+                               used2[i] = true;\r
+\r
+               }\r
                for (int i1 = off1; i1 < off1 + len1; i1++) {\r
                        if (!used1[i1-off1]) {\r
                                System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1)));\r