]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java
In some cases Comparator matched incorrect resources.
[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.ManyObjectsForFunctionalRelationException;\r
33 import org.simantics.db.exception.ServiceException;\r
34 import org.simantics.db.exception.ValidationException;\r
35 import org.simantics.layer0.Layer0;\r
36 import org.simantics.utils.datastructures.BijectionMap;\r
37 import org.simantics.utils.datastructures.MapList;\r
38 import org.simantics.utils.datastructures.Pair;\r
39 \r
40 /**\r
41  * Compares two subgraphs and reports differences.\r
42  * \r
43  * Assumes that subgraphs (defined using traverse relations) are not cyclic.\r
44  * \r
45  * Assumes that properties can be used to identify objects, if relation type is not enough.\r
46  * \r
47  * \r
48  * \r
49  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
50  *\r
51  */\r
52 public class GraphComparator {\r
53 \r
54         private Resource r1;\r
55         private Resource r2;\r
56         private Set<Resource> strong = new HashSet<Resource>();       // List of relations that identify object, if subject is already identified. \r
57         private List<Resource> traversed = new ArrayList<Resource>(); // list of relations that are traversed (and tested)\r
58         private List<Resource> tested = new ArrayList<Resource>();    // list of relations that are tested, but not traversed\r
59         private List<Resource> nonTraversed = new ArrayList<Resource>(); // list of relations that are not traversed\r
60         private List<Resource> nonTested = new ArrayList<Resource>(); // list of relations that are not tested\r
61         \r
62         private List<Statement> changes1 = new ArrayList<Statement>();\r
63         private List<Statement> changes2 = new ArrayList<Statement>();\r
64         private List<Pair<Statement,Statement>> modifications = new ArrayList<Pair<Statement,Statement>>();\r
65         private Set<Statement> changes1Set = new HashSet<Statement>();\r
66         private Set<Statement> changes2Set = new HashSet<Statement>();\r
67         private Set<Pair<Statement,Statement>> modificationsSet = new HashSet<Pair<Statement,Statement>>();\r
68 \r
69         private BijectionMap<Statement, Statement> comparableStatements = new BijectionMap<Statement, Statement>();\r
70         private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();\r
71         \r
72         \r
73         private ResourceComparator comparator;\r
74         \r
75         private Comparator<Statement> scomp = new PredicateComparator();\r
76         private Comparator<Resource> rcomp = new ResComparator();\r
77         \r
78         // runtime attributes\r
79         \r
80         private ReadGraph g;\r
81         private Layer0 b;\r
82         \r
83         public GraphComparator(Resource r1, Resource r2) {\r
84                 this.r1 = r1;\r
85                 this.r2 = r2;\r
86                 comparator = new TypeComparator();\r
87         }\r
88         \r
89         public GraphComparator(Resource r1, Resource r2, ResourceComparator comparator) {\r
90                 this.r1 = r1;\r
91                 this.r2 = r2;\r
92                 this.comparator = comparator;\r
93         }\r
94         \r
95         ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
96         ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
97         \r
98         \r
99         public Comparator<Resource> getResourceComparator() {\r
100                 return rcomp;\r
101         }\r
102         \r
103         public Comparator<Statement> getStatementComparator() {\r
104                 return scomp;\r
105         }\r
106         \r
107         public Resource getR1() {\r
108                 return r1;\r
109         }\r
110         \r
111         public Resource getR2() {\r
112                 return r2;\r
113         }\r
114         \r
115         public void addTraversed(Resource rel) {\r
116                 traversed.add(rel);\r
117         }\r
118         \r
119         public void addTraversed(Collection<Resource> rels) {\r
120                 traversed.addAll(rels);\r
121         }\r
122         \r
123         public void addNonTraversed(Resource rel) {\r
124                 nonTraversed.add(rel);\r
125         }\r
126         \r
127         public void addNonTraversed(Collection<Resource> rels) {\r
128                 nonTraversed.addAll(rels);\r
129         }\r
130         \r
131         public void addTested(Resource rel) {\r
132                 tested.add(rel);\r
133         }\r
134         \r
135         public void addTested(Collection<Resource> rels) {\r
136                 tested.addAll(rels);\r
137         }\r
138         \r
139         public void addNonTested(Resource rel) {\r
140                 nonTested.add(rel);\r
141         }\r
142         \r
143         public void addNonTested(Collection<Resource> rels) {\r
144                 nonTested.addAll(rels);\r
145         }\r
146         \r
147         public void addComparableResources(Resource r1, Resource r2) {\r
148                 comparableResources.map(r1, r2);\r
149         }\r
150         \r
151         public void addComparableResources(BijectionMap<Resource, Resource> matching) {\r
152                 comparableResources.addAll(matching);\r
153         }\r
154         \r
155         public void addStrong(Resource r) {\r
156                 strong.add(r);\r
157         }\r
158         \r
159         public void addStrong(Collection<Resource> rels) {\r
160                 strong.addAll(rels);\r
161         }\r
162         \r
163         public void clearRels() {\r
164                 traversed.clear();\r
165                 tested.clear();\r
166                 nonTraversed.clear();\r
167                 nonTested.clear();\r
168         }\r
169         \r
170         public void test(ReadGraph g) throws DatabaseException {\r
171                 this.g = g;\r
172                 this.b = Layer0.getInstance(g);\r
173                 comparator.setComparator(this);\r
174                 \r
175                 Stack<Resource> objectsLeft = new Stack<Resource>();\r
176                 Stack<Resource> objectsRight = new Stack<Resource>();\r
177                 objectsLeft.push(r1);\r
178                 objectsRight.push(r2);\r
179                 \r
180                 \r
181                 \r
182                 \r
183                 Set<Statement> unreliableLeft = new HashSet<Statement>();\r
184                 Set<Statement> unreliableRight = new HashSet<Statement>();\r
185                 \r
186                 while (true) {\r
187                         if (objectsLeft.isEmpty())\r
188                                 break;\r
189                         \r
190                         \r
191                         // process compares objects that are identified and searches for more resources to process. \r
192                         process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);\r
193                         // process unreliable handles cases where unidentified statements subject and object have been identified \r
194                         processUnreliable(unreliableLeft, unreliableRight);\r
195                         // process unreliable handles cases where unidentified resources have path of length one to identified resource\r
196                         processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);\r
197                         if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {\r
198                                 // comparison is ending, but we have still unprocessed unidentified resources left.\r
199                                 // These cases have longer path than one to identified objects.\r
200                                 processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);\r
201                         }\r
202                         \r
203                 }\r
204                 for (Statement s : unreliableLeft) {\r
205                         if (!comparableStatements.containsLeft(s))\r
206                                 addDeletion(s);\r
207                 }\r
208                 for (Statement s : unreliableRight) {\r
209                         if (!comparableStatements.containsRight(s))\r
210                                 addAddition(s);\r
211                 }\r
212                 \r
213                 \r
214         }\r
215         \r
216         private void process(Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {\r
217                 List<Statement> ss1 = new ArrayList<Statement>();\r
218                 List<Statement> ss2 = new ArrayList<Statement>();\r
219                 \r
220                 while (!objectsLeft.isEmpty()) {\r
221                         Resource r1 = objectsLeft.pop();\r
222                         Resource r2 = objectsRight.pop();\r
223                         \r
224 //                      if (r1.getResourceId() == 42543612 ||\r
225 //                              r1.getResourceId() == 42729524 ||\r
226 //                              r1.getResourceId() == 42729506) {\r
227 //                              System.out.println("test " + r1 + " " + r2);\r
228 //                      }\r
229                         \r
230                         if (r1.equals(r2))\r
231                                 continue;\r
232                 \r
233                         if (comparableResources.contains(r1, r2)) {\r
234                                 //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
235                                 continue;\r
236                         }\r
237                         if (comparableResources.containsLeft(r1) || comparableResources.containsRight(r2)) {\r
238                                 throw new DatabaseException("Comparator error: Trying to map " + r1 + " to " + r2 + " while mappings " + r1 + " to " + comparableResources.getRight(r1) + " and " + comparableResources.getLeft(r2) + " to " + r2 + " exist.");\r
239                         }\r
240                         comparableResources.map(r1, r2);\r
241                         \r
242                         //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
243                         compareProps(r1, r2);\r
244                         \r
245                         for (Resource rel : tested) {\r
246                                 ss1.addAll(g.getStatements(r1, rel));\r
247                                 ss2.addAll(g.getStatements(r2, rel));\r
248                                 ss1 = filterAsserted(r1, ss1);\r
249                                 ss2 = filterAsserted(r2, ss2);\r
250                                 ss1 = filterTraversed(ss1);\r
251                                 ss2 = filterTraversed(ss2);\r
252                                 ss1 = filterNonTested(ss1);\r
253                                 ss2 = filterNonTested(ss2);\r
254                                 \r
255                                 compareStatements(ss1, ss2, null, null,null,null);\r
256                                 ss1.clear();\r
257                                 ss2.clear();\r
258                         }\r
259                         \r
260                         for (Resource rel : traversed) {\r
261                                 ss1.addAll(g.getStatements(r1, rel));\r
262                                 ss2.addAll(g.getStatements(r2, rel));\r
263                                 ss1 = filterAsserted(r1, ss1);\r
264                                 ss2 = filterAsserted(r2, ss2);\r
265                                 compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
266                                 ss1.clear();\r
267                                 ss2.clear();\r
268                                 \r
269                         }\r
270                 }\r
271         }\r
272         \r
273         private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight) {\r
274                 MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
275                 MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
276                 MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
277                 MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
278                 \r
279                 for (Statement s : unreliableLeft) {\r
280                         subjectLeft.add(s.getSubject(),s);\r
281                         objectLeft.add(s.getObject(),s);\r
282                 }\r
283                 for (Statement s : unreliableRight) {\r
284                         subjectRight.add(s.getSubject(),s);\r
285                         objectRight.add(s.getObject(),s);\r
286                 }\r
287                 \r
288                 for (Resource left : subjectLeft.getKeys()) {\r
289                         if (!comparableResources.containsLeft(left))\r
290                                 continue;\r
291                         Resource right = comparableResources.getRight(left);\r
292                         for (Statement leftS : subjectLeft.getValues(left)) {\r
293                                 Resource leftO = leftS.getObject();\r
294                                 if (!comparableResources.containsLeft(leftO)) \r
295                                         continue;\r
296                                 if (!unreliableLeft.contains(leftS))\r
297                                         continue;\r
298                                 Resource rightO = comparableResources.getRight(leftO);\r
299                                 for (Statement rightS : subjectRight.getValues(right)) {\r
300                                         if (!rightS.getObject().equals(rightO))\r
301                                                 continue;\r
302                                         if (!unreliableRight.contains(rightS))\r
303                                                 continue;\r
304                                         if (leftS.getPredicate().equals(rightS.getPredicate()) ||\r
305                                                 comparableResources.contains(leftS.getPredicate(), rightS.getPredicate())) {\r
306                                                 unreliableLeft.remove(leftS);\r
307                                                 unreliableRight.remove(rightS);\r
308                                                 comparableStatements.map(leftS, rightS);\r
309                                         }\r
310                                 }\r
311                         }\r
312                         \r
313                 }\r
314         }\r
315         \r
316         private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) {\r
317                 MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
318                 MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
319                 MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
320                 MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
321                 \r
322                 for (Statement s : unreliableLeft) {\r
323                         subjectLeft.add(s.getSubject(),s);\r
324                         objectLeft.add(s.getObject(),s);\r
325                 }\r
326                 for (Statement s : unreliableRight) {\r
327                         subjectRight.add(s.getSubject(),s);\r
328                         objectRight.add(s.getObject(),s);\r
329                 }\r
330                 \r
331                 for (Resource ol : objectLeft.getKeys()) {\r
332 //                      if (ol.getResourceId() == 42729506) {\r
333 //                              System.out.println();\r
334 //                      }\r
335                         // all statements to the left side object\r
336                         List<Statement> left = objectLeft.getValues(ol);\r
337                         // all subjects that have statements to the left side object (ol)\r
338                         Set<Resource> sLeft = new HashSet<Resource>();\r
339                         // all matching subjects on the right side\r
340                         Set<Resource> sRight = new HashSet<Resource>();\r
341                         for (Statement s : left) {\r
342                                 sLeft.add(s.getSubject());\r
343                                 sRight.add(comparableResources.getRight(s.getSubject()));\r
344                         }\r
345                         \r
346                         // check if object left can be reliably identified by available statements\r
347                         // if there are any objects on the left side with similar statements, object left cannot be mapped.\r
348                         boolean hasSimilar = false;\r
349                         MapList<Resource, Statement> comparableOLeft = new MapList<Resource, Statement>();\r
350                         for (Resource sl : sLeft) {\r
351                                 for (Statement s : subjectLeft.getValues(sl)) {\r
352                                         if (!s.getObject().equals(ol)) {\r
353                                                 comparableOLeft.add(s.getObject(),s);\r
354                                         }\r
355                                 }\r
356                         }\r
357                         \r
358                         for (Resource similarOl : comparableOLeft.getKeys()) {\r
359                                 List<Statement> similarLeft = comparableOLeft.getValues(similarOl);\r
360                                 if (similarLeft.size() == left.size()) {\r
361                                         boolean useL[] = new boolean[left.size()];\r
362                                         boolean useSL[] = new boolean[left.size()];\r
363                                         for (int i = 0; i < left.size(); i++) {\r
364                                                 useL[i] = false;\r
365                                                 useSL[i] = false;\r
366                                         }\r
367                                         for (int i = 0; i < left.size(); i++) {\r
368                                                 for (int j = 0; j < left.size(); j++) {\r
369                                                         if (useSL[j])\r
370                                                                 continue;\r
371                                                         Resource pl = left.get(i).getPredicate();\r
372                                                         Resource psl = similarLeft.get(j).getPredicate();\r
373                                                         if (pl.equals(psl)) {\r
374                                                                 useL[i] = true;\r
375                                                                 useSL[j] = true;\r
376                                                                 break;\r
377                                                         }\r
378                                                 }\r
379                                         }\r
380                                         boolean diff = false;\r
381                                         for (int i = 0; i < left.size(); i++) {\r
382                                                 if (!useL[i] || !useSL[i]) {\r
383                                                         diff = true;\r
384                                                 }\r
385                                         }\r
386                                         if (!diff) {\r
387                                                 hasSimilar = true;\r
388                                                 break;\r
389                                         }\r
390                                 }\r
391                         }\r
392                         \r
393                         if (hasSimilar)\r
394                                 continue;\r
395                                 \r
396                         \r
397                         // all objects that subjects on the right side point to. Object left has its matching resource among these, if it has matching resource\r
398                         MapList<Resource,Statement> possibleOR = new MapList<Resource, Statement>();\r
399                         for (Resource sr : sRight) {\r
400                                 for (Statement s : subjectRight.getValues(sr))\r
401                                         possibleOR.add(s.getObject(),s);\r
402                         }\r
403                         \r
404                         // filter possible right side objects to those that have same amount of statements as the left side object\r
405                         for (Resource or : possibleOR.getKeys().toArray(new Resource[possibleOR.getKeys().size()])) {\r
406                                 List<Statement> right = possibleOR.getValues(or);\r
407                                 if (right.size() != left.size())\r
408                                         possibleOR.remove(or);\r
409                                         \r
410                         }\r
411                         \r
412                         // check for matching statements (comparable subjects, matching predicates)\r
413                         MapList<Resource,Statement> matchingOR = new MapList<Resource, Statement>(); // list of objects that have matching statements\r
414                         Map<Resource,Pair<int[], int[]>> matchingStatements = new HashMap<Resource, Pair<int[], int[]>>(); // matching statements\r
415                         for (Resource or : possibleOR.getKeys()) {\r
416                                 List<Statement> right = possibleOR.getValues(or);\r
417                                 int iLeft[] = new int[left.size()];\r
418                                 int iRight[] = new int[right.size()];\r
419                                 \r
420                                 for (int i = 0; i < left.size(); i++) {\r
421                                         iLeft[i] = -1;\r
422                                         iRight[i] = -1;\r
423                                 }\r
424                                 \r
425                                 for (int l = 0; l < left.size(); l++) {\r
426                                         Statement ls = left.get(l);\r
427                                         for (int r = 0; r < right.size(); r++) {\r
428                                                 if (iRight[r] >= 0)\r
429                                                         continue;\r
430                                                 Statement rs = right.get(r);\r
431                                                 if (!comparableResources.contains(ls.getSubject(), rs.getSubject()))\r
432                                                         continue;\r
433                                                 if (rcomp.compare(ls.getPredicate(),rs.getPredicate()) == 0) {\r
434                                                         iLeft[l] = r;\r
435                                                         iRight[r] = l;\r
436                                                         break;\r
437                                                 }\r
438                                         }\r
439                                         \r
440                                 }\r
441                                 boolean success = true;\r
442                                 for (int i = 0; i < left.size(); i++) {\r
443                                         if (iLeft[i] < 0) {\r
444                                                 success = false;\r
445                                                 break;\r
446                                         }\r
447                                         if (iRight[i] < 0) {\r
448                                                 success = false;\r
449                                                 break;\r
450                                         }\r
451                                                 \r
452                                 }\r
453                                 if (success) {\r
454                                         for (Statement s : right) \r
455                                                 matchingOR.add(or,s);\r
456                                         matchingStatements.put(or, new Pair<int[], int[]>(iLeft, iRight));\r
457                                 }\r
458                         }\r
459                         // if there is only one matching right side object, we have found a match \r
460                         if (matchingOR.getKeySize() == 1) {\r
461                                 Resource or = matchingOR.getKeys().iterator().next();\r
462                                 List<Statement> right = matchingOR.getValues(or);\r
463                                 Pair<int[], int[]> indices = matchingStatements.get(or);\r
464                                 \r
465                                 //comparableResources.map(ol, or);\r
466                                 objectsLeft.add(ol);\r
467                                 objectsRight.add(or);\r
468                                 for (int l = 0; l < left.size(); l++) {\r
469                                         int r = indices.first[l];\r
470                                         Statement sl = left.get(l);\r
471                                         Statement sr = right.get(r);\r
472                                         addComparable(sl, sr, true);\r
473                                         unreliableLeft.remove(sl);\r
474                                         unreliableRight.remove(sr);\r
475                                 }\r
476                                 \r
477                         }\r
478 \r
479                 }\r
480                 \r
481                 \r
482         }\r
483         \r
484         private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
485                 MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
486                 MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
487                 MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
488                 MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
489                 \r
490                 for (Statement s : unreliableLeft) {\r
491                         subjectLeft.add(s.getSubject(),s);\r
492                         objectLeft.add(s.getObject(),s);\r
493                 }\r
494                 for (Statement s : unreliableRight) {\r
495                         subjectRight.add(s.getSubject(),s);\r
496                         objectRight.add(s.getObject(),s);\r
497                 }\r
498                 for (Resource ol : objectLeft.getKeys()) {\r
499                         Set<Path> pathsLeft = new HashSet<Path>();\r
500                         for (Resource rel : traversed) {\r
501                                 pathsLeft.addAll(Path.create(g.getStatements(ol, rel)));\r
502                         }\r
503                         while (true) {\r
504                                 expand(pathsLeft);\r
505                                 if (pathsLeft.size() == 0)\r
506                                         break;\r
507                                 Collection<Path> endPaths = new ArrayList<Path>(1);\r
508                                 for (Path p : pathsLeft) {\r
509                                         if (comparableResources.containsLeft(p.getEnd())) {\r
510                                                 endPaths.add(p);\r
511                                         }\r
512                                 }\r
513                                 if (endPaths.size() > 0) {\r
514                                         pathsLeft.clear();\r
515                                         pathsLeft.addAll(endPaths);\r
516                                         break;\r
517                                 }       \r
518                         }\r
519                         if (pathsLeft.size() > 0) {\r
520                                 Resource sl = objectLeft.getValues(ol).get(0).getSubject();\r
521                                 Resource sr = comparableResources.getRight(sl);\r
522                                 Collection<Resource> possibleOR = new ArrayList<Resource>();\r
523                                 for (Statement s : subjectRight.getValues(sr)) {\r
524                                         possibleOR.add(s.getObject());\r
525                                 }\r
526                                 Map<Resource,Set<Path>> matchingPaths = new HashMap<Resource, Set<Path>>();\r
527                                 for (Resource or : possibleOR) {\r
528                                         Set<Path> possiblePathsRight = new HashSet<Path>();\r
529                                         for (Path leftPath : pathsLeft) {\r
530                                                 possiblePathsRight.addAll(findComparableRight(leftPath, or));\r
531                                         }\r
532                                         if (possiblePathsRight.size() == pathsLeft.size()) {\r
533                                                 matchingPaths.put(or, possiblePathsRight);\r
534                                         }\r
535                                 }\r
536                                 if (matchingPaths.size() > 0) {\r
537                                         if (matchingPaths.size() == 1) {\r
538                                                 Resource or = matchingPaths.keySet().iterator().next();\r
539                                                 objectsLeft.add(ol);\r
540                                                 objectsRight.add(or);\r
541                                                 Collection<Statement> statementsLeft = objectLeft.getValues(ol);\r
542                                                 Collection<Statement> statementsRight = objectRight.getValues(or);\r
543                                                 unreliableLeft.removeAll(statementsLeft);\r
544                                                 unreliableRight.removeAll(statementsRight);\r
545                                                 System.out.println();\r
546                                         } else {\r
547                                                 System.out.println();\r
548                                         }\r
549                                 }\r
550                         }\r
551                         \r
552                 }\r
553                 \r
554         }\r
555         \r
556         private void expand(Set<Path> paths) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
557                 Set<Path> stepPathsLeft = new HashSet<Path>();\r
558                 if (paths.size() == 0)\r
559                         return;\r
560                 int length = paths.iterator().next().getLength() + 1;\r
561                 for (Path p : paths) {\r
562                         for (Resource rel : traversed) {\r
563                                 stepPathsLeft.addAll(Path.expand(p,g.getStatements(p.getEnd(), rel)));\r
564                         }\r
565                 }\r
566                 paths.clear();\r
567                 for (Path p : stepPathsLeft) {\r
568                         if (p.getLength() == length)\r
569                                 paths.add(p);\r
570                 }\r
571         }\r
572         \r
573         private Collection<Path> findComparableRight(Path leftPath, Resource beginRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
574                 Set<Path> rightPaths = new HashSet<Path>();\r
575                 rightPaths.addAll(Path.create(g.getStatements(beginRight, getRight(leftPath.getStatements().get(0).getPredicate()))));\r
576                 for (int i = 1; i < leftPath.getLength(); i++) {\r
577                         if (rightPaths.size() == 0)\r
578                                 return rightPaths;\r
579                         Set<Path> stepPaths = new HashSet<Path>();\r
580                         for (Path p : rightPaths) {\r
581                                 stepPaths.addAll(Path.expand(p, g.getStatements(p.getEnd(), getRight(leftPath.getStatements().get(i).getPredicate()))));\r
582                         }\r
583                         rightPaths.clear();\r
584                         for (Path p : stepPaths)\r
585                                 if (p.getLength() == i+1) \r
586                                         rightPaths.add(p);\r
587                 }\r
588                 return rightPaths;\r
589                 \r
590         }\r
591         \r
592         private Resource getRight(Resource r) {\r
593                 if (comparableResources.containsLeft(r))\r
594                         return comparableResources.getRight(r);\r
595                 return r;\r
596         }\r
597         \r
598 \r
599         \r
600         public BijectionMap<Statement, Statement> getComparableStatements() {\r
601                 return comparableStatements;\r
602         }\r
603         \r
604         public GraphChanges getChanges() {\r
605                 return new GraphChanges(r1,r2,changes1,changes2,modifications,comparableResources);\r
606         }\r
607         \r
608         private void addComparable(Statement left, Statement right, boolean process) {\r
609 //              if (left.getObject().getResourceId() == 42543612 ||\r
610 //                      left.getObject().getResourceId() == 42729524 ||\r
611 //                      left.getObject().getResourceId() == 42729506) {\r
612 //                              System.out.println("test " + r1 + " " + r2);\r
613 //                      }\r
614                 comparableStatements.map(left, right);\r
615                 if (!process) {\r
616                         comparableResources.map(left.getObject(), right.getObject());\r
617                 }\r
618         }\r
619         \r
620         public List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
621                 List<Statement> out = new ArrayList<Statement>();\r
622                 for (Statement s : in) {\r
623                         if (!s.isAsserted(r))\r
624                                 out.add(s);\r
625                         \r
626                 }\r
627                 return out;\r
628         }\r
629 \r
630         private String printStatement(ReadGraph graph, Statement s) throws ValidationException, ServiceException {\r
631                 return NameUtils.getSafeName(graph, s.getSubject()) + " " + NameUtils.getSafeName(graph, s.getPredicate()) + " " + NameUtils.getSafeName(graph, s.getObject());\r
632         }\r
633         \r
634         private List<Statement> filterTraversed(List<Statement> in) throws ServiceException {\r
635                 return filter(traversed, in);\r
636         }\r
637         \r
638         private List<Statement> filterNonTested(List<Statement> in) throws ServiceException {\r
639                 return filter(nonTested, in);\r
640         }\r
641         \r
642         private List<Statement> filter(Collection<Resource> toFilter, List<Statement> in) throws ServiceException {\r
643                 if (toFilter.size() == 0)\r
644                         return in;\r
645                 List<Statement> out = new ArrayList<Statement>();\r
646                 for (Statement s : in) {\r
647                         boolean usable = true;\r
648                         for (Resource r : toFilter) {\r
649                                 if (g.isSubrelationOf(s.getPredicate(),r)) {\r
650                                         usable = false;\r
651                                         break;\r
652                                 }\r
653                         }\r
654                         if (usable) {\r
655                                 out.add(s);\r
656                         }\r
657                         \r
658                 }\r
659                 return out;\r
660         }\r
661         \r
662         \r
663         private void addDeletion(Statement s) {\r
664                 if (!changes1Set.contains(s)) {\r
665                         changes1Set.add(s);\r
666                         changes1.add(s);\r
667                 }\r
668         }\r
669         \r
670         private void addAddition(Statement s) {\r
671                 if (!changes2Set.contains(s)) {\r
672                         changes2Set.add(s);\r
673                         changes2.add(s);\r
674                 }\r
675         }\r
676         \r
677         private void addModification(Statement s1, Statement s2) {\r
678                 Pair<Statement, Statement> mod = new Pair<Statement, Statement>(s1,s2);\r
679                 if (!modificationsSet.contains(mod)) {\r
680                         modificationsSet.add(mod);\r
681                         modifications.add(mod);\r
682                 }\r
683         }\r
684         \r
685         public void sortStatement(List<Statement> list1, List<Statement> list2) {\r
686                 sortStatement(list1, list2, scomp);\r
687         }\r
688         \r
689         public void sortStatement(List<Statement> list1, List<Statement> list2, Comparator<Statement> scomp) {\r
690                 Collections.sort(list1,scomp);\r
691                 Collections.sort(list2,scomp);\r
692                 \r
693                 List<Statement> sorted1 = new ArrayList<Statement>(list1.size());\r
694                 List<Statement> sorted2 = new ArrayList<Statement>(list2.size());\r
695                 sorted1.addAll(list1);\r
696                 sorted2.addAll(list2);\r
697                 \r
698                 int ss1 = 0;\r
699                 int ss2 = 0;\r
700                 for (int i = 0; i < list1.size(); ) {\r
701                         Statement s1 = list1.get(i);\r
702                         int same1 = sameRel(list1, i);  \r
703                         for (int j = 0; j < list2.size(); j++) {\r
704                                 Statement s2 = list2.get(j);\r
705                                 if (scomp.compare(s1, s2) == 0) {\r
706                                         int same2 = sameRel(list2, j);\r
707                                         copy(sorted1,ss1,list1,i,same1);\r
708                                         ss1 += same1;\r
709                                         copy(sorted2,ss2,list2,j,same2);\r
710                                         ss2 += same2;\r
711                                         break;\r
712                                 }\r
713                         }\r
714                         i+= same1;\r
715                 }\r
716                 if (ss1 < sorted1.size()) {\r
717                         for (Statement s : list1) {\r
718                                 if (!sorted1.contains(s)) {\r
719                                         sorted1.set(ss1,s);\r
720                                         ss1++;\r
721                                 }\r
722                         }\r
723                 }\r
724                 if (ss2 < sorted2.size()) {\r
725                         for (Statement s : list2) {\r
726                                 if (!sorted2.contains(s)) {\r
727                                         sorted2.set(ss2,s);\r
728                                         ss2++;\r
729                                 }\r
730                         }\r
731                 }\r
732                 \r
733                 list1.clear();\r
734                 list2.clear();\r
735                 list1.addAll(sorted1);\r
736                 list2.addAll(sorted2);\r
737         }\r
738         \r
739         public <T> void copy(List<T> to, int toIndex, List<T> from, int fromIndex, int amount) {\r
740                 for (int i = 0; i <  amount; i++) {\r
741                         to.set(toIndex + i, from.get(fromIndex+ i));\r
742                 }\r
743         }\r
744         \r
745         public void sortResource(List<Resource> list1, List<Resource> list2) {\r
746                 Collections.sort(list1,rcomp);\r
747                 int js = 0;\r
748                 for (int i = 0; i < list1.size(); i++) {\r
749                         Resource s1 = list1.get(i);\r
750                         for (int j = js; j < list2.size(); j++) {\r
751                                 Resource s2 = list2.get(j);\r
752                                 if (rcomp.compare(s1, s2) == 0) {\r
753                                         Resource t = list2.get(js);\r
754                                         list2.set(js, s2);\r
755                                         list2.set(j, t);\r
756                                         break;\r
757                                 }\r
758                         }\r
759                         js++;\r
760                 }\r
761         }\r
762         \r
763         private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Collection<Statement> unreliableLeft, Collection<Statement> unreliableRight) throws DatabaseException {\r
764                 sortStatement(ss1, ss2);\r
765                 \r
766                 int i1 = 0;\r
767                 int i2 = 0;\r
768                 \r
769                 while (true) {\r
770                         if (i1 >= ss1.size()) {\r
771                                 if (i2 >= ss2.size()) {\r
772                                         break;\r
773                                 } else {\r
774                                         while (i2 < ss2.size()) {\r
775                                                 System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
776                                                 \r
777                                                 addAddition(ss2.get(i2));\r
778                                                 i2++;\r
779                                         }\r
780                                         break;\r
781                                 }\r
782                         } else if (i2 >= ss2.size()) {\r
783                                 while (i1 < ss1.size()) {\r
784                                         System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
785                                         addDeletion(ss1.get(i1));\r
786                                         i1++;\r
787                                 }\r
788                                 break;\r
789                         }\r
790                         int same1 = sameRel(ss1, i1);\r
791                         int same2 = sameRel(ss2, i2);\r
792                         int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
793                         if (c == 0) {\r
794                                 compareStatements(ss1, i1, same1, ss2, i2, same2,objectsLeft,objectsRight,unreliableLeft,unreliableRight);\r
795                                 i1+=same1;\r
796                                 i2+=same2;\r
797                         } else if (c < 0) {\r
798                                 for (int i = 0; i < same1; i++) {\r
799                                         System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1)));\r
800                                         addDeletion(ss1.get(i+i1));\r
801                                 }\r
802                                 i1 += same1;\r
803                         } else {\r
804                                 for (int i = 0; i < same2; i++) {\r
805                                         System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2)));\r
806                                         addAddition(ss2.get(i+i2));\r
807                                 }\r
808                                 \r
809                                 i2 += same2;\r
810                         }\r
811                 }\r
812         }\r
813         \r
814 \r
815         \r
816         private int sameRel(List<Statement> statements, int off) {\r
817                 if (statements.size() <= off)\r
818                         return 0;\r
819                 int same = 1;\r
820                 long id = statements.get(off).getPredicate().getResourceId();\r
821                 for (int i = off+1; i <statements.size(); i++) {\r
822                         if (statements.get(i).getPredicate().getResourceId() == id)\r
823                                 same++;\r
824                         else \r
825                                 break;\r
826                 }\r
827                 return same;\r
828                 \r
829         }\r
830 \r
831         private int compareObject(Resource o1, Resource o2) throws DatabaseException {\r
832                 if (o1.equals(o2))\r
833                         return -1;\r
834                 if (comparableResources.contains(o1, o2))\r
835                         return (-1);\r
836                 if (comparableResources.containsLeft(o1))\r
837                         return Integer.MAX_VALUE;\r
838                 if (comparableResources.containsRight(o2))\r
839                         return Integer.MAX_VALUE;\r
840                 return comparator.compare(g, o1, o2);\r
841         }\r
842         \r
843         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
844                 boolean[] used1 = new boolean[len1];\r
845                 for (int i = 0; i < used1.length; i++) {\r
846                         used1[i] = false;\r
847                 }\r
848                 \r
849                 boolean[] used2 = new boolean[len2];\r
850                 for (int i = 0; i < used2.length; i++) {\r
851                         used2[i] = false;\r
852                 }\r
853                 \r
854                 // left, right, difference\r
855                 List<List<Integer>> differences = new ArrayList<List<Integer>>();\r
856                 for (int i1 = off1; i1 < off1 + len1; i1++) {\r
857                         Statement s1 = ss1.get(i1);\r
858                         List<Integer> diff = new ArrayList<Integer>();\r
859                         for (int i2 = off2; i2 < off2 + len2; i2++) {\r
860                                 Statement s2 = ss2.get(i2);\r
861                                 int d = compareObject(s1.getObject(), s2.getObject());\r
862                                 if (d == 0) {\r
863                                         for (Resource t : strong) {\r
864                                                  if (s1.getPredicate().equals(t) || g.isSubrelationOf(s1.getPredicate(), t)) {\r
865                                                          d = 1;\r
866                                                          break;\r
867                                                  }\r
868                                         }\r
869                                 }\r
870                                 diff.add(d);\r
871                         }\r
872                         differences.add(diff);\r
873                 }\r
874                 // difference, left\r
875                 MapList<Integer, Integer> priorities = new MapList<Integer, Integer>();\r
876                 for (int i = 0; i < differences.size(); i++) {\r
877                         List<Integer> list = differences.get(i);\r
878                         for (int j = 0; j < list.size(); j++) {\r
879                                 priorities.add(list.get(j), i);\r
880                         }\r
881                 }\r
882                 \r
883                 Integer[] pris = priorities.getKeys(new Integer[]{});\r
884                 Arrays.sort(pris);\r
885                 \r
886                 for (Integer pri : pris) {\r
887                         if (pri == Integer.MAX_VALUE) {\r
888 \r
889                         } else if (pri == 0) {\r
890                                 \r
891                         } else {\r
892                                 List<Integer> i1s = priorities.getValues(pri);\r
893                                 for (Integer i1 : i1s) {\r
894                                         if (used1[i1])\r
895                                                 continue;\r
896                                         List<Integer> i2diff = differences.get(i1);\r
897                                         for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
898                                                 if (i2diff.get(i2) == pri) {\r
899                                                         if (used2[i2])\r
900                                                                 continue;\r
901                                                         used1[i1] = true;\r
902                                                         used2[i2] = true;\r
903                                                         Statement s1  = ss1.get(i1+off1);\r
904                                                         Statement s2  = ss2.get(i2+off2);\r
905                                                         \r
906                                                         if (objectsLeft != null) {\r
907                                                                 objectsLeft.add(s1.getObject());\r
908                                                                 objectsRight.add(s2.getObject());\r
909                                                         } \r
910                                                         addComparable(s1, s2, true);\r
911                                                         break;\r
912                                                 }\r
913                                         }\r
914                                 }\r
915                         }\r
916                 }\r
917                 \r
918                 for (Integer pri : pris) {\r
919                         if (pri != 0)\r
920                                 continue;\r
921                         Set<Statement> s1s = new HashSet<Statement>();\r
922                         Set<Statement> s2s = new HashSet<Statement>();\r
923                         Set<Integer> s1i = new HashSet<Integer>();\r
924                         Set<Integer> s2i = new HashSet<Integer>();\r
925                         List<Integer> i1s = priorities.getValues(pri);\r
926                         for (Integer i1 : i1s) {\r
927                                 if (used1[i1])\r
928                                         continue;\r
929                                 List<Integer> i2diff = differences.get(i1);\r
930                                 for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
931                                         if (i2diff.get(i2) == pri) {\r
932                                                 if (used2[i2])\r
933                                                         continue;\r
934                                                 Statement s1  = ss1.get(i1+off1);\r
935                                                 Statement s2  = ss2.get(i2+off2);\r
936                                                 s1s.add(s1);\r
937                                                 s2s.add(s2);\r
938                                                 s1i.add(i1);\r
939                                                 s2i.add(i2);\r
940                                         }\r
941                                 }\r
942                         }\r
943                         if (unreliableLeft != null) {\r
944                                 unreliableLeft.addAll(s1s);\r
945                                 unreliableRight.addAll(s2s);\r
946                         }\r
947                         for (Integer i : s1i)\r
948                                 used1[i] = true;\r
949                         for (Integer i : s2i)\r
950                                 used2[i] = true;\r
951 \r
952                 }\r
953                 for (int i1 = off1; i1 < off1 + len1; i1++) {\r
954                         if (!used1[i1-off1]) {\r
955                                 System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1)));\r
956                                 addDeletion(ss1.get(i1));\r
957                         }\r
958                 }\r
959                 for (int i2 = off2; i2 < off2 + len2; i2++) {\r
960                         if (!used2[i2-off2]) {\r
961                                 System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2)));\r
962                                 addAddition(ss2.get(i2));\r
963                         }\r
964                 }\r
965         }\r
966         \r
967         \r
968         \r
969         /**\r
970          * compares properties, assumes functional relations\r
971          * @param r1\r
972          * @param r2\r
973          * @throws ServiceException\r
974          * @throws DoesNotContainValueException\r
975          * @throws ValidationException \r
976          */\r
977         private void compareProps(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
978                 ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
979                 ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
980                 ss1.addAll(g.getStatements(r1, b.HasProperty));\r
981                 ss2.addAll(g.getStatements(r2, b.HasProperty));\r
982                 sortStatement(ss1, ss2);\r
983                 \r
984                 int i1 = 0; \r
985                 int i2 = 0;\r
986                 \r
987                 while (true) {\r
988                         if (i1 >= ss1.size()) {\r
989                                 if (i2 >= ss2.size())\r
990                                         break;\r
991                                 else {\r
992                                         while (i2 < ss2.size()) {\r
993                                                 System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
994                                                 addAddition(ss2.get(i2));\r
995                                                 i2++;\r
996                                         }\r
997                                         break;\r
998                                 }\r
999                         } else if (i2 >= ss2.size()) {\r
1000                                 while (i1 < ss1.size()) {\r
1001                                         System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
1002                                         addDeletion(ss1.get(i1));\r
1003                                         i1++;\r
1004                                 }\r
1005                                 break;\r
1006                         }\r
1007                         Statement s1 = ss1.get(i1);\r
1008                         Statement s2 = ss2.get(i2);\r
1009                         int c = scomp.compare(s1, s2);\r
1010                         switch (c) {\r
1011                                 case 0:{\r
1012                                         boolean b1 = g.hasValue(s1.getObject());\r
1013                                         boolean b2 = g.hasValue(s2.getObject());\r
1014                                         if (b1 == b2) {\r
1015                                                 if (b1) {\r
1016                                                         Object v1 = g.getValue(s1.getObject());\r
1017                                                         Object v2 = g.getValue(s2.getObject());\r
1018                                                         boolean eq = compareValue(v1, v2);\r
1019                                                         if (!eq) {\r
1020                                                                 addModification(s1, s2);\r
1021                                                                 addComparable(s1, s2, false);\r
1022                                                         }\r
1023                                                 } else {\r
1024                                                         compareProps(s1.getObject(), s2.getObject());\r
1025                                                 }\r
1026                                         } else {\r
1027                                                 addModification(s1, s2);\r
1028                                                 addComparable(s1, s2, false);\r
1029                                         }\r
1030                                         i1++;\r
1031                                         i2++;\r
1032                                         break;\r
1033                                 }\r
1034                                 case -1:{\r
1035                                         System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
1036                                         addDeletion(s1);\r
1037                                         i1++;\r
1038                                         break;\r
1039                                 }\r
1040                                         \r
1041                                 case 1:{\r
1042                                         System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
1043                                         addAddition(s2);\r
1044                                         i2++;\r
1045                                         break;\r
1046                                 }\r
1047                         }\r
1048 \r
1049                 }\r
1050                 \r
1051                 ss1.clear();\r
1052                 ss2.clear();\r
1053                 \r
1054         }\r
1055         \r
1056         public static boolean compareValue(Object v1, Object v2) {\r
1057                 if (v1 instanceof Object[] && v2 instanceof Object[])\r
1058                         return Arrays.deepEquals((Object[])v1, (Object[])v2);\r
1059                 else if (v1 instanceof int[] && v2 instanceof int[]) \r
1060                         return Arrays.equals((int[])v1, (int[])v2);\r
1061                 else if (v1 instanceof float[] && v2 instanceof float[]) \r
1062                         return Arrays.equals((float[])v1, (float[])v2);\r
1063                 else if (v1 instanceof double[] && v2 instanceof double[]) \r
1064                         return Arrays.equals((double[])v1, (double[])v2);\r
1065                 else if (v1 instanceof long[] && v2 instanceof long[]) \r
1066                         return  Arrays.equals((long[])v1, (long[])v2);\r
1067                 else if (v1 instanceof byte[] && v2 instanceof byte[]) \r
1068                         return Arrays.equals((byte[])v1, (byte[])v2);\r
1069                 else if (v1 instanceof boolean[] && v2 instanceof boolean[]) \r
1070                         return Arrays.equals((boolean[])v1, (boolean[])v2);\r
1071                 else\r
1072                         return v1.equals(v2);\r
1073         }\r
1074 \r
1075         \r
1076         public class PredicateComparator implements Comparator<Statement> {\r
1077                 @Override\r
1078                 public int compare(Statement o1, Statement o2) {\r
1079                         if (comparableResources.contains(o1.getPredicate(), o2.getPredicate()))\r
1080                                 return 0;\r
1081                         if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
1082                                 return -1;\r
1083                         if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
1084                                 return 1;\r
1085                         return 0;\r
1086                 }\r
1087         }\r
1088         \r
1089         public class SubjectComparator implements Comparator<Statement> {\r
1090                 @Override\r
1091                 public int compare(Statement o1, Statement o2) {\r
1092                         if (comparableResources.contains(o1.getSubject(), o2.getSubject()))\r
1093                                 return 0;\r
1094                         if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
1095                                 return -1;\r
1096                         if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
1097                                 return 1;\r
1098                         return 0;\r
1099                 }\r
1100         }\r
1101         \r
1102         public class ObjectComparator implements Comparator<Statement> {\r
1103                 @Override\r
1104                 public int compare(Statement o1, Statement o2) {\r
1105                         if (comparableResources.contains(o1.getObject(), o2.getObject()))\r
1106                                 return 0;\r
1107                         if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
1108                                 return -1;\r
1109                         if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
1110                                 return 1;\r
1111                         return 0;\r
1112                 }\r
1113         }\r
1114         \r
1115         public static class FullStatementComparator implements Comparator<Statement> {\r
1116                 @Override\r
1117                 public int compare(Statement o1, Statement o2) {\r
1118                         if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
1119                                 return -1;\r
1120                         if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
1121                                 return 1;\r
1122                         if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
1123                                 return -1;\r
1124                         if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
1125                                 return 1;\r
1126                         if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
1127                                 return -1;\r
1128                         if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
1129                                 return 1;\r
1130                         return 0;\r
1131                 }\r
1132         }\r
1133         \r
1134         public class ResComparator implements Comparator<Resource> {\r
1135                 @Override\r
1136                 public int compare(Resource o1, Resource o2) {\r
1137                         if (comparableResources.contains(o1, o2))\r
1138                                 return 0;\r
1139                         if (o1.getResourceId() < o2.getResourceId())\r
1140                                 return -1;\r
1141                         if (o1.getResourceId() > o2.getResourceId())\r
1142                                 return 1;\r
1143                         return 0;\r
1144                 }\r
1145         }\r
1146 \r
1147 }\r