]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
Comparator bug fixes.
[simantics/interop.git] / org.simantics.interop / src / org / simantics / interop / test / GraphComparator.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Foster Wheeler Energia Oy - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.interop.test;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Arrays;\r
16 import java.util.Collection;\r
17 import java.util.Collections;\r
18 import java.util.Comparator;\r
19 import java.util.HashSet;\r
20 import java.util.List;\r
21 import java.util.Set;\r
22 import java.util.Stack;\r
23 \r
24 import org.simantics.db.ReadGraph;\r
25 import org.simantics.db.Resource;\r
26 import org.simantics.db.Statement;\r
27 import org.simantics.db.common.utils.NameUtils;\r
28 import org.simantics.db.exception.DoesNotContainValueException;\r
29 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
30 import org.simantics.db.exception.ServiceException;\r
31 import org.simantics.db.exception.ValidationException;\r
32 import org.simantics.layer0.Layer0;\r
33 import org.simantics.utils.datastructures.BijectionMap;\r
34 import org.simantics.utils.datastructures.MapList;\r
35 import org.simantics.utils.datastructures.Pair;\r
36 \r
37 /**\r
38  * Compares two subgraphs and reports differences.\r
39  * \r
40  * Assumes that subgraphs (defined using traverse relations) are not cyclic.\r
41  * \r
42  * Assumes that properties can be used to identify objects, if relation type is not enough.\r
43  * \r
44  * \r
45  * \r
46  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
47  *\r
48  */\r
49 public class GraphComparator {\r
50 \r
51         \r
52         private List<Resource> traversed = new ArrayList<Resource>(); // list of relations that are traversed (and tested)\r
53         private List<Resource> tested = new ArrayList<Resource>();    // list of relations that are tested, but not traversed\r
54         private List<Resource> nonTraversed = new ArrayList<Resource>(); // list of relations that are not traversed\r
55         \r
56         private List<Statement> changes1 = new ArrayList<Statement>();\r
57         private List<Statement> changes2 = new ArrayList<Statement>();\r
58         private List<Pair<Statement,Statement>> modifications = new ArrayList<Pair<Statement,Statement>>();\r
59         private Set<Statement> changes1Set = new HashSet<Statement>();\r
60         private Set<Statement> changes2Set = new HashSet<Statement>();\r
61         private Set<Pair<Statement,Statement>> modificationsSet = new HashSet<Pair<Statement,Statement>>();\r
62 \r
63         private BijectionMap<Statement, Statement> comparable = new BijectionMap<Statement, Statement>();\r
64         \r
65         \r
66         // runtime attributes\r
67         \r
68         private ReadGraph g;\r
69         private Layer0 b;\r
70         \r
71         ArrayList<Resource> rs1 = new ArrayList<Resource>();\r
72         ArrayList<Resource> rs2 = new ArrayList<Resource>();\r
73         ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
74         ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
75         Comparator<Statement> scomp = new PredicateComparator();\r
76         Comparator<Resource> rcomp = new ResourceComparator();\r
77 \r
78         \r
79         public void addTraversed(Resource rel) {\r
80                 traversed.add(rel);\r
81         }\r
82         \r
83         public void addTraversed(Collection<Resource> rels) {\r
84                 traversed.addAll(rels);\r
85         }\r
86         \r
87         public void addNonTraversed(Resource rel) {\r
88                 nonTraversed.add(rel);\r
89         }\r
90         \r
91         public void addNonTraversed(Collection<Resource> rels) {\r
92                 nonTraversed.addAll(rels);\r
93         }\r
94         \r
95         public void addTested(Resource rel) {\r
96                 tested.add(rel);\r
97         }\r
98         \r
99         public void addTested(Collection<Resource> rels) {\r
100                 tested.addAll(rels);\r
101         }\r
102         \r
103         public void clearRels() {\r
104                 traversed.clear();\r
105                 tested.clear();\r
106         }\r
107         \r
108         public void test(ReadGraph g, Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
109                 this.g = g;\r
110                 this.b = Layer0.getInstance(g);\r
111                 \r
112                 changes1Set.clear();\r
113                 changes2Set.clear();\r
114                 modificationsSet.clear();\r
115                 changes1.clear();\r
116                 changes2.clear();\r
117                 modifications.clear();\r
118                 \r
119                 Stack<Resource> stack1 = new Stack<Resource>();\r
120                 Stack<Resource> stack2 = new Stack<Resource>();\r
121                 stack1.push(r1);\r
122                 stack2.push(r2);\r
123                 \r
124                 List<Statement> ss1 = new ArrayList<Statement>();\r
125                 List<Statement> ss2 = new ArrayList<Statement>();\r
126                 \r
127                 while (!stack1.isEmpty()) {\r
128                         r1 = stack1.pop();\r
129                         r2 = stack2.pop();\r
130                         \r
131                         System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
132                         compareProps(r1, r2);\r
133                         \r
134                         for (Resource rel : tested) {\r
135                                 ss1.addAll(g.getStatements(r1, rel));\r
136                                 ss2.addAll(g.getStatements(r2, rel));\r
137                                 ss1 = filterAsserted(r1, ss1);\r
138                                 ss2 = filterAsserted(r2, ss2);\r
139                                 ss1 = filterTraversed(ss1);\r
140                                 ss2 = filterTraversed(ss2);\r
141                                 \r
142                                 compareStatement(ss1, ss2, null, null);\r
143                                 ss1.clear();\r
144                                 ss2.clear();\r
145                         }\r
146                         \r
147                         for (Resource rel : traversed) {\r
148                                 ss1.addAll(g.getStatements(r1, rel));\r
149                                 ss2.addAll(g.getStatements(r2, rel));\r
150                                 ss1 = filterAsserted(r1, ss1);\r
151                                 ss2 = filterAsserted(r2, ss2);\r
152                                 compareStatement(ss1, ss2, stack1, stack2);\r
153                                 ss1.clear();\r
154                                 ss2.clear();\r
155                         }\r
156                 }\r
157         }\r
158         \r
159         \r
160         \r
161         public BijectionMap<Statement, Statement> getComparable() {\r
162                 return comparable;\r
163         }\r
164         \r
165         public GraphChanges getChanges() {\r
166 //              List<Statement> deletions = new ArrayList<Statement>();\r
167 //              List<Statement> additions = new ArrayList<Statement>();\r
168 //              deletions.addAll(changes1);\r
169 //              additions.addAll(changes2);\r
170 //              Collections.sort(deletions, new FullStatementComparator());\r
171 //              Collections.sort(additions, new FullStatementComparator());\r
172 //              return new GraphChanges(deletions, additions, modifications);\r
173                 return new GraphChanges(changes1,changes2,modifications);\r
174         }\r
175         \r
176         private List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
177                 List<Statement> out = new ArrayList<Statement>();\r
178                 for (Statement s : in) {\r
179                         if (!s.isAsserted(r))\r
180                                 out.add(s);\r
181                         \r
182                 }\r
183                 return out;\r
184         }\r
185         \r
186         private String printStatement(ReadGraph graph, Statement s) throws ValidationException, ServiceException {\r
187                 return NameUtils.getSafeName(graph, s.getSubject()) + " " + NameUtils.getSafeName(graph, s.getPredicate()) + " " + NameUtils.getSafeName(graph, s.getObject());\r
188         }\r
189         \r
190         private List<Statement> filterTraversed(Collection<Statement> in) throws ServiceException {\r
191                 List<Statement> out = new ArrayList<Statement>();\r
192                 for (Statement s : in) {\r
193                         boolean usable = true;\r
194                         for (Resource r : traversed) {\r
195                                 if (g.isSubrelationOf(s.getPredicate(),r)) {\r
196                                         usable = false;\r
197                                         break;\r
198                                 }\r
199                         }\r
200                         if (usable) {\r
201                                 out.add(s);\r
202                         }\r
203                         \r
204                 }\r
205                 return out;\r
206         }\r
207         \r
208         \r
209         private void addDeletion(Statement s) {\r
210                 if (!changes1Set.contains(s)) {\r
211                         changes1Set.add(s);\r
212                         changes1.add(s);\r
213                 }\r
214         }\r
215         \r
216         private void addAddition(Statement s) {\r
217                 if (!changes2Set.contains(s)) {\r
218                         changes2Set.add(s);\r
219                         changes2.add(s);\r
220                 }\r
221         }\r
222         \r
223         private void addModification(Statement s1, Statement s2) {\r
224                 Pair<Statement, Statement> mod = new Pair<Statement, Statement>(s1,s2);\r
225                 if (!modificationsSet.contains(mod)) {\r
226                         modificationsSet.add(mod);\r
227                         modifications.add(mod);\r
228                 }\r
229         }\r
230         \r
231         private void compareStatement(List<Statement> ss1, List<Statement> ss2, Stack<Resource> stack1, Stack<Resource> stack2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
232                 Collections.sort(ss1, scomp);\r
233                 Collections.sort(ss2, scomp);\r
234                 \r
235                 int i1 = 0;\r
236                 int i2 = 0;\r
237                 \r
238                 while (true) {\r
239                         if (i1 >= ss1.size()) {\r
240                                 if (i2 >= ss2.size()) {\r
241                                         break;\r
242                                 } else {\r
243                                         while (i2 < ss2.size()) {\r
244                                                 System.out.println("Compare Statement diff2 " + printStatement(g,ss2.get(i2)));\r
245                                                 \r
246                                                 addAddition(ss2.get(i2));\r
247                                                 i2++;\r
248                                         }\r
249                                         break;\r
250                                 }\r
251                         } else if (i2 >= ss2.size()) {\r
252                                 while (i1 < ss1.size()) {\r
253                                         System.out.println("Compare Statement diff1 " + printStatement(g,ss1.get(i1)));\r
254                                         addDeletion(ss1.get(i1));\r
255                                         i1++;\r
256                                 }\r
257                                 break;\r
258                         }\r
259                         int same1 = sameRel(ss1, i1);\r
260                         int same2 = sameRel(ss2, i2);\r
261                         int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
262                         if (c == 0) {\r
263                                 compareObject(ss1, i1, same1, ss2, i2, same2,stack1,stack2);\r
264                                 i1+=same1;\r
265                                 i2+=same2;\r
266                         } else if (c < 0) {\r
267                                 for (int i = 0; i < same1; i++) {\r
268                                         System.out.println("Compare Statement diff1 " + printStatement(g,ss1.get(i+i1)));\r
269                                         addDeletion(ss1.get(i+i1));\r
270                                 }\r
271                                 i1 += same1;\r
272                         } else {\r
273                                 for (int i = 0; i < same2; i++) {\r
274                                         System.out.println("Compare Statement diff2 " + printStatement(g,ss2.get(i+i2)));\r
275                                         addAddition(ss2.get(i+i2));\r
276                                 }\r
277                                 \r
278                                 i2 += same2;\r
279                         }\r
280                         \r
281                 }\r
282         }\r
283         \r
284         private int sameRel(List<Statement> statements, int off) {\r
285                 if (statements.size() <= off)\r
286                         return 0;\r
287                 int same = 1;\r
288                 long id = statements.get(off).getPredicate().getResourceId();\r
289                 for (int i = off+1; i <statements.size(); i++) {\r
290                         if (statements.get(i).getPredicate().getResourceId() == id)\r
291                                 same++;\r
292                         else \r
293                                 break;\r
294                 }\r
295                 return same;\r
296                 \r
297         }\r
298 \r
299         \r
300         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
301                 boolean[] used1 = new boolean[len1];\r
302                 for (int i = 0; i < used1.length; i++) {\r
303                         used1[i] = false;\r
304                 }\r
305                 \r
306                 boolean[] used2 = new boolean[len2];\r
307                 for (int i = 0; i < used2.length; i++) {\r
308                         used2[i] = false;\r
309                 }\r
310                 \r
311                 // left, right, difference\r
312                 List<List<Integer>> differences = new ArrayList<List<Integer>>();\r
313                 for (int i1 = off1; i1 < off1 + len1; i1++) {\r
314                         Statement s1 = ss1.get(i1);\r
315                         //Map<Integer,Integer> differences = new HashMap<Integer, Integer>();\r
316                         List<Integer> diff = new ArrayList<Integer>();\r
317                         for (int i2 = off2; i2 < off2 + len2; i2++) {\r
318                                 Statement s2 = ss2.get(i2);\r
319                                 if (!compareType(s1.getObject(), s2.getObject())) {\r
320                                         diff.add(Integer.MAX_VALUE);\r
321                                         continue;\r
322                                 }\r
323                                 diff.add(propsDiffCount(s1.getObject(), s2.getObject()));\r
324                         }\r
325                         differences.add(diff);\r
326                 }\r
327                 // difference, left\r
328                 MapList<Integer, Integer> priorities = new MapList<Integer, Integer>();\r
329                 for (int i = 0; i < differences.size(); i++) {\r
330                         List<Integer> list = differences.get(i);\r
331                         for (int j = 0; j < list.size(); j++) {\r
332                                 priorities.add(list.get(j), i);\r
333                         }\r
334                 }\r
335                 \r
336                 Integer[] pris = priorities.getKeys(new Integer[]{});\r
337                 Arrays.sort(pris);\r
338                 \r
339                 for (Integer pri : pris) {\r
340                         if (pri == Integer.MAX_VALUE)\r
341                                 continue;\r
342                         List<Integer> i1s = priorities.getValues(pri);\r
343                         for (Integer i1 : i1s) {\r
344                                 if (used1[i1])\r
345                                         continue;\r
346                                 List<Integer> i2diff = differences.get(i1);\r
347                                 for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
348                                         if (i2diff.get(i2) == pri) {\r
349                                                 if (used2[i2])\r
350                                                         continue;\r
351                                                 used1[i1] = true;\r
352                                                 used2[i2] = true;\r
353                                                 if (stack1 != null) {\r
354                                                         stack1.add(ss1.get(i1+off1).getObject());\r
355                                                         stack2.add(ss2.get(i2+off2).getObject());\r
356                                                 } else {\r
357                                                         // TODO : how should we report non traversed differences\r
358                                                         // using compareProps assumes that referenced objects are the same (references are not different)\r
359                                                         // using propsDiffCount assumes that objects are different, and cannot report changes in referred object.\r
360                                                         \r
361                                                         \r
362 //                                                      int diff = propsDiffCount(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject());\r
363 //                                                      if (diff != 0) {\r
364 //                                                              //changes1.add(ss1.get(i1+off1));\r
365 //                                                              //changes2.add(ss2.get(i2+off2));\r
366 //                                                              modifies.add(new Pair<Statement, Statement>(ss1.get(i1+off1), ss2.get(i2+off2)));\r
367 //                                                      }\r
368                                                 }\r
369                                                 break;\r
370                                         }\r
371                                 }\r
372                         }\r
373                 }\r
374                 for (int i1 = off1; i1 < off1 + len1; i1++) {\r
375                         if (!used1[i1-off1]) {\r
376                                 System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1)));\r
377                                 addDeletion(ss1.get(i1));\r
378                         }\r
379                 }\r
380                 for (int i2 = off2; i2 < off2 + len2; i2++) {\r
381                         if (!used2[i2-off2]) {\r
382                                 System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2)));\r
383                                 addAddition(ss2.get(i2));\r
384                         }\r
385                 }\r
386         }\r
387         \r
388         private boolean compareType(Resource r1, Resource r2) throws ServiceException, ManyObjectsForFunctionalRelationException {\r
389                 rs1.addAll(g.getObjects(r1, b.InstanceOf));\r
390                 rs2.addAll(g.getObjects(r2, b.InstanceOf));\r
391                 if (rs1.size() != rs2.size()) {\r
392                         rs1.clear();\r
393                         rs2.clear();\r
394                         return false;\r
395                 }\r
396                 Collections.sort(rs1, rcomp);\r
397                 Collections.sort(rs2, rcomp);\r
398                 for (int i = 0; i < rs1.size(); i++) {\r
399                         int c = rcomp.compare(rs1.get(i), rs2.get(i));\r
400                         if (c != 0) {\r
401                                 rs1.clear();\r
402                                 rs2.clear();\r
403                                 return false;\r
404                         }\r
405                 }\r
406                 \r
407                 rs1.clear();\r
408                 rs2.clear();\r
409                 \r
410                 return true;\r
411         }\r
412         \r
413         /**\r
414          * compares properties, assumes functional relations\r
415          * @param r1\r
416          * @param r2\r
417          * @throws ServiceException\r
418          * @throws DoesNotContainValueException\r
419          * @throws ValidationException \r
420          */\r
421         private void compareProps(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
422                 ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
423                 ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
424                 ss1.addAll(g.getStatements(r1, b.HasProperty));\r
425                 ss2.addAll(g.getStatements(r2, b.HasProperty));\r
426                 Collections.sort(ss1, scomp);\r
427                 Collections.sort(ss2, scomp);\r
428                 \r
429                 int i1 = 0; \r
430                 int i2 = 0;\r
431                 \r
432                 while (true) {\r
433                         if (i1 >= ss1.size()) {\r
434                                 if (i2 >= ss2.size())\r
435                                         break;\r
436                                 else {\r
437                                         while (i2 < ss2.size()) {\r
438                                                 System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
439                                                 addAddition(ss2.get(i2));\r
440                                                 i2++;\r
441                                         }\r
442                                         break;\r
443                                 }\r
444                         } else if (i2 >= ss2.size()) {\r
445                                 while (i1 < ss1.size()) {\r
446                                         System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
447                                         addDeletion(ss1.get(i1));\r
448                                         i1++;\r
449                                 }\r
450                                 break;\r
451                         }\r
452                         Statement s1 = ss1.get(i1);\r
453                         Statement s2 = ss2.get(i2);\r
454                         int c = scomp.compare(s1, s2);\r
455                         switch (c) {\r
456                         case 0:{\r
457                                 boolean b1 = g.hasValue(s1.getObject());\r
458                                 boolean b2 = g.hasValue(s2.getObject());\r
459                                 if (b1 == b2) {\r
460                                         if (b1) {\r
461                                                 Object v1 = g.getValue(s1.getObject());\r
462                                                 Object v2 = g.getValue(s2.getObject());\r
463                                                 boolean eq = false;\r
464                                                 if (v1 instanceof Object[] && v2 instanceof Object[])\r
465                                                         eq = Arrays.deepEquals((Object[])v1, (Object[])v2);\r
466                                                 else if (v1 instanceof int[] && v2 instanceof int[]) \r
467                                                         eq = Arrays.equals((int[])v1, (int[])v2);\r
468                                                 else if (v1 instanceof float[] && v2 instanceof float[]) \r
469                                                         eq = Arrays.equals((float[])v1, (float[])v2);\r
470                                                 else if (v1 instanceof double[] && v2 instanceof double[]) \r
471                                                         eq = Arrays.equals((double[])v1, (double[])v2);\r
472                                                 else if (v1 instanceof long[] && v2 instanceof long[]) \r
473                                                         eq = Arrays.equals((long[])v1, (long[])v2);\r
474                                                 else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
475                                                         eq = Arrays.equals((byte[])v1, (byte[])v2);\r
476                                                 else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
477                                                         eq = Arrays.equals((boolean[])v1, (boolean[])v2);\r
478                                                 else\r
479                                                         eq = v1.equals(v2);\r
480                                                 if (!eq) {\r
481                                                         //changes1.add(s1);\r
482                                                         //changes2.add(s2);\r
483                                                         addModification(s1, s2);\r
484                                                         comparable.map(s1, s2);\r
485                                                 }\r
486                                         } else {\r
487                                                 compareProps(s1.getObject(), s2.getObject());\r
488                                         }\r
489                                 } else {\r
490                                         //changes1.add(s1);\r
491                                         //changes2.add(s2);\r
492                                         addModification(s1, s2);\r
493                                         comparable.map(s1, s2);\r
494                                 }\r
495                                 i1++;\r
496                                 i2++;\r
497                                 break;\r
498                         }\r
499                         case -1:{\r
500                                 System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
501                                 addDeletion(s1);\r
502                                 i1++;\r
503                                 break;\r
504                         }\r
505                                 \r
506                         case 1:{\r
507                                 System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
508                                 addAddition(s2);\r
509                                 i2++;\r
510                                 break;\r
511                         }\r
512                         }\r
513                         \r
514                         \r
515                 }\r
516                 \r
517                 ss1.clear();\r
518                 ss2.clear();\r
519                 \r
520         }\r
521         \r
522         private int propsDiffCount(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
523                 ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
524                 ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
525                 ss1.addAll(g.getStatements(r1, b.HasProperty));\r
526                 ss2.addAll(g.getStatements(r2, b.HasProperty));\r
527                 //System.out.println("Props count " + GraphUtils.getReadableName(g, r1) + " " + GraphUtils.getReadableName(g, r2));\r
528                 Collections.sort(ss1, scomp);\r
529                 Collections.sort(ss2, scomp);\r
530                 \r
531                 int count = 0;\r
532                 \r
533                 int i1 = 0; \r
534                 int i2 = 0;\r
535                 \r
536                 while (true) {\r
537                         if (i1 >= ss1.size()) {\r
538                                 if (i2 >= ss2.size())\r
539                                         break;\r
540                                 else {\r
541                                         while (i2 < ss2.size()) {\r
542                                                 count++;\r
543                                                 i2++;\r
544                                         }\r
545                                         break;\r
546                                 }\r
547                         } else if (i2 >= ss2.size()) {\r
548                                 while (i1 < ss1.size()) {\r
549                                         count++;\r
550                                         i1++;\r
551                                 }\r
552                                 break;\r
553                         }\r
554                         Statement s1 = ss1.get(i1);\r
555                         Statement s2 = ss2.get(i2);\r
556                         int c = scomp.compare(s1, s2);\r
557                         switch (c) {\r
558                                 case 0:{\r
559                                         boolean b1 = g.hasValue(s1.getObject());\r
560                                         boolean b2 = g.hasValue(s2.getObject());\r
561                                         if (b1 == b2) {\r
562                                                 if (b1) {\r
563                                                         Object v1 = g.getValue(s1.getObject());\r
564                                                         Object v2 = g.getValue(s2.getObject());\r
565                                                         boolean eq = false;\r
566                                                         if (v1 instanceof Object[] && v2 instanceof Object[])\r
567                                                                 eq = Arrays.deepEquals((Object[])v1, (Object[])v2);\r
568                                                         else if (v1 instanceof int[] && v2 instanceof int[]) \r
569                                                                 eq = Arrays.equals((int[])v1, (int[])v2);\r
570                                                         else if (v1 instanceof float[] && v2 instanceof float[]) \r
571                                                                 eq = Arrays.equals((float[])v1, (float[])v2);\r
572                                                         else if (v1 instanceof double[] && v2 instanceof double[]) \r
573                                                                 eq = Arrays.equals((double[])v1, (double[])v2);\r
574                                                         else if (v1 instanceof long[] && v2 instanceof long[]) \r
575                                                                 eq = Arrays.equals((long[])v1, (long[])v2);\r
576                                                         else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
577                                                                 eq = Arrays.equals((byte[])v1, (byte[])v2);\r
578                                                         else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
579                                                                 eq = Arrays.equals((boolean[])v1, (boolean[])v2);\r
580                                                         else\r
581                                                                 eq = v1.equals(v2);\r
582                                                         if (!eq) {\r
583                                                                 count++;\r
584                                                         }\r
585                                                         //System.out.println("Prop count values " + v1 + " " + v2);\r
586                                                 } else {\r
587                                                         count += propsDiffCount(s1.getObject(), s2.getObject());\r
588                                                 }\r
589                                         } else {\r
590                                                 //System.out.println("Props count structural vs literal");\r
591                                                 count++;\r
592                                         }\r
593                                         i1++;\r
594                                         i2++;\r
595                                         break;\r
596                                 }\r
597                                 case -1:{\r
598                                         count++;\r
599                                         i1++;\r
600                                         break;\r
601                                 }\r
602                                         \r
603                                 case 1:{\r
604                                         count++;\r
605                                         i2++;\r
606                                         break;\r
607                                 }\r
608                         }\r
609 \r
610                 }\r
611                 \r
612                 ss1.clear();\r
613                 ss2.clear();\r
614                 return count;\r
615         }\r
616 \r
617         \r
618         \r
619         public class PredicateComparator implements Comparator<Statement> {\r
620                 @Override\r
621                 public int compare(Statement o1, Statement o2) {\r
622                         if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
623                                 return -1;\r
624                         if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
625                                 return 1;\r
626                         return 0;\r
627                 }\r
628         }\r
629         \r
630         public class FullStatementComparator implements Comparator<Statement> {\r
631                 @Override\r
632                 public int compare(Statement o1, Statement o2) {\r
633                         if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
634                                 return -1;\r
635                         if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
636                                 return 1;\r
637                         if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
638                                 return -1;\r
639                         if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
640                                 return 1;\r
641                         if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
642                                 return -1;\r
643                         if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
644                                 return 1;\r
645                         return 0;\r
646                 }\r
647         }\r
648         \r
649 \r
650         \r
651         public class ResourceComparator implements Comparator<Resource> {\r
652                 @Override\r
653                 public int compare(Resource o1, Resource o2) {\r
654                         if (o1.getResourceId() < o2.getResourceId())\r
655                                 return -1;\r
656                         if (o1.getResourceId() > o2.getResourceId())\r
657                                 return 1;\r
658                         return 0;\r
659                 }\r
660         }\r
661 }\r