]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
GraphComparator behavior can be customized with ObjectComparator
authorluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 19 Sep 2011 13:55:06 +0000 (13:55 +0000)
committerMarko Luukkainen <marko.luukkainen@vtt.fi>
Thu, 2 Feb 2017 09:22:15 +0000 (11:22 +0200)
git-svn-id: https://www.simantics.org/svn/simantics/interoperability/trunk@22324 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java
org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
org.simantics.interop/src/org/simantics/interop/test/NameComparator.java [new file with mode: 0644]
org.simantics.interop/src/org/simantics/interop/test/ObjectComparator.java [new file with mode: 0644]
org.simantics.interop/src/org/simantics/interop/test/TypeComparator.java [new file with mode: 0644]

index 871be6d1171da22de34dd60bc173b8611db33653..f022209a1c99d0cb6954ee2f842814a800520981 100644 (file)
@@ -2,23 +2,40 @@ package org.simantics.interop.test;
 \r
 import java.util.List;\r
 \r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
 import org.simantics.db.Statement;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.exception.ValidationException;\r
 import org.simantics.utils.datastructures.Pair;\r
 \r
 public class GraphChanges {\r
        \r
+       private Resource r1;\r
+       private Resource r2;\r
        private List<Statement> deletions;\r
        private List<Statement> additions;\r
        private List<Pair<Statement,Statement>> modifications;\r
        \r
-       public GraphChanges(List<Statement> deletions, List<Statement> additions,\r
+       public GraphChanges(Resource r1, Resource r2, List<Statement> deletions, List<Statement> additions,\r
                        List<Pair<Statement, Statement>> modifications) {\r
                super();\r
+               this.r1 = r1;\r
+               this.r2 = r2;\r
                this.deletions = deletions;\r
                this.additions = additions;\r
                this.modifications = modifications;\r
        }\r
        \r
+       public Resource getResource1() {\r
+               return r1;\r
+       }\r
+       \r
+       public Resource getResource2() {\r
+               return r2;\r
+       }\r
+       \r
        public List<Statement> getAdditions() {\r
                return additions;\r
        }\r
@@ -30,5 +47,41 @@ public class GraphChanges {
        public List<Pair<Statement, Statement>> getModifications() {\r
                return modifications;\r
        }\r
+       \r
+       public String toString(ReadGraph graph) throws ValidationException, ServiceException {\r
+               StringBuilder sb = new StringBuilder();\r
+               sb.append("Del:\n");\r
+               for (Statement stm : deletions) {\r
+                       sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+\r
+                                                  NameUtils.getSafeName(graph, stm.getPredicate()) + " " +\r
+                                                  NameUtils.getSafeName(graph, stm.getObject()) + " (" +\r
+                                                  stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n");\r
+       }\r
+               sb.append("Add:\n");\r
+               for (Statement stm : additions) {\r
+                       sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+\r
+                                          NameUtils.getSafeName(graph, stm.getPredicate()) + " " +\r
+                                  NameUtils.getSafeName(graph, stm.getObject()) + " (" +\r
+                                  stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n");\r
+       }\r
+               sb.append("Mod:\n");\r
+               for (Pair<Statement, Statement> mod :modifications) {\r
+                       {\r
+                               Statement stm = mod.first;\r
+                               sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+\r
+                                                  NameUtils.getSafeName(graph, stm.getPredicate()) + " " +\r
+                                          NameUtils.getSafeName(graph, stm.getObject()) + " (" +\r
+                                          stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n");\r
+                       }\r
+                       {\r
+                               Statement stm = mod.second;\r
+                               sb.append(NameUtils.getSafeName(graph, stm.getSubject()) + " "+\r
+                                                  NameUtils.getSafeName(graph, stm.getPredicate()) + " " +\r
+                                          NameUtils.getSafeName(graph, stm.getObject()) + " (" +\r
+                                          stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n");\r
+                       }\r
+       }\r
+               return sb.toString();\r
+       }\r
 \r
 }\r
index 6c9685830465a687258fa79b9072be8ff575606b..e529fbbed7cc50481dae1771fc54b0731f001f05 100644 (file)
@@ -25,8 +25,8 @@ import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;\r
 import org.simantics.db.Statement;\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
@@ -48,7 +48,8 @@ import org.simantics.utils.datastructures.Pair;
  */\r
 public class GraphComparator {\r
 \r
-       \r
+       private Resource r1;\r
+       private Resource r2;\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
@@ -65,15 +66,24 @@ public class GraphComparator {
        private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();\r
        \r
        \r
+       private ObjectComparator comparator;\r
+       \r
        // runtime attributes\r
        \r
        private ReadGraph g;\r
        private Layer0 b;\r
        \r
-       ArrayList<Resource> rs1 = new ArrayList<Resource>();\r
-       ArrayList<Resource> rs2 = new ArrayList<Resource>();\r
+       public GraphComparator() {\r
+                comparator = new TypeComparator();\r
+       }\r
+       \r
+       public GraphComparator(ObjectComparator comparator) {\r
+                this.comparator = comparator;\r
+       }\r
+       \r
        ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
        ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
+       \r
        Comparator<Statement> scomp = new PredicateComparator();\r
        Comparator<Resource> rcomp = new ResourceComparator();\r
 \r
@@ -115,10 +125,12 @@ public class GraphComparator {
                tested.clear();\r
        }\r
        \r
-       public void test(ReadGraph g, Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+       public void test(ReadGraph g, Resource r1, Resource r2) throws DatabaseException {\r
                this.g = g;\r
                this.b = Layer0.getInstance(g);\r
                \r
+               this.r1 = r1;\r
+               this.r2 = r2;\r
                changes1Set.clear();\r
                changes2Set.clear();\r
                modificationsSet.clear();\r
@@ -159,7 +171,7 @@ public class GraphComparator {
                                ss1 = filterNonTested(ss1);\r
                                ss2 = filterNonTested(ss2);\r
                                \r
-                               compareStatement(ss1, ss2, null, null);\r
+                               compareStatements(ss1, ss2, null, null);\r
                                ss1.clear();\r
                                ss2.clear();\r
                        }\r
@@ -169,7 +181,7 @@ public class GraphComparator {
                                ss2.addAll(g.getStatements(r2, rel));\r
                                ss1 = filterAsserted(r1, ss1);\r
                                ss2 = filterAsserted(r2, ss2);\r
-                               compareStatement(ss1, ss2, stack1, stack2);\r
+                               compareStatements(ss1, ss2, stack1, stack2);\r
                                ss1.clear();\r
                                ss2.clear();\r
                        }\r
@@ -183,14 +195,7 @@ public class GraphComparator {
        }\r
        \r
        public GraphChanges getChanges() {\r
-//             List<Statement> deletions = new ArrayList<Statement>();\r
-//             List<Statement> additions = new ArrayList<Statement>();\r
-//             deletions.addAll(changes1);\r
-//             additions.addAll(changes2);\r
-//             Collections.sort(deletions, new FullStatementComparator());\r
-//             Collections.sort(additions, new FullStatementComparator());\r
-//             return new GraphChanges(deletions, additions, modifications);\r
-               return new GraphChanges(changes1,changes2,modifications);\r
+               return new GraphChanges(r1,r2,changes1,changes2,modifications);\r
        }\r
        \r
        private List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
@@ -258,7 +263,7 @@ public class GraphComparator {
                }\r
        }\r
        \r
-       private void compareStatement(List<Statement> ss1, List<Statement> ss2, Stack<Resource> stack1, Stack<Resource> stack2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+       private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> stack1, Stack<Resource> stack2) throws DatabaseException {\r
                Collections.sort(ss1, scomp);\r
                Collections.sort(ss2, scomp);\r
                \r
@@ -290,7 +295,7 @@ 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
-                               compareObject(ss1, i1, same1, ss2, i2, same2,stack1,stack2);\r
+                               compareStatements(ss1, i1, same1, ss2, i2, same2,stack1,stack2);\r
                                i1+=same1;\r
                                i2+=same2;\r
                        } else if (c < 0) {\r
@@ -326,8 +331,13 @@ public class GraphComparator {
                \r
        }\r
 \r
+       private int compareObject(Resource o1, Resource o2) throws DatabaseException {\r
+               if (comparableResources.contains(o1, o2))\r
+                       return (-1);\r
+               return comparator.compare(g, o1, o2);\r
+       }\r
        \r
-       private void compareObject(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Stack<Resource> stack1, Stack<Resource> stack2) throws ServiceException, DoesNotContainValueException, ValidationException {\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
                boolean[] used1 = new boolean[len1];\r
                for (int i = 0; i < used1.length; i++) {\r
                        used1[i] = false;\r
@@ -342,18 +352,10 @@ public class GraphComparator {
                List<List<Integer>> differences = new ArrayList<List<Integer>>();\r
                for (int i1 = off1; i1 < off1 + len1; i1++) {\r
                        Statement s1 = ss1.get(i1);\r
-                       //Map<Integer,Integer> differences = new HashMap<Integer, Integer>();\r
                        List<Integer> diff = new ArrayList<Integer>();\r
                        for (int i2 = off2; i2 < off2 + len2; i2++) {\r
                                Statement s2 = ss2.get(i2);\r
-                               if (!compareType(s1.getObject(), s2.getObject())) {\r
-                                       diff.add(Integer.MAX_VALUE);\r
-                                       continue;\r
-                               }\r
-                               if (comparableResources.contains(s1.getObject(), s2.getObject()))\r
-                                       diff.add(-1);\r
-                               else\r
-                                       diff.add(propsDiffCount(s1.getObject(), s2.getObject()));\r
+                               diff.add(compareObject(s1.getObject(), s2.getObject()));\r
                        }\r
                        differences.add(diff);\r
                }\r
@@ -425,30 +427,7 @@ public class GraphComparator {
                }\r
        }\r
        \r
-       private boolean compareType(Resource r1, Resource r2) throws ServiceException, ManyObjectsForFunctionalRelationException {\r
-               rs1.addAll(g.getObjects(r1, b.InstanceOf));\r
-               rs2.addAll(g.getObjects(r2, b.InstanceOf));\r
-               if (rs1.size() != rs2.size()) {\r
-                       rs1.clear();\r
-                       rs2.clear();\r
-                       return false;\r
-               }\r
-               Collections.sort(rs1, rcomp);\r
-               Collections.sort(rs2, rcomp);\r
-               for (int i = 0; i < rs1.size(); i++) {\r
-                       int c = rcomp.compare(rs1.get(i), rs2.get(i));\r
-                       if (c != 0) {\r
-                               rs1.clear();\r
-                               rs2.clear();\r
-                               return false;\r
-                       }\r
-               }\r
-               \r
-               rs1.clear();\r
-               rs2.clear();\r
-               \r
-               return true;\r
-       }\r
+       \r
        \r
        /**\r
         * compares properties, assumes functional relations\r
@@ -500,26 +479,8 @@ public class GraphComparator {
                                        if (b1) {\r
                                                Object v1 = g.getValue(s1.getObject());\r
                                                Object v2 = g.getValue(s2.getObject());\r
-                                               boolean eq = false;\r
-                                               if (v1 instanceof Object[] && v2 instanceof Object[])\r
-                                                       eq = Arrays.deepEquals((Object[])v1, (Object[])v2);\r
-                                               else if (v1 instanceof int[] && v2 instanceof int[]) \r
-                                                       eq = Arrays.equals((int[])v1, (int[])v2);\r
-                                               else if (v1 instanceof float[] && v2 instanceof float[]) \r
-                                                       eq = Arrays.equals((float[])v1, (float[])v2);\r
-                                               else if (v1 instanceof double[] && v2 instanceof double[]) \r
-                                                       eq = Arrays.equals((double[])v1, (double[])v2);\r
-                                               else if (v1 instanceof long[] && v2 instanceof long[]) \r
-                                                       eq = Arrays.equals((long[])v1, (long[])v2);\r
-                                               else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
-                                                       eq = Arrays.equals((byte[])v1, (byte[])v2);\r
-                                               else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
-                                                       eq = Arrays.equals((boolean[])v1, (boolean[])v2);\r
-                                               else\r
-                                                       eq = v1.equals(v2);\r
+                                               boolean eq = compareValue(v1, v2);\r
                                                if (!eq) {\r
-                                                       //changes1.add(s1);\r
-                                                       //changes2.add(s2);\r
                                                        addModification(s1, s2);\r
                                                        comparableStatements.map(s1, s2);\r
                                                        comparableResources.map(s1.getObject(),s2.getObject());\r
@@ -528,8 +489,6 @@ public class GraphComparator {
                                                compareProps(s1.getObject(), s2.getObject());\r
                                        }\r
                                } else {\r
-                                       //changes1.add(s1);\r
-                                       //changes2.add(s2);\r
                                        addModification(s1, s2);\r
                                        comparableStatements.map(s1, s2);\r
                                        comparableResources.map(s1.getObject(),s2.getObject());\r
@@ -561,104 +520,29 @@ public class GraphComparator {
                \r
        }\r
        \r
-       private int propsDiffCount(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
-               ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
-               ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
-               ss1.addAll(g.getStatements(r1, b.HasProperty));\r
-               ss2.addAll(g.getStatements(r2, b.HasProperty));\r
-               //System.out.println("Props count " + GraphUtils.getReadableName(g, r1) + " " + GraphUtils.getReadableName(g, r2));\r
-               Collections.sort(ss1, scomp);\r
-               Collections.sort(ss2, scomp);\r
-               \r
-               int count = 0;\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
-                                               count++;\r
-                                               i2++;\r
-                                       }\r
-                                       break;\r
-                               }\r
-                       } else if (i2 >= ss2.size()) {\r
-                               while (i1 < ss1.size()) {\r
-                                       count++;\r
-                                       i1++;\r
-                               }\r
-                               break;\r
-                       }\r
-                       Statement s1 = ss1.get(i1);\r
-                       Statement s2 = ss2.get(i2);\r
-                       int c = scomp.compare(s1, s2);\r
-                       switch (c) {\r
-                               case 0:{\r
-                                       boolean b1 = g.hasValue(s1.getObject());\r
-                                       boolean b2 = g.hasValue(s2.getObject());\r
-                                       if (b1 == b2) {\r
-                                               if (b1) {\r
-                                                       Object v1 = g.getValue(s1.getObject());\r
-                                                       Object v2 = g.getValue(s2.getObject());\r
-                                                       boolean eq = false;\r
-                                                       if (v1 instanceof Object[] && v2 instanceof Object[])\r
-                                                               eq = Arrays.deepEquals((Object[])v1, (Object[])v2);\r
-                                                       else if (v1 instanceof int[] && v2 instanceof int[]) \r
-                                                               eq = Arrays.equals((int[])v1, (int[])v2);\r
-                                                       else if (v1 instanceof float[] && v2 instanceof float[]) \r
-                                                               eq = Arrays.equals((float[])v1, (float[])v2);\r
-                                                       else if (v1 instanceof double[] && v2 instanceof double[]) \r
-                                                               eq = Arrays.equals((double[])v1, (double[])v2);\r
-                                                       else if (v1 instanceof long[] && v2 instanceof long[]) \r
-                                                               eq = Arrays.equals((long[])v1, (long[])v2);\r
-                                                       else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
-                                                               eq = Arrays.equals((byte[])v1, (byte[])v2);\r
-                                                       else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
-                                                               eq = Arrays.equals((boolean[])v1, (boolean[])v2);\r
-                                                       else\r
-                                                               eq = v1.equals(v2);\r
-                                                       if (!eq) {\r
-                                                               count++;\r
-                                                       }\r
-                                                       //System.out.println("Prop count values " + v1 + " " + v2);\r
-                                               } else {\r
-                                                       count += propsDiffCount(s1.getObject(), s2.getObject());\r
-                                               }\r
-                                       } else {\r
-                                               //System.out.println("Props count structural vs literal");\r
-                                               count++;\r
-                                       }\r
-                                       i1++;\r
-                                       i2++;\r
-                                       break;\r
-                               }\r
-                               case -1:{\r
-                                       count++;\r
-                                       i1++;\r
-                                       break;\r
-                               }\r
-                                       \r
-                               case 1:{\r
-                                       count++;\r
-                                       i2++;\r
-                                       break;\r
-                               }\r
-                       }\r
-\r
-               }\r
-               \r
-               ss1.clear();\r
-               ss2.clear();\r
-               return count;\r
+       \r
+       public static boolean compareValue(Object v1, Object v2) {\r
+               if (v1 instanceof Object[] && v2 instanceof Object[])\r
+                       return Arrays.deepEquals((Object[])v1, (Object[])v2);\r
+               else if (v1 instanceof int[] && v2 instanceof int[]) \r
+                       return Arrays.equals((int[])v1, (int[])v2);\r
+               else if (v1 instanceof float[] && v2 instanceof float[]) \r
+                       return Arrays.equals((float[])v1, (float[])v2);\r
+               else if (v1 instanceof double[] && v2 instanceof double[]) \r
+                       return Arrays.equals((double[])v1, (double[])v2);\r
+               else if (v1 instanceof long[] && v2 instanceof long[]) \r
+                       return  Arrays.equals((long[])v1, (long[])v2);\r
+               else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
+                       return Arrays.equals((byte[])v1, (byte[])v2);\r
+               else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
+                       return Arrays.equals((boolean[])v1, (boolean[])v2);\r
+               else\r
+                       return v1.equals(v2);\r
        }\r
 \r
        \r
        \r
-       public class PredicateComparator implements Comparator<Statement> {\r
+       public static class PredicateComparator implements Comparator<Statement> {\r
                @Override\r
                public int compare(Statement o1, Statement o2) {\r
                        if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
@@ -669,7 +553,7 @@ public class GraphComparator {
                }\r
        }\r
        \r
-       public class FullStatementComparator implements Comparator<Statement> {\r
+       public static class FullStatementComparator implements Comparator<Statement> {\r
                @Override\r
                public int compare(Statement o1, Statement o2) {\r
                        if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
@@ -690,7 +574,7 @@ public class GraphComparator {
        \r
 \r
        \r
-       public class ResourceComparator implements Comparator<Resource> {\r
+       public static class ResourceComparator implements Comparator<Resource> {\r
                @Override\r
                public int compare(Resource o1, Resource o2) {\r
                        if (o1.getResourceId() < o2.getResourceId())\r
@@ -700,4 +584,6 @@ public class GraphComparator {
                        return 0;\r
                }\r
        }\r
+       \r
+       \r
 }\r
diff --git a/org.simantics.interop/src/org/simantics/interop/test/NameComparator.java b/org.simantics.interop/src/org/simantics/interop/test/NameComparator.java
new file mode 100644 (file)
index 0000000..abc2ab2
--- /dev/null
@@ -0,0 +1,38 @@
+package org.simantics.interop.test;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+\r
+/**\r
+ * * Object comparator that uses type and name of objects to check if objects are comparable. \r
+ * \r
+ * Difference value is amount of properties that have different values.\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class NameComparator extends TypeComparator {\r
+       \r
+       @Override\r
+       public int compare(ReadGraph g, Resource o1, Resource o2)\r
+                       throws DatabaseException {\r
+               if (!compareType(g,o1, o2)) {\r
+                       return Integer.MAX_VALUE;\r
+               }\r
+               Layer0 l0 = Layer0.getInstance(g);\r
+               String n1 = g.getPossibleRelatedValue(o1, l0.HasName);\r
+               String n2 = g.getPossibleRelatedValue(o2, l0.HasName);\r
+               if (n1 != null && n2 != null) {\r
+                       if (!n1.equals(n2))\r
+                               return Integer.MAX_VALUE;\r
+               } else if (n1 == null && n2 == null) {\r
+                       \r
+               } else {\r
+                       return Integer.MAX_VALUE;\r
+               }\r
+               return propsDiffCount(g,o1, o2);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/test/ObjectComparator.java b/org.simantics.interop/src/org/simantics/interop/test/ObjectComparator.java
new file mode 100644 (file)
index 0000000..0484def
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.interop.test;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+/**\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public interface 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
+        * @param g\r
+        * @param o1\r
+        * @param o2\r
+        * @return\r
+        * @throws DatabaseException\r
+        */\r
+       public int compare(ReadGraph g, Resource o1, Resource o2) throws DatabaseException;\r
+\r
+}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/test/TypeComparator.java b/org.simantics.interop/src/org/simantics/interop/test/TypeComparator.java
new file mode 100644 (file)
index 0000000..0526a07
--- /dev/null
@@ -0,0 +1,149 @@
+package org.simantics.interop.test;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\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.interop.test.GraphComparator.PredicateComparator;\r
+import org.simantics.interop.test.GraphComparator.ResourceComparator;\r
+import org.simantics.layer0.Layer0;\r
+\r
+/**\r
+ * Object comparator that uses type of objects to check if objects are comparable. \r
+ * \r
+ * Difference value is amount of properties that have different values.\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class TypeComparator implements ObjectComparator {\r
+\r
+       Comparator<Statement> scomp = new PredicateComparator();\r
+       Comparator<Resource> rcomp = new ResourceComparator();\r
+       \r
+       ArrayList<Resource> rs1 = new ArrayList<Resource>();\r
+       ArrayList<Resource> rs2 = new ArrayList<Resource>();\r
+       \r
+       @Override\r
+       public int compare(ReadGraph g, Resource o1, Resource o2) throws DatabaseException{\r
+               if (!compareType(g,o1, o2)) {\r
+                       return (Integer.MAX_VALUE);\r
+               }\r
+               return propsDiffCount(g,o1, o2);\r
+       }\r
+       \r
+       protected boolean compareType(ReadGraph g,Resource r1, Resource r2) throws ServiceException, ManyObjectsForFunctionalRelationException {\r
+               Layer0 l0 = Layer0.getInstance(g);\r
+               rs1.addAll(g.getObjects(r1, l0.InstanceOf));\r
+               rs2.addAll(g.getObjects(r2, l0.InstanceOf));\r
+               if (rs1.size() != rs2.size()) {\r
+                       rs1.clear();\r
+                       rs2.clear();\r
+                       return false;\r
+               }\r
+               Collections.sort(rs1, rcomp);\r
+               Collections.sort(rs2, rcomp);\r
+               for (int i = 0; i < rs1.size(); i++) {\r
+                       int c = rcomp.compare(rs1.get(i), rs2.get(i));\r
+                       if (c != 0) {\r
+                               rs1.clear();\r
+                               rs2.clear();\r
+                               return false;\r
+                       }\r
+               }\r
+               \r
+               rs1.clear();\r
+               rs2.clear();\r
+               \r
+               return true;\r
+       }\r
+       \r
+       protected int propsDiffCount(ReadGraph g, Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+               Layer0 l0 = Layer0.getInstance(g);\r
+               ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
+               ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
+               ss1.addAll(g.getStatements(r1, l0.HasProperty));\r
+               ss2.addAll(g.getStatements(r2, l0.HasProperty));\r
+               Collections.sort(ss1, scomp);\r
+               Collections.sort(ss2, scomp);\r
+               \r
+               int count = 0;\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
+                                               count++;\r
+                                               i2++;\r
+                                       }\r
+                                       break;\r
+                               }\r
+                       } else if (i2 >= ss2.size()) {\r
+                               while (i1 < ss1.size()) {\r
+                                       count++;\r
+                                       i1++;\r
+                               }\r
+                               break;\r
+                       }\r
+                       Statement s1 = ss1.get(i1);\r
+                       Statement s2 = ss2.get(i2);\r
+                       int c = scomp.compare(s1, s2);\r
+                       switch (c) {\r
+                               case 0:{\r
+                                       boolean b1 = g.hasValue(s1.getObject());\r
+                                       boolean b2 = g.hasValue(s2.getObject());\r
+                                       if (b1 == b2) {\r
+                                               if (b1) {\r
+                                                       Object v1 = g.getValue(s1.getObject());\r
+                                                       Object v2 = g.getValue(s2.getObject());\r
+                                                       boolean eq = GraphComparator.compareValue(v1, v2);\r
+                                                       \r
+                                                       if (!eq) {\r
+                                                               count++;\r
+                                                       }\r
+                                                       //System.out.println("Prop count values " + v1 + " " + v2);\r
+                                               } else {\r
+                                                       count += propsDiffCount(g,s1.getObject(), s2.getObject());\r
+                                               }\r
+                                       } else {\r
+                                               //System.out.println("Props count structural vs literal");\r
+                                               count++;\r
+                                       }\r
+                                       i1++;\r
+                                       i2++;\r
+                                       break;\r
+                               }\r
+                               case -1:{\r
+                                       count++;\r
+                                       i1++;\r
+                                       break;\r
+                               }\r
+                                       \r
+                               case 1:{\r
+                                       count++;\r
+                                       i2++;\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+               }\r
+               \r
+               ss1.clear();\r
+               ss2.clear();\r
+               return count;\r
+       }\r
+\r
+}\r