]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
Fix
[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.HashMap;\r
20 import java.util.HashSet;\r
21 import java.util.List;\r
22 import java.util.Map;\r
23 import java.util.Set;\r
24 import java.util.Stack;\r
25 \r
26 import org.simantics.db.ReadGraph;\r
27 import org.simantics.db.Resource;\r
28 import org.simantics.db.Statement;\r
29 import org.simantics.db.common.utils.NameUtils;\r
30 import org.simantics.db.exception.DatabaseException;\r
31 import org.simantics.db.exception.DoesNotContainValueException;\r
32 import org.simantics.db.exception.ServiceException;\r
33 import org.simantics.db.exception.ValidationException;\r
34 import org.simantics.layer0.Layer0;\r
35 import org.simantics.utils.datastructures.BijectionMap;\r
36 import org.simantics.utils.datastructures.MapList;\r
37 import org.simantics.utils.datastructures.Pair;\r
38 \r
39 /**\r
40  * Compares two subgraphs and reports differences.\r
41  * \r
42  * Assumes that subgraphs (defined using traverse relations) are not cyclic.\r
43  * \r
44  * Assumes that properties can be used to identify objects, if relation type is not enough.\r
45  * \r
46  * \r
47  * \r
48  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
49  *\r
50  */\r
51 public class GraphComparator {\r
52 \r
53         private Resource r1;\r
54         private Resource r2;\r
55         private List<Resource> traversed = new ArrayList<Resource>(); // list of relations that are traversed (and tested)\r
56         private List<Resource> tested = new ArrayList<Resource>();    // list of relations that are tested, but not traversed\r
57         private List<Resource> nonTraversed = new ArrayList<Resource>(); // list of relations that are not traversed\r
58         private List<Resource> nonTested = new ArrayList<Resource>(); // list of relations that are not tested\r
59         \r
60         private List<Statement> changes1 = new ArrayList<Statement>();\r
61         private List<Statement> changes2 = new ArrayList<Statement>();\r
62         private List<Pair<Statement,Statement>> modifications = new ArrayList<Pair<Statement,Statement>>();\r
63         private Set<Statement> changes1Set = new HashSet<Statement>();\r
64         private Set<Statement> changes2Set = new HashSet<Statement>();\r
65         private Set<Pair<Statement,Statement>> modificationsSet = new HashSet<Pair<Statement,Statement>>();\r
66 \r
67         private BijectionMap<Statement, Statement> comparableStatements = new BijectionMap<Statement, Statement>();\r
68         private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();\r
69         \r
70         \r
71         private ResourceComparator comparator;\r
72         \r
73         private Comparator<Statement> scomp = new PredicateComparator();\r
74         private Comparator<Resource> rcomp = new ResComparator();\r
75         \r
76         // runtime attributes\r
77         \r
78         private ReadGraph g;\r
79         private Layer0 b;\r
80         \r
81         public GraphComparator(Resource r1, Resource r2) {\r
82                 this.r1 = r1;\r
83                 this.r2 = r2;\r
84                 comparator = new TypeComparator();\r
85         }\r
86         \r
87         public GraphComparator(Resource r1, Resource r2, ResourceComparator comparator) {\r
88                 this.r1 = r1;\r
89                 this.r2 = r2;\r
90                 this.comparator = comparator;\r
91         }\r
92         \r
93         ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
94         ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
95         \r
96         \r
97         public Comparator<Resource> getResourceComparator() {\r
98                 return rcomp;\r
99         }\r
100         \r
101         public Comparator<Statement> getStatementComparator() {\r
102                 return scomp;\r
103         }\r
104         \r
105         public Resource getR1() {\r
106                 return r1;\r
107         }\r
108         \r
109         public Resource getR2() {\r
110                 return r2;\r
111         }\r
112         \r
113         public void addTraversed(Resource rel) {\r
114                 traversed.add(rel);\r
115         }\r
116         \r
117         public void addTraversed(Collection<Resource> rels) {\r
118                 traversed.addAll(rels);\r
119         }\r
120         \r
121         public void addNonTraversed(Resource rel) {\r
122                 nonTraversed.add(rel);\r
123         }\r
124         \r
125         public void addNonTraversed(Collection<Resource> rels) {\r
126                 nonTraversed.addAll(rels);\r
127         }\r
128         \r
129         public void addTested(Resource rel) {\r
130                 tested.add(rel);\r
131         }\r
132         \r
133         public void addTested(Collection<Resource> rels) {\r
134                 tested.addAll(rels);\r
135         }\r
136         \r
137         public void addNonTested(Resource rel) {\r
138                 nonTested.add(rel);\r
139         }\r
140         \r
141         public void addNonTested(Collection<Resource> rels) {\r
142                 nonTested.addAll(rels);\r
143         }\r
144         \r
145         public void addComparableResources(Resource r1, Resource r2) {\r
146                 comparableResources.map(r1, r2);\r
147         }\r
148         \r
149         public void addComparableResources(BijectionMap<Resource, Resource> matching) {\r
150                 comparableResources.addAll(matching);\r
151         }\r
152         \r
153         public void clearRels() {\r
154                 traversed.clear();\r
155                 tested.clear();\r
156                 nonTraversed.clear();\r
157                 nonTested.clear();\r
158         }\r
159         \r
160         public void test(ReadGraph g) throws DatabaseException {\r
161                 this.g = g;\r
162                 this.b = Layer0.getInstance(g);\r
163                 comparator.setComparator(this);\r
164                 \r
165                 Stack<Resource> objectsLeft = new Stack<Resource>();\r
166                 Stack<Resource> objectsRight = new Stack<Resource>();\r
167                 objectsLeft.push(r1);\r
168                 objectsRight.push(r2);\r
169                 \r
170                 \r
171                 List<Statement> ss1 = new ArrayList<Statement>();\r
172                 List<Statement> ss2 = new ArrayList<Statement>();\r
173                 \r
174                 Set<Statement> unreliableLeft = new HashSet<Statement>();\r
175                 Set<Statement> unreliableRight = new HashSet<Statement>();\r
176                 \r
177                 while (!objectsLeft.isEmpty()) {\r
178                         Resource r1 = objectsLeft.pop();\r
179                         Resource r2 = objectsRight.pop();\r
180                 \r
181                         if (comparableResources.contains(r1, r2)) {\r
182                                 //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
183                                 continue;\r
184                         }\r
185                         comparableResources.map(r1, r2);\r
186                         \r
187                         //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
188                         compareProps(r1, r2);\r
189                         \r
190                         for (Resource rel : tested) {\r
191                                 ss1.addAll(g.getStatements(r1, rel));\r
192                                 ss2.addAll(g.getStatements(r2, rel));\r
193                                 ss1 = filterAsserted(r1, ss1);\r
194                                 ss2 = filterAsserted(r2, ss2);\r
195                                 ss1 = filterTraversed(ss1);\r
196                                 ss2 = filterTraversed(ss2);\r
197                                 ss1 = filterNonTested(ss1);\r
198                                 ss2 = filterNonTested(ss2);\r
199                                 \r
200                                 compareStatements(ss1, ss2, null, null,null,null);\r
201                                 ss1.clear();\r
202                                 ss2.clear();\r
203                         }\r
204                         \r
205                         for (Resource rel : traversed) {\r
206                                 ss1.addAll(g.getStatements(r1, rel));\r
207                                 ss2.addAll(g.getStatements(r2, rel));\r
208                                 ss1 = filterAsserted(r1, ss1);\r
209                                 ss2 = filterAsserted(r2, ss2);\r
210                                 compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
211                                 ss1.clear();\r
212                                 ss2.clear();\r
213                                 \r
214                         }\r
215                 }\r
216                 MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
217                 MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
218                 MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
219                 MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
220                 \r
221                 for (Statement s : unreliableLeft) {\r
222                         subjectLeft.add(s.getSubject(),s);\r
223                         objectLeft.add(s.getObject(),s);\r
224                 }\r
225                 for (Statement s : unreliableRight) {\r
226                         subjectRight.add(s.getSubject(),s);\r
227                         objectRight.add(s.getObject(),s);\r
228                 }\r
229                 \r
230                 for (Resource ol : objectLeft.getKeys()) {\r
231 \r
232                         // all statements to the left side object\r
233                         List<Statement> left = objectLeft.getValues(ol);\r
234                         // all subjects that have statements to the left side object (ol)\r
235                         Set<Resource> sLeft = new HashSet<Resource>();\r
236                         // all matching subjects on the right side\r
237                         Set<Resource> sRight = new HashSet<Resource>();\r
238                         for (Statement s : left) {\r
239                                 sLeft.add(s.getSubject());\r
240                                 sRight.add(comparableResources.getRight(s.getSubject()));\r
241                         }\r
242                         // all objects that subjects on the right side point to. Object left has its matching resource among these, if it has matching resource\r
243                         MapList<Resource,Statement> possibleOR = new MapList<Resource, Statement>();\r
244                         for (Resource sr : sRight) {\r
245                                 for (Statement s : subjectRight.getValues(sr))\r
246                                         possibleOR.add(s.getObject(),s);\r
247                         }\r
248                         \r
249                         // filter possible right side objects to those that have same amount of statements as the left side object\r
250                         for (Resource or : possibleOR.getKeys().toArray(new Resource[possibleOR.getKeys().size()])) {\r
251                                 List<Statement> right = possibleOR.getValues(or);\r
252                                 if (right.size() != left.size())\r
253                                         possibleOR.remove(or);\r
254                                         \r
255                         }\r
256                         \r
257                         // check for matching statements (comparable subjects, matching predicates)\r
258                         MapList<Resource,Statement> matchingOR = new MapList<Resource, Statement>(); // list of objects that have matching statements\r
259                         Map<Resource,Pair<int[], int[]>> matchingStatements = new HashMap<Resource, Pair<int[], int[]>>(); // matching statements\r
260                         for (Resource or : possibleOR.getKeys()) {\r
261                                 List<Statement> right = possibleOR.getValues(or);\r
262                                 int iLeft[] = new int[left.size()];\r
263                                 int iRight[] = new int[right.size()];\r
264                                 \r
265                                 for (int i = 0; i < left.size(); i++) {\r
266                                         iLeft[i] = -1;\r
267                                         iRight[i] = -1;\r
268                                 }\r
269                                 \r
270                                 for (int l = 0; l < left.size(); l++) {\r
271                                         Statement ls = left.get(l);\r
272                                         for (int r = 0; r < right.size(); r++) {\r
273                                                 if (iRight[r] >= 0)\r
274                                                         continue;\r
275                                                 Statement rs = right.get(r);\r
276                                                 if (!comparableResources.contains(ls.getSubject(), rs.getSubject()))\r
277                                                         continue;\r
278                                                 if (rcomp.compare(ls.getPredicate(),rs.getPredicate()) == 0) {\r
279                                                         iLeft[l] = r;\r
280                                                         iRight[r] = l;\r
281                                                         break;\r
282                                                 }\r
283                                         }\r
284                                         \r
285                                 }\r
286                                 boolean success = true;\r
287                                 for (int i = 0; i < left.size(); i++) {\r
288                                         if (iLeft[i] < 0) {\r
289                                                 success = false;\r
290                                                 break;\r
291                                         }\r
292                                         if (iRight[i] < 0) {\r
293                                                 success = false;\r
294                                                 break;\r
295                                         }\r
296                                                 \r
297                                 }\r
298                                 if (success) {\r
299                                         for (Statement s : right) \r
300                                                 matchingOR.add(or,s);\r
301                                         matchingStatements.put(or, new Pair<int[], int[]>(iLeft, iRight));\r
302                                 }\r
303                         }\r
304                         // if there is only one matching right side object, we have found a match \r
305                         if (matchingOR.getKeySize() == 1) {\r
306                                 Resource or = matchingOR.getKeys().iterator().next();\r
307                                 List<Statement> right = matchingOR.getValues(or);\r
308                                 Pair<int[], int[]> indices = matchingStatements.get(or);\r
309                                 \r
310                                 comparableResources.map(ol, or);\r
311                                 for (int l = 0; l < left.size(); l++) {\r
312                                         int r = indices.first[l];\r
313                                         comparableStatements.map(left.get(l), right.get(r));\r
314                                 }\r
315                                 \r
316                         }\r
317 \r
318                 }\r
319                 \r
320                 for (Statement s : unreliableLeft) {\r
321                         if (!comparableStatements.containsLeft(s))\r
322                                 addDeletion(s);\r
323                 }\r
324                 for (Statement s : unreliableRight) {\r
325                         if (!comparableStatements.containsRight(s))\r
326                                 addAddition(s);\r
327                 }\r
328                 \r
329                 \r
330         }\r
331         \r
332         \r
333         \r
334         public BijectionMap<Statement, Statement> getComparableStatements() {\r
335                 return comparableStatements;\r
336         }\r
337         \r
338         public GraphChanges getChanges() {\r
339                 return new GraphChanges(r1,r2,changes1,changes2,modifications,comparableResources);\r
340         }\r
341         \r
342         private List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
343                 List<Statement> out = new ArrayList<Statement>();\r
344                 for (Statement s : in) {\r
345                         if (!s.isAsserted(r))\r
346                                 out.add(s);\r
347                         \r
348                 }\r
349                 return out;\r
350         }\r
351         \r
352         private String printStatement(ReadGraph graph, Statement s) throws ValidationException, ServiceException {\r
353                 return NameUtils.getSafeName(graph, s.getSubject()) + " " + NameUtils.getSafeName(graph, s.getPredicate()) + " " + NameUtils.getSafeName(graph, s.getObject());\r
354         }\r
355         \r
356         private List<Statement> filterTraversed(List<Statement> in) throws ServiceException {\r
357                 return filter(traversed, in);\r
358         }\r
359         \r
360         private List<Statement> filterNonTested(List<Statement> in) throws ServiceException {\r
361                 return filter(nonTested, in);\r
362         }\r
363         \r
364         private List<Statement> filter(Collection<Resource> toFilter, List<Statement> in) throws ServiceException {\r
365                 if (toFilter.size() == 0)\r
366                         return in;\r
367                 List<Statement> out = new ArrayList<Statement>();\r
368                 for (Statement s : in) {\r
369                         boolean usable = true;\r
370                         for (Resource r : toFilter) {\r
371                                 if (g.isSubrelationOf(s.getPredicate(),r)) {\r
372                                         usable = false;\r
373                                         break;\r
374                                 }\r
375                         }\r
376                         if (usable) {\r
377                                 out.add(s);\r
378                         }\r
379                         \r
380                 }\r
381                 return out;\r
382         }\r
383         \r
384         \r
385         private void addDeletion(Statement s) {\r
386                 if (!changes1Set.contains(s)) {\r
387                         changes1Set.add(s);\r
388                         changes1.add(s);\r
389                 }\r
390         }\r
391         \r
392         private void addAddition(Statement s) {\r
393                 if (!changes2Set.contains(s)) {\r
394                         changes2Set.add(s);\r
395                         changes2.add(s);\r
396                 }\r
397         }\r
398         \r
399         private void addModification(Statement s1, Statement s2) {\r
400                 Pair<Statement, Statement> mod = new Pair<Statement, Statement>(s1,s2);\r
401                 if (!modificationsSet.contains(mod)) {\r
402                         modificationsSet.add(mod);\r
403                         modifications.add(mod);\r
404                 }\r
405         }\r
406         \r
407         public void sortStatement(List<Statement> list1, List<Statement> list2) {\r
408                 sortStatement(list1, list2, scomp);\r
409         }\r
410         \r
411         public void sortStatement(List<Statement> list1, List<Statement> list2, Comparator<Statement> scomp) {\r
412                 Collections.sort(list1,scomp);\r
413                 Collections.sort(list2,scomp);\r
414                 \r
415                 List<Statement> sorted1 = new ArrayList<Statement>(list1.size());\r
416                 List<Statement> sorted2 = new ArrayList<Statement>(list2.size());\r
417                 sorted1.addAll(list1);\r
418                 sorted2.addAll(list2);\r
419                 \r
420                 int ss1 = 0;\r
421                 int ss2 = 0;\r
422                 for (int i = 0; i < list1.size(); ) {\r
423                         Statement s1 = list1.get(i);\r
424                         int same1 = sameRel(list1, i);  \r
425                         for (int j = 0; j < list2.size(); j++) {\r
426                                 Statement s2 = list2.get(j);\r
427                                 if (scomp.compare(s1, s2) == 0) {\r
428                                         int same2 = sameRel(list2, j);\r
429                                         copy(sorted1,ss1,list1,i,same1);\r
430                                         ss1 += same1;\r
431                                         copy(sorted2,ss2,list2,j,same2);\r
432                                         ss2 += same2;\r
433                                         break;\r
434                                 }\r
435                         }\r
436                         i+= same1;\r
437                 }\r
438                 if (ss1 < sorted1.size()) {\r
439                         for (Statement s : list1) {\r
440                                 if (!sorted1.contains(s)) {\r
441                                         sorted1.set(ss1,s);\r
442                                         ss1++;\r
443                                 }\r
444                         }\r
445                 }\r
446                 if (ss2 < sorted2.size()) {\r
447                         for (Statement s : list2) {\r
448                                 if (!sorted2.contains(s)) {\r
449                                         sorted2.set(ss2,s);\r
450                                         ss2++;\r
451                                 }\r
452                         }\r
453                 }\r
454                 \r
455                 list1.clear();\r
456                 list2.clear();\r
457                 list1.addAll(sorted1);\r
458                 list2.addAll(sorted2);\r
459         }\r
460         \r
461         public <T> void copy(List<T> to, int toIndex, List<T> from, int fromIndex, int amount) {\r
462                 for (int i = 0; i <  amount; i++) {\r
463                         to.set(toIndex + i, from.get(fromIndex+ i));\r
464                 }\r
465         }\r
466         \r
467         public void sortResource(List<Resource> list1, List<Resource> list2) {\r
468                 Collections.sort(list1,rcomp);\r
469                 int js = 0;\r
470                 for (int i = 0; i < list1.size(); i++) {\r
471                         Resource s1 = list1.get(i);\r
472                         for (int j = js; j < list2.size(); j++) {\r
473                                 Resource s2 = list2.get(j);\r
474                                 if (rcomp.compare(s1, s2) == 0) {\r
475                                         Resource t = list2.get(js);\r
476                                         list2.set(js, s2);\r
477                                         list2.set(j, t);\r
478                                         break;\r
479                                 }\r
480                         }\r
481                         js++;\r
482                         \r
483                 }\r
484         }\r
485         \r
486         private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Collection<Statement> unreliableLeft, Collection<Statement> unreliableRight) throws DatabaseException {\r
487                 sortStatement(ss1, ss2);\r
488                 \r
489                 int i1 = 0;\r
490                 int i2 = 0;\r
491                 \r
492                 while (true) {\r
493                         if (i1 >= ss1.size()) {\r
494                                 if (i2 >= ss2.size()) {\r
495                                         break;\r
496                                 } else {\r
497                                         while (i2 < ss2.size()) {\r
498                                                 System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
499                                                 \r
500                                                 addAddition(ss2.get(i2));\r
501                                                 i2++;\r
502                                         }\r
503                                         break;\r
504                                 }\r
505                         } else if (i2 >= ss2.size()) {\r
506                                 while (i1 < ss1.size()) {\r
507                                         System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
508                                         addDeletion(ss1.get(i1));\r
509                                         i1++;\r
510                                 }\r
511                                 break;\r
512                         }\r
513                         int same1 = sameRel(ss1, i1);\r
514                         int same2 = sameRel(ss2, i2);\r
515                         int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
516                         if (c == 0) {\r
517                                 compareStatements(ss1, i1, same1, ss2, i2, same2,objectsLeft,objectsRight,unreliableLeft,unreliableRight);\r
518                                 i1+=same1;\r
519                                 i2+=same2;\r
520                         } else if (c < 0) {\r
521                                 for (int i = 0; i < same1; i++) {\r
522                                         System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1)));\r
523                                         addDeletion(ss1.get(i+i1));\r
524                                 }\r
525                                 i1 += same1;\r
526                         } else {\r
527                                 for (int i = 0; i < same2; i++) {\r
528                                         System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2)));\r
529                                         addAddition(ss2.get(i+i2));\r
530                                 }\r
531                                 \r
532                                 i2 += same2;\r
533                         }\r
534                         \r
535                 }\r
536         }\r
537         \r
538 \r
539         \r
540         private int sameRel(List<Statement> statements, int off) {\r
541                 if (statements.size() <= off)\r
542                         return 0;\r
543                 int same = 1;\r
544                 long id = statements.get(off).getPredicate().getResourceId();\r
545                 for (int i = off+1; i <statements.size(); i++) {\r
546                         if (statements.get(i).getPredicate().getResourceId() == id)\r
547                                 same++;\r
548                         else \r
549                                 break;\r
550                 }\r
551                 return same;\r
552                 \r
553         }\r
554 \r
555         private int compareObject(Resource o1, Resource o2) throws DatabaseException {\r
556                 if (comparableResources.contains(o1, o2))\r
557                         return (-1);\r
558                 if (comparableResources.containsLeft(o1))\r
559                         return Integer.MAX_VALUE;\r
560                 if (comparableResources.containsRight(o2))\r
561                         return Integer.MAX_VALUE;\r
562                 return comparator.compare(g, o1, o2);\r
563         }\r
564         \r
565         private void compareStatements(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Collection<Resource> objectsLeft, Collection<Resource> objectsRight, Collection<Statement> unreliableLeft, Collection<Statement> unreliableRight) throws DatabaseException {\r
566                 boolean[] used1 = new boolean[len1];\r
567                 for (int i = 0; i < used1.length; i++) {\r
568                         used1[i] = false;\r
569                 }\r
570                 \r
571                 boolean[] used2 = new boolean[len2];\r
572                 for (int i = 0; i < used2.length; i++) {\r
573                         used2[i] = false;\r
574                 }\r
575                 \r
576                 // left, right, difference\r
577                 List<List<Integer>> differences = new ArrayList<List<Integer>>();\r
578                 for (int i1 = off1; i1 < off1 + len1; i1++) {\r
579                         Statement s1 = ss1.get(i1);\r
580                         List<Integer> diff = new ArrayList<Integer>();\r
581                         for (int i2 = off2; i2 < off2 + len2; i2++) {\r
582                                 Statement s2 = ss2.get(i2);\r
583                                 int d = compareObject(s1.getObject(), s2.getObject());\r
584                                 diff.add(d);\r
585                         }\r
586                         differences.add(diff);\r
587                 }\r
588                 // difference, left\r
589                 MapList<Integer, Integer> priorities = new MapList<Integer, Integer>();\r
590                 for (int i = 0; i < differences.size(); i++) {\r
591                         List<Integer> list = differences.get(i);\r
592                         for (int j = 0; j < list.size(); j++) {\r
593                                 priorities.add(list.get(j), i);\r
594                         }\r
595                 }\r
596                 \r
597                 Integer[] pris = priorities.getKeys(new Integer[]{});\r
598                 Arrays.sort(pris);\r
599                 \r
600                 for (Integer pri : pris) {\r
601                         if (pri == Integer.MAX_VALUE) {\r
602 \r
603                         } else if (pri == 0) {\r
604                                 \r
605                         } else {\r
606                                 List<Integer> i1s = priorities.getValues(pri);\r
607                                 for (Integer i1 : i1s) {\r
608                                         if (used1[i1])\r
609                                                 continue;\r
610                                         List<Integer> i2diff = differences.get(i1);\r
611                                         for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
612                                                 if (i2diff.get(i2) == pri) {\r
613                                                         if (used2[i2])\r
614                                                                 continue;\r
615                                                         used1[i1] = true;\r
616                                                         used2[i2] = true;\r
617                                                         Statement s1  = ss1.get(i1+off1);\r
618                                                         Statement s2  = ss2.get(i2+off2);\r
619                                                         \r
620                                                         if (objectsLeft != null) {\r
621                                                                 \r
622                                                                         objectsLeft.add(s1.getObject());\r
623                                                                         objectsRight.add(s2.getObject());\r
624                                                                 \r
625                                                         } \r
626                                                         comparableStatements.map(s1, s2);\r
627                                                         //comparableResources.map(s1.getObject(), s2.getObject());\r
628                                                         break;\r
629                                                 }\r
630                                         }\r
631                                 }\r
632                         }\r
633                 }\r
634                 \r
635                 for (Integer pri : pris) {\r
636                         if (pri != 0)\r
637                                 continue;\r
638                         Set<Statement> s1s = new HashSet<Statement>();\r
639                         Set<Statement> s2s = new HashSet<Statement>();\r
640                         Set<Integer> s1i = new HashSet<Integer>();\r
641                         Set<Integer> s2i = new HashSet<Integer>();\r
642                         List<Integer> i1s = priorities.getValues(pri);\r
643                         for (Integer i1 : i1s) {\r
644                                 if (used1[i1])\r
645                                         continue;\r
646                                 List<Integer> i2diff = differences.get(i1);\r
647                                 for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
648                                         if (i2diff.get(i2) == pri) {\r
649                                                 if (used2[i2])\r
650                                                         continue;\r
651                                                 Statement s1  = ss1.get(i1+off1);\r
652                                                 Statement s2  = ss2.get(i2+off2);\r
653                                                 s1s.add(s1);\r
654                                                 s2s.add(s2);\r
655                                                 s1i.add(i1);\r
656                                                 s2i.add(i2);\r
657                                         }\r
658                                 }\r
659                         }\r
660                         if (unreliableLeft != null) {\r
661                                 unreliableLeft.addAll(s1s);\r
662                                 unreliableRight.addAll(s2s);\r
663                         }\r
664                         for (Integer i : s1i)\r
665                                 used1[i] = true;\r
666                         for (Integer i : s2i)\r
667                                 used2[i] = true;\r
668 \r
669                 }\r
670                 for (int i1 = off1; i1 < off1 + len1; i1++) {\r
671                         if (!used1[i1-off1]) {\r
672                                 System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1)));\r
673                                 addDeletion(ss1.get(i1));\r
674                         }\r
675                 }\r
676                 for (int i2 = off2; i2 < off2 + len2; i2++) {\r
677                         if (!used2[i2-off2]) {\r
678                                 System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2)));\r
679                                 addAddition(ss2.get(i2));\r
680                         }\r
681                 }\r
682         }\r
683         \r
684         \r
685         \r
686         /**\r
687          * compares properties, assumes functional relations\r
688          * @param r1\r
689          * @param r2\r
690          * @throws ServiceException\r
691          * @throws DoesNotContainValueException\r
692          * @throws ValidationException \r
693          */\r
694         private void compareProps(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
695                 ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
696                 ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
697                 ss1.addAll(g.getStatements(r1, b.HasProperty));\r
698                 ss2.addAll(g.getStatements(r2, b.HasProperty));\r
699                 sortStatement(ss1, ss2);\r
700 //              Collections.sort(ss1, scomp);\r
701 //              Collections.sort(ss2, scomp);\r
702                 \r
703                 int i1 = 0; \r
704                 int i2 = 0;\r
705                 \r
706                 while (true) {\r
707                         if (i1 >= ss1.size()) {\r
708                                 if (i2 >= ss2.size())\r
709                                         break;\r
710                                 else {\r
711                                         while (i2 < ss2.size()) {\r
712                                                 System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
713                                                 addAddition(ss2.get(i2));\r
714                                                 i2++;\r
715                                         }\r
716                                         break;\r
717                                 }\r
718                         } else if (i2 >= ss2.size()) {\r
719                                 while (i1 < ss1.size()) {\r
720                                         System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
721                                         addDeletion(ss1.get(i1));\r
722                                         i1++;\r
723                                 }\r
724                                 break;\r
725                         }\r
726                         Statement s1 = ss1.get(i1);\r
727                         Statement s2 = ss2.get(i2);\r
728                         int c = scomp.compare(s1, s2);\r
729                         switch (c) {\r
730                         case 0:{\r
731                                 boolean b1 = g.hasValue(s1.getObject());\r
732                                 boolean b2 = g.hasValue(s2.getObject());\r
733                                 if (b1 == b2) {\r
734                                         if (b1) {\r
735                                                 Object v1 = g.getValue(s1.getObject());\r
736                                                 Object v2 = g.getValue(s2.getObject());\r
737                                                 boolean eq = compareValue(v1, v2);\r
738                                                 if (!eq) {\r
739                                                         addModification(s1, s2);\r
740                                                         comparableStatements.map(s1, s2);\r
741                                                         comparableResources.map(s1.getObject(),s2.getObject());\r
742                                                 }\r
743                                         } else {\r
744                                                 compareProps(s1.getObject(), s2.getObject());\r
745                                         }\r
746                                 } else {\r
747                                         addModification(s1, s2);\r
748                                         comparableStatements.map(s1, s2);\r
749                                         comparableResources.map(s1.getObject(),s2.getObject());\r
750                                 }\r
751                                 i1++;\r
752                                 i2++;\r
753                                 break;\r
754                         }\r
755                         case -1:{\r
756                                 System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
757                                 addDeletion(s1);\r
758                                 i1++;\r
759                                 break;\r
760                         }\r
761                                 \r
762                         case 1:{\r
763                                 System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
764                                 addAddition(s2);\r
765                                 i2++;\r
766                                 break;\r
767                         }\r
768                         }\r
769                         \r
770                         \r
771                 }\r
772                 \r
773                 ss1.clear();\r
774                 ss2.clear();\r
775                 \r
776         }\r
777         \r
778         \r
779         public static boolean compareValue(Object v1, Object v2) {\r
780                 if (v1 instanceof Object[] && v2 instanceof Object[])\r
781                         return Arrays.deepEquals((Object[])v1, (Object[])v2);\r
782                 else if (v1 instanceof int[] && v2 instanceof int[]) \r
783                         return Arrays.equals((int[])v1, (int[])v2);\r
784                 else if (v1 instanceof float[] && v2 instanceof float[]) \r
785                         return Arrays.equals((float[])v1, (float[])v2);\r
786                 else if (v1 instanceof double[] && v2 instanceof double[]) \r
787                         return Arrays.equals((double[])v1, (double[])v2);\r
788                 else if (v1 instanceof long[] && v2 instanceof long[]) \r
789                         return  Arrays.equals((long[])v1, (long[])v2);\r
790                 else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
791                         return Arrays.equals((byte[])v1, (byte[])v2);\r
792                 else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
793                         return Arrays.equals((boolean[])v1, (boolean[])v2);\r
794                 else\r
795                         return v1.equals(v2);\r
796         }\r
797 \r
798         \r
799         \r
800         public class PredicateComparator implements Comparator<Statement> {\r
801                 @Override\r
802                 public int compare(Statement o1, Statement o2) {\r
803                         if (comparableResources.contains(o1.getPredicate(), o2.getPredicate()))\r
804                                 return 0;\r
805                         if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
806                                 return -1;\r
807                         if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
808                                 return 1;\r
809                         return 0;\r
810                 }\r
811         }\r
812         \r
813         public class SubjectComparator implements Comparator<Statement> {\r
814                 @Override\r
815                 public int compare(Statement o1, Statement o2) {\r
816                         if (comparableResources.contains(o1.getSubject(), o2.getSubject()))\r
817                                 return 0;\r
818                         if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
819                                 return -1;\r
820                         if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
821                                 return 1;\r
822                         return 0;\r
823                 }\r
824         }\r
825         \r
826         public class ObjectComparator implements Comparator<Statement> {\r
827                 @Override\r
828                 public int compare(Statement o1, Statement o2) {\r
829                         if (comparableResources.contains(o1.getObject(), o2.getObject()))\r
830                                 return 0;\r
831                         if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
832                                 return -1;\r
833                         if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
834                                 return 1;\r
835                         return 0;\r
836                 }\r
837         }\r
838         \r
839         public static class FullStatementComparator implements Comparator<Statement> {\r
840                 @Override\r
841                 public int compare(Statement o1, Statement o2) {\r
842                         if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
843                                 return -1;\r
844                         if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
845                                 return 1;\r
846                         if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
847                                 return -1;\r
848                         if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
849                                 return 1;\r
850                         if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
851                                 return -1;\r
852                         if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
853                                 return 1;\r
854                         return 0;\r
855                 }\r
856         }\r
857         \r
858 \r
859         \r
860         public class ResComparator implements Comparator<Resource> {\r
861                 @Override\r
862                 public int compare(Resource o1, Resource o2) {\r
863                         if (comparableResources.contains(o1, o2))\r
864                                 return 0;\r
865                         if (o1.getResourceId() < o2.getResourceId())\r
866                                 return -1;\r
867                         if (o1.getResourceId() > o2.getResourceId())\r
868                                 return 1;\r
869                         return 0;\r
870                 }\r
871         }\r
872         \r
873         \r
874 }\r