]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
Improve Proteus property comparison
[simantics/interop.git] / org.simantics.interop / src / org / simantics / interop / test / GraphComparator.java
index 5ba622b620f9379d0c6deec0ebe07a46f5780cc9..72a975f790789e1d3f2971683b4fed07fd15a9fd 100644 (file)
@@ -25,13 +25,11 @@ import java.util.Stack;
 \r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
 import org.simantics.db.Statement;\r
+import org.simantics.db.common.request.ReadRequest;\r
 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
 import org.simantics.utils.datastructures.BijectionMap;\r
 import org.simantics.utils.datastructures.MapList;\r
@@ -50,6 +48,8 @@ import org.simantics.utils.datastructures.Pair;
  *\r
  */\r
 public class GraphComparator {\r
+       \r
+       private static final boolean DEBUG = false;\r
 \r
        private Resource r1;\r
        private Resource r2;\r
@@ -202,6 +202,62 @@ public class GraphComparator {
                }\r
                \r
                \r
+       }\r
+       \r
+       public void test(Session session) throws DatabaseException {\r
+               test(session, r1, r2);\r
+       }\r
+       \r
+       public void test(Session session, Resource r1, Resource r2) throws DatabaseException {\r
+               \r
+               comparator.setComparator(this);\r
+               \r
+               addComparable(r1, r2, false);\r
+               \r
+               final Stack<Resource> objectsLeft = new Stack<Resource>();\r
+               final Stack<Resource> objectsRight = new Stack<Resource>();\r
+               objectsLeft.push(r1);\r
+               objectsRight.push(r2);\r
+               \r
+               final Set<Statement> unreliableLeft = new HashSet<Statement>();\r
+               final Set<Statement> unreliableRight = new HashSet<Statement>();\r
+               \r
+               while (true) {\r
+                       if (objectsLeft.isEmpty())\r
+                               break;\r
+                       session.syncRequest(new ReadRequest() {\r
+                               \r
+                               @Override\r
+                               public void run(ReadGraph graph) throws DatabaseException {\r
+                                       g = graph;\r
+                                       b = Layer0.getInstance(graph);\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 statements subject and object have been identified \r
+                                       processUnreliable(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
+                       \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
@@ -220,9 +276,10 @@ public class GraphComparator {
                        processedResources.add(r1);\r
                        \r
                \r
-                       if(!comparableResources.contains(r1, r2) && (comparableResources.containsLeft(r1)||comparableResources.containsRight(r2))) {\r
+                       if((comparableResources.containsLeft(r1)||comparableResources.containsRight(r2)) && !comparableResources.contains(r1, r2)) {\r
                                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.");\r
                        }\r
+                       addComparable(r1, r2, false);\r
                        \r
                        //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
                        compareProps(r1, r2);\r
@@ -237,6 +294,7 @@ public class GraphComparator {
                                ss1 = filterNonTested(ss1);\r
                                ss2 = filterNonTested(ss2);\r
                                \r
+                               \r
                                compareStatements(ss1, ss2, null, null,null,null);\r
                                ss1.clear();\r
                                ss2.clear();\r
@@ -247,6 +305,8 @@ public class GraphComparator {
                                ss2.addAll(g.getStatements(r2, rel));\r
                                ss1 = filterAsserted(r1, ss1);\r
                                ss2 = filterAsserted(r2, ss2);\r
+                               ss1 = filterNonTraversed(ss1);\r
+                               ss2 = filterNonTraversed(ss2);\r
                                compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
                                ss1.clear();\r
                                ss2.clear();\r
@@ -255,7 +315,7 @@ public class GraphComparator {
                }\r
        }\r
        \r
-       private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight) {\r
+       private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {\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
@@ -290,15 +350,14 @@ public class GraphComparator {
                                                comparableResources.contains(leftS.getPredicate(), rightS.getPredicate())) {\r
                                                unreliableLeft.remove(leftS);\r
                                                unreliableRight.remove(rightS);\r
-                                               comparableStatements.map(leftS, rightS);\r
+                                               addComparable(leftS, rightS, false);\r
                                        }\r
                                }\r
-                       }\r
-                       \r
+                       }               \r
                }\r
        }\r
        \r
-       private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) {\r
+       private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws DatabaseException {\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
@@ -444,9 +503,9 @@ public class GraphComparator {
                                List<Statement> right = matchingOR.getValues(or);\r
                                Pair<int[], int[]> indices = matchingStatements.get(or);\r
                                \r
-                               comparableResources.map(ol, or);\r
                                objectsLeft.add(ol);\r
                                objectsRight.add(or);\r
+                               addComparable(ol, or, false);\r
                                for (int l = 0; l < left.size(); l++) {\r
                                        int r = indices.first[l];\r
                                        Statement sl = left.get(l);\r
@@ -463,7 +522,7 @@ public class GraphComparator {
                \r
        }\r
        \r
-       private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+       private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws DatabaseException {\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
@@ -511,24 +570,29 @@ public class GraphComparator {
                                        for (Path leftPath : pathsLeft) {\r
                                                possiblePathsRight.addAll(findComparableRight(leftPath, or));\r
                                        }\r
-                                       if (possiblePathsRight.size() == pathsLeft.size()) {\r
+                                       if (hasMatchingPaths(pathsLeft, possiblePathsRight)) {\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
+                                               \r
                                                objectsLeft.add(ol);\r
                                                objectsRight.add(or);\r
-                                               comparableResources.map(ol, or);\r
+                                               addComparable(ol, or, false);\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("Compare not implemented");\r
-                                       } else {\r
-                                               System.out.println("Compare not implemented");\r
-                                       }\r
+                                               BijectionMap<Path,Path> map = getMatchingPaths(pathsLeft, matchingPaths.get(or));\r
+                                               for (Path left : map.getLeftSet()) {\r
+                                                       Path right = map.getRight(left);\r
+                                                       for (int i = 0; i < left.getLength(); i++) {\r
+                                                               addComparable(left.getStatements().get(i),right.getStatements().get(i),false);\r
+                                                       }\r
+                                               }\r
+                                       } \r
                                }\r
                        }\r
                        \r
@@ -536,7 +600,31 @@ public class GraphComparator {
                \r
        }\r
        \r
-       private void expand(Set<Path> paths) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+       private boolean hasMatchingPaths(Set<Path> leftPaths, Set<Path> rightPaths) {\r
+               if (leftPaths.size() != rightPaths.size())\r
+                       return false;\r
+               BijectionMap<Path,Path> map = getMatchingPaths(leftPaths, rightPaths);\r
+               return map.size() == leftPaths.size();\r
+       }\r
+       \r
+       private BijectionMap<Path,Path> getMatchingPaths(Set<Path> leftPaths, Set<Path> rightPaths) {\r
+               BijectionMap<Path,Path> map = new BijectionMap<Path, Path>();\r
+               for (Path leftPath : leftPaths) {\r
+                       for (Path rightPath : rightPaths) {\r
+                               if (map.containsRight(rightPath))\r
+                                       continue;\r
+                               if (leftPath.getLength() != rightPath.getLength())\r
+                                       continue;\r
+                               if (comparableResources.contains(leftPath.getEnd(), rightPath.getEnd())) {\r
+                                       map.map(leftPath, rightPath);\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+               return map;\r
+       }\r
+       \r
+       private void expand(Set<Path> paths) throws DatabaseException {\r
                Set<Path> stepPathsLeft = new HashSet<Path>();\r
                if (paths.size() == 0)\r
                        return;\r
@@ -553,7 +641,7 @@ public class GraphComparator {
                }\r
        }\r
        \r
-       private Collection<Path> findComparableRight(Path leftPath, Resource beginRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+       private Collection<Path> findComparableRight(Path leftPath, Resource beginRight) throws DatabaseException {\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
@@ -584,16 +672,33 @@ public class GraphComparator {
                return comparableStatements;\r
        }\r
        \r
+       public BijectionMap<Resource, Resource> getComparableResources() {\r
+               return comparableResources;\r
+       }\r
+       \r
        public GraphChanges getChanges() {\r
                return new GraphChanges(r1,r2,changes1,changes2,modifications,comparableResources);\r
        }\r
        \r
-       private void addComparable(Statement left, Statement right, boolean process) {\r
+       private void addComparable(Statement left, Statement right, boolean process) throws DatabaseException {\r
+               addComparable(left.getObject(), right.getObject(), process);\r
                comparableStatements.map(left, right);\r
-               comparableResources.map(left.getObject(), right.getObject());\r
+               //comparableResources.map(left.getObject(), right.getObject());\r
        }\r
        \r
-       public List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
+       private void addComparable(Resource left, Resource right, boolean process) throws DatabaseException {\r
+               if(!comparableResources.contains(left, right)) {\r
+                       if (comparableResources.containsLeft(left)||comparableResources.containsRight(right)) {\r
+                               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.");\r
+                       } else {\r
+                               if (DEBUG) System.out.println(left + " = " + right);\r
+                               comparableResources.map(left, right);           \r
+                       }\r
+               }\r
+               \r
+       }\r
+       \r
+       public List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws DatabaseException {\r
                List<Statement> out = new ArrayList<Statement>();\r
                for (Statement s : in) {\r
                        if (!s.isAsserted(r))\r
@@ -602,20 +707,26 @@ public class GraphComparator {
                }\r
                return out;\r
        }\r
+       \r
+       \r
 \r
-       private String printStatement(ReadGraph graph, Statement s) throws ValidationException, ServiceException {\r
+       private String printStatement(ReadGraph graph, Statement s) throws DatabaseException {\r
                return NameUtils.getSafeName(graph, s.getSubject()) + " " + NameUtils.getSafeName(graph, s.getPredicate()) + " " + NameUtils.getSafeName(graph, s.getObject());\r
        }\r
        \r
-       private List<Statement> filterTraversed(List<Statement> in) throws ServiceException {\r
+       private List<Statement> filterTraversed(List<Statement> in) throws DatabaseException {\r
                return filter(traversed, in);\r
        }\r
        \r
-       private List<Statement> filterNonTested(List<Statement> in) throws ServiceException {\r
+       private List<Statement> filterNonTested(List<Statement> in) throws DatabaseException {\r
                return filter(nonTested, in);\r
        }\r
        \r
-       private List<Statement> filter(Collection<Resource> toFilter, List<Statement> in) throws ServiceException {\r
+       private List<Statement> filterNonTraversed(List<Statement> in) throws DatabaseException {\r
+               return filter(nonTraversed, in);\r
+       }\r
+       \r
+       private List<Statement> filter(Collection<Resource> toFilter, List<Statement> in) throws DatabaseException {\r
                if (toFilter.size() == 0)\r
                        return in;\r
                List<Statement> out = new ArrayList<Statement>();\r
@@ -748,7 +859,7 @@ public class GraphComparator {
                                        break;\r
                                } else {\r
                                        while (i2 < ss2.size()) {\r
-                                               System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
+                                               if (DEBUG) System.out.println("Compare Statements addition " + printStatement(g,ss2.get(i2)));\r
                                                \r
                                                addAddition(ss2.get(i2));\r
                                                i2++;\r
@@ -757,7 +868,7 @@ public class GraphComparator {
                                }\r
                        } else if (i2 >= ss2.size()) {\r
                                while (i1 < ss1.size()) {\r
-                                       System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
+                                       if (DEBUG) System.out.println("Compare Statements deletion " + printStatement(g,ss1.get(i1)));\r
                                        addDeletion(ss1.get(i1));\r
                                        i1++;\r
                                }\r
@@ -772,13 +883,13 @@ public class GraphComparator {
                                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
+                                       if (DEBUG) System.out.println("Compare Statements deletion " + 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
+                                       if (DEBUG) System.out.println("Compare Statements addition " + printStatement(g,ss2.get(i+i2)));\r
                                        addAddition(ss2.get(i+i2));\r
                                }\r
                                \r
@@ -928,13 +1039,13 @@ public class GraphComparator {
                }\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
+                               if (DEBUG) System.out.println("Compare Object deletion " + printStatement(g,ss1.get(i1)));\r
                                addDeletion(ss1.get(i1));\r
                        }\r
                }\r
                for (int i2 = off2; i2 < off2 + len2; i2++) {\r
                        if (!used2[i2-off2]) {\r
-                               System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2)));\r
+                               if (DEBUG) System.out.println("Compare Object addition " + printStatement(g,ss2.get(i2)));\r
                                addAddition(ss2.get(i2));\r
                        }\r
                }\r
@@ -950,8 +1061,8 @@ public class GraphComparator {
         * @throws DoesNotContainValueException\r
         * @throws ValidationException \r
         */\r
-       private void compareProps(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
-               System.out.println("compareProps " + r1 + " " + NameUtils.getSafeName(g, r1) + " " + r2 + " " + NameUtils.getSafeName(g, r2));\r
+       private void compareProps(Resource r1, Resource r2) throws DatabaseException {\r
+               if (DEBUG) System.out.println("compareProps " + r1 + " " + NameUtils.getSafeName(g, r1) + " " + r2 + " " + NameUtils.getSafeName(g, r2));\r
                ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
                ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
                ss1.addAll(g.getStatements(r1, b.HasProperty));\r
@@ -967,7 +1078,7 @@ public class GraphComparator {
                                        break;\r
                                else {\r
                                        while (i2 < ss2.size()) {\r
-                                               System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
+                                               if (DEBUG) System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
                                                addAddition(ss2.get(i2));\r
                                                i2++;\r
                                        }\r
@@ -975,7 +1086,7 @@ public class GraphComparator {
                                }\r
                        } else if (i2 >= ss2.size()) {\r
                                while (i1 < ss1.size()) {\r
-                                       System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
+                                       if (DEBUG) System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
                                        addDeletion(ss1.get(i1));\r
                                        i1++;\r
                                }\r
@@ -1015,14 +1126,14 @@ public class GraphComparator {
                                        break;\r
                                }\r
                                case -1:{\r
-                                       System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
+                                       if (DEBUG) System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
                                        addDeletion(s1);\r
                                        i1++;\r
                                        break;\r
                                }\r
                                        \r
                                case 1:{\r
-                                       System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
+                                       if (DEBUG) System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
                                        addAddition(s2);\r
                                        i2++;\r
                                        break;\r