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