\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
import org.simantics.db.Statement;\r
+import org.simantics.db.common.request.ReadRequest;\r
import org.simantics.db.common.utils.NameUtils;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.exception.DoesNotContainValueException;\r
*\r
*/\r
public class GraphComparator {\r
+ \r
+ private static final boolean DEBUG = false;\r
\r
private Resource r1;\r
private Resource r2;\r
\r
private BijectionMap<Statement, Statement> comparableStatements = new BijectionMap<Statement, Statement>();\r
private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();\r
- \r
+ private Set<Resource> processedResources = new HashSet<Resource>();\r
\r
private ResourceComparator comparator;\r
\r
strong.add(r);\r
}\r
\r
- public void clearRels() {\r
- traversed.clear();\r
- tested.clear();\r
- nonTraversed.clear();\r
- nonTested.clear();\r
+ public void addStrong(Collection<Resource> rels) {\r
+ strong.addAll(rels);\r
}\r
\r
+ \r
public void test(ReadGraph g) throws DatabaseException {\r
this.g = g;\r
this.b = Layer0.getInstance(g);\r
objectsLeft.push(r1);\r
objectsRight.push(r2);\r
\r
- \r
- \r
- \r
Set<Statement> unreliableLeft = new HashSet<Statement>();\r
Set<Statement> unreliableRight = new HashSet<Statement>();\r
\r
if (objectsLeft.isEmpty())\r
break;\r
\r
+ \r
// process compares objects that are identified and searches for more resources to process. \r
process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);\r
+ // process unreliable handles cases where unidentified statements subject and object have been identified \r
+ processUnreliable(unreliableLeft, unreliableRight);\r
// process unreliable handles cases where unidentified resources have path of length one to identified resource\r
processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);\r
if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {\r
}\r
\r
\r
+ }\r
+ \r
+ public void test(Session session) throws DatabaseException {\r
+ \r
+ comparator.setComparator(this);\r
+ \r
+ comparableResources.map(r1, r2);\r
+ \r
+ final Stack<Resource> objectsLeft = new Stack<Resource>();\r
+ final Stack<Resource> objectsRight = new Stack<Resource>();\r
+ objectsLeft.push(r1);\r
+ objectsRight.push(r2);\r
+ \r
+ final Set<Statement> unreliableLeft = new HashSet<Statement>();\r
+ final Set<Statement> unreliableRight = new HashSet<Statement>();\r
+ \r
+ while (true) {\r
+ if (objectsLeft.isEmpty())\r
+ break;\r
+ session.syncRequest(new ReadRequest() {\r
+ \r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ g = graph;\r
+ b = Layer0.getInstance(graph);\r
+ // process compares objects that are identified and searches for more resources to process. \r
+ process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);\r
+ // process unreliable handles cases where unidentified statements subject and object have been identified \r
+ processUnreliable(unreliableLeft, unreliableRight);\r
+ // process unreliable handles cases where unidentified resources have path of length one to identified resource\r
+ processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);\r
+ if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {\r
+ // comparison is ending, but we have still unprocessed unidentified resources left.\r
+ // These cases have longer path than one to identified objects.\r
+ processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);\r
+ }\r
+ }\r
+ });\r
+ \r
+ \r
+ \r
+ }\r
+ for (Statement s : unreliableLeft) {\r
+ if (!comparableStatements.containsLeft(s))\r
+ addDeletion(s);\r
+ }\r
+ for (Statement s : unreliableRight) {\r
+ if (!comparableStatements.containsRight(s))\r
+ addAddition(s);\r
+ }\r
+ \r
+ \r
}\r
\r
private void process(Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {\r
while (!objectsLeft.isEmpty()) {\r
Resource r1 = objectsLeft.pop();\r
Resource r2 = objectsRight.pop();\r
- \r
- if (comparableResources.contains(r1, r2)) {\r
- //System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
+ \r
+ if (r1.equals(r2))\r
continue;\r
+ \r
+ if (processedResources.contains(r1))\r
+ continue;\r
+ processedResources.add(r1);\r
+ \r
+ \r
+ if(!comparableResources.contains(r1, r2) && (comparableResources.containsLeft(r1)||comparableResources.containsRight(r2))) {\r
+ 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
}\r
- comparableResources.map(r1, r2);\r
\r
//System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
compareProps(r1, r2);\r
}\r
}\r
}\r
- private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) {\r
+ \r
+ private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {\r
+ MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
+ MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
+ MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
+ MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
+ \r
+ for (Statement s : unreliableLeft) {\r
+ subjectLeft.add(s.getSubject(),s);\r
+ objectLeft.add(s.getObject(),s);\r
+ }\r
+ for (Statement s : unreliableRight) {\r
+ subjectRight.add(s.getSubject(),s);\r
+ objectRight.add(s.getObject(),s);\r
+ }\r
+ \r
+ for (Resource left : subjectLeft.getKeys()) {\r
+ if (!comparableResources.containsLeft(left))\r
+ continue;\r
+ Resource right = comparableResources.getRight(left);\r
+ for (Statement leftS : subjectLeft.getValues(left)) {\r
+ Resource leftO = leftS.getObject();\r
+ if (!comparableResources.containsLeft(leftO)) \r
+ continue;\r
+ if (!unreliableLeft.contains(leftS))\r
+ continue;\r
+ Resource rightO = comparableResources.getRight(leftO);\r
+ for (Statement rightS : subjectRight.getValues(right)) {\r
+ if (!rightS.getObject().equals(rightO))\r
+ continue;\r
+ if (!unreliableRight.contains(rightS))\r
+ continue;\r
+ if (leftS.getPredicate().equals(rightS.getPredicate()) ||\r
+ comparableResources.contains(leftS.getPredicate(), rightS.getPredicate())) {\r
+ unreliableLeft.remove(leftS);\r
+ unreliableRight.remove(rightS);\r
+ addComparable(leftS, rightS, false);\r
+ }\r
+ }\r
+ }\r
+ \r
+ }\r
+ }\r
+ \r
+ private void processUnreliable(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws DatabaseException {\r
MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
}\r
\r
for (Resource ol : objectLeft.getKeys()) {\r
-\r
// all statements to the left side object\r
List<Statement> left = objectLeft.getValues(ol);\r
// all subjects that have statements to the left side object (ol)\r
sLeft.add(s.getSubject());\r
sRight.add(comparableResources.getRight(s.getSubject()));\r
}\r
+ \r
+ // check if object left can be reliably identified by available statements\r
+ // if there are any objects on the left side with similar statements, object left cannot be mapped.\r
+ boolean hasSimilar = false;\r
+ MapList<Resource, Statement> comparableOLeft = new MapList<Resource, Statement>();\r
+ for (Resource sl : sLeft) {\r
+ for (Statement s : subjectLeft.getValues(sl)) {\r
+ if (!s.getObject().equals(ol)) {\r
+ comparableOLeft.add(s.getObject(),s);\r
+ }\r
+ }\r
+ }\r
+ \r
+ for (Resource similarOl : comparableOLeft.getKeys()) {\r
+ List<Statement> similarLeft = comparableOLeft.getValues(similarOl);\r
+ if (similarLeft.size() == left.size()) {\r
+ boolean useL[] = new boolean[left.size()];\r
+ boolean useSL[] = new boolean[left.size()];\r
+ for (int i = 0; i < left.size(); i++) {\r
+ useL[i] = false;\r
+ useSL[i] = false;\r
+ }\r
+ for (int i = 0; i < left.size(); i++) {\r
+ for (int j = 0; j < left.size(); j++) {\r
+ if (useSL[j])\r
+ continue;\r
+ Resource pl = left.get(i).getPredicate();\r
+ Resource psl = similarLeft.get(j).getPredicate();\r
+ if (pl.equals(psl)) {\r
+ useL[i] = true;\r
+ useSL[j] = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ boolean diff = false;\r
+ for (int i = 0; i < left.size(); i++) {\r
+ if (!useL[i] || !useSL[i]) {\r
+ diff = true;\r
+ }\r
+ }\r
+ if (!diff) {\r
+ hasSimilar = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ \r
+ if (hasSimilar)\r
+ continue;\r
+ \r
+ \r
// all objects that subjects on the right side point to. Object left has its matching resource among these, if it has matching resource\r
MapList<Resource,Statement> possibleOR = new MapList<Resource, Statement>();\r
for (Resource sr : sRight) {\r
List<Statement> right = matchingOR.getValues(or);\r
Pair<int[], int[]> indices = matchingStatements.get(or);\r
\r
- //comparableResources.map(ol, or);\r
objectsLeft.add(ol);\r
objectsRight.add(or);\r
+ addComparable(ol, or, false);\r
for (int l = 0; l < left.size(); l++) {\r
int r = indices.first[l];\r
- comparableStatements.map(left.get(l), right.get(r));\r
- unreliableLeft.remove(left.get(l));\r
- unreliableRight.remove(right.get(r));\r
+ Statement sl = left.get(l);\r
+ Statement sr = right.get(r);\r
+ addComparable(sl, sr, true);\r
+ unreliableLeft.remove(sl);\r
+ unreliableRight.remove(sr);\r
}\r
\r
}\r
\r
}\r
\r
- private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+ private void processUnreliableDeep(Set<Statement> unreliableLeft, Set<Statement> unreliableRight, Stack<Resource> objectsLeft, Stack<Resource> objectsRight) throws DatabaseException {\r
MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
for (Path leftPath : pathsLeft) {\r
possiblePathsRight.addAll(findComparableRight(leftPath, or));\r
}\r
- if (possiblePathsRight.size() == pathsLeft.size()) {\r
+ if (hasMatchingPaths(pathsLeft, possiblePathsRight)) {\r
matchingPaths.put(or, possiblePathsRight);\r
}\r
}\r
if (matchingPaths.size() > 0) {\r
if (matchingPaths.size() == 1) {\r
Resource or = matchingPaths.keySet().iterator().next();\r
+ \r
objectsLeft.add(ol);\r
objectsRight.add(or);\r
+ addComparable(ol, or, false);\r
Collection<Statement> statementsLeft = objectLeft.getValues(ol);\r
Collection<Statement> statementsRight = objectRight.getValues(or);\r
unreliableLeft.removeAll(statementsLeft);\r
unreliableRight.removeAll(statementsRight);\r
- System.out.println();\r
- } else {\r
- System.out.println();\r
- }\r
+ BijectionMap<Path,Path> map = getMatchingPaths(pathsLeft, matchingPaths.get(or));\r
+ for (Path left : map.getLeftSet()) {\r
+ Path right = map.getRight(left);\r
+ for (int i = 0; i < left.getLength(); i++) {\r
+ addComparable(left.getStatements().get(i),right.getStatements().get(i),false);\r
+ }\r
+ }\r
+ } \r
}\r
}\r
\r
\r
}\r
\r
+ private boolean hasMatchingPaths(Set<Path> leftPaths, Set<Path> rightPaths) {\r
+ if (leftPaths.size() != rightPaths.size())\r
+ return false;\r
+ BijectionMap<Path,Path> map = getMatchingPaths(leftPaths, rightPaths);\r
+ return map.size() == leftPaths.size();\r
+ \r
+ }\r
+ \r
+ private BijectionMap<Path,Path> getMatchingPaths(Set<Path> leftPaths, Set<Path> rightPaths) {\r
+ BijectionMap<Path,Path> map = new BijectionMap<Path, Path>();\r
+ for (Path leftPath : leftPaths) {\r
+ for (Path rightPath : rightPaths) {\r
+ if (map.containsRight(rightPath))\r
+ continue;\r
+ if (leftPath.getLength() != rightPath.getLength())\r
+ continue;\r
+ if (comparableResources.contains(leftPath.getEnd(), rightPath.getEnd())) {\r
+ map.map(leftPath, rightPath);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return map;\r
+ }\r
+ \r
private void expand(Set<Path> paths) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
Set<Path> stepPathsLeft = new HashSet<Path>();\r
if (paths.size() == 0)\r
return new GraphChanges(r1,r2,changes1,changes2,modifications,comparableResources);\r
}\r
\r
- private List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
+ private void addComparable(Statement left, Statement right, boolean process) throws DatabaseException {\r
+ addComparable(left.getObject(), right.getObject(), process);\r
+ comparableStatements.map(left, right);\r
+ comparableResources.map(left.getObject(), right.getObject());\r
+ }\r
+ \r
+ private void addComparable(Resource left, Resource right, boolean process) throws DatabaseException {\r
+ if(!comparableResources.contains(r1, r2)) {\r
+ if (comparableResources.containsLeft(r1)||comparableResources.containsRight(r2)) {\r
+ 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
+ } else {\r
+ comparableResources.map(left, right); \r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
+ public List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws ServiceException {\r
List<Statement> out = new ArrayList<Statement>();\r
for (Statement s : in) {\r
if (!s.isAsserted(r))\r
}\r
return out;\r
}\r
- \r
+\r
private String printStatement(ReadGraph graph, Statement s) throws ValidationException, ServiceException {\r
return NameUtils.getSafeName(graph, s.getSubject()) + " " + NameUtils.getSafeName(graph, s.getPredicate()) + " " + NameUtils.getSafeName(graph, s.getObject());\r
}\r
}\r
}\r
js++;\r
- \r
}\r
}\r
\r
break;\r
} else {\r
while (i2 < ss2.size()) {\r
- System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
+ if (DEBUG) System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
\r
addAddition(ss2.get(i2));\r
i2++;\r
}\r
} else if (i2 >= ss2.size()) {\r
while (i1 < ss1.size()) {\r
- System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
+ if (DEBUG) System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
addDeletion(ss1.get(i1));\r
i1++;\r
}\r
i2+=same2;\r
} else if (c < 0) {\r
for (int i = 0; i < same1; i++) {\r
- System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1)));\r
+ if (DEBUG) System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1)));\r
addDeletion(ss1.get(i+i1));\r
}\r
i1 += same1;\r
} else {\r
for (int i = 0; i < same2; i++) {\r
- System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2)));\r
+ if (DEBUG) System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2)));\r
addAddition(ss2.get(i+i2));\r
}\r
\r
i2 += same2;\r
}\r
- \r
}\r
}\r
\r
}\r
\r
private int compareObject(Resource o1, Resource o2) throws DatabaseException {\r
+ if (o1.equals(o2))\r
+ return -1;\r
if (comparableResources.contains(o1, o2))\r
return (-1);\r
if (comparableResources.containsLeft(o1))\r
Statement s2 = ss2.get(i2+off2);\r
\r
if (objectsLeft != null) {\r
- \r
- objectsLeft.add(s1.getObject());\r
- objectsRight.add(s2.getObject());\r
- \r
+ objectsLeft.add(s1.getObject());\r
+ objectsRight.add(s2.getObject());\r
} \r
- comparableStatements.map(s1, s2);\r
- //comparableResources.map(s1.getObject(), s2.getObject());\r
+ addComparable(s1, s2, true);\r
break;\r
}\r
}\r
}\r
for (int i1 = off1; i1 < off1 + len1; i1++) {\r
if (!used1[i1-off1]) {\r
- System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1)));\r
+ if (DEBUG) System.out.println("Compare Object diff1 " + printStatement(g,ss1.get(i1)));\r
addDeletion(ss1.get(i1));\r
}\r
}\r
for (int i2 = off2; i2 < off2 + len2; i2++) {\r
if (!used2[i2-off2]) {\r
- System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2)));\r
+ if (DEBUG) System.out.println("Compare Object diff2 " + printStatement(g,ss2.get(i2)));\r
addAddition(ss2.get(i2));\r
}\r
}\r
* @throws DoesNotContainValueException\r
* @throws ValidationException \r
*/\r
- private void compareProps(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+ private void compareProps(Resource r1, Resource r2) throws DatabaseException {\r
+ if (DEBUG) System.out.println("compareProps " + r1 + " " + NameUtils.getSafeName(g, r1) + " " + r2 + " " + NameUtils.getSafeName(g, r2));\r
ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
ss1.addAll(g.getStatements(r1, b.HasProperty));\r
ss2.addAll(g.getStatements(r2, b.HasProperty));\r
sortStatement(ss1, ss2);\r
-// Collections.sort(ss1, scomp);\r
-// Collections.sort(ss2, scomp);\r
\r
int i1 = 0; \r
int i2 = 0;\r
break;\r
else {\r
while (i2 < ss2.size()) {\r
- System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
+ if (DEBUG) System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2)));\r
addAddition(ss2.get(i2));\r
i2++;\r
}\r
}\r
} else if (i2 >= ss2.size()) {\r
while (i1 < ss1.size()) {\r
- System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
+ if (DEBUG) System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1)));\r
addDeletion(ss1.get(i1));\r
i1++;\r
}\r
}\r
Statement s1 = ss1.get(i1);\r
Statement s2 = ss2.get(i2);\r
+ if (s1.isAsserted(r1) && s2.isAsserted(r2)) {\r
+ i1++;\r
+ i2++;\r
+ continue;\r
+ }\r
int c = scomp.compare(s1, s2);\r
switch (c) {\r
- case 0:{\r
- boolean b1 = g.hasValue(s1.getObject());\r
- boolean b2 = g.hasValue(s2.getObject());\r
- if (b1 == b2) {\r
- if (b1) {\r
- Object v1 = g.getValue(s1.getObject());\r
- Object v2 = g.getValue(s2.getObject());\r
- boolean eq = compareValue(v1, v2);\r
- if (!eq) {\r
- addModification(s1, s2);\r
- comparableStatements.map(s1, s2);\r
- comparableResources.map(s1.getObject(),s2.getObject());\r
+ case 0:{\r
+ boolean b1 = g.hasValue(s1.getObject());\r
+ boolean b2 = g.hasValue(s2.getObject());\r
+ if (b1 == b2) {\r
+ if (b1) {\r
+ Object v1 = g.getValue(s1.getObject());\r
+ Object v2 = g.getValue(s2.getObject());\r
+ boolean eq = compareValue(v1, v2);\r
+ if (!eq) {\r
+ addModification(s1, s2);\r
+ addComparable(s1, s2, false);\r
+ }\r
+ } else {\r
+ if (!s1.getObject().equals(s1.getSubject()) && !s2.getObject().equals(s2.getSubject()))\r
+ compareProps(s1.getObject(), s2.getObject());\r
}\r
} else {\r
- compareProps(s1.getObject(), s2.getObject());\r
+ addModification(s1, s2);\r
+ addComparable(s1, s2, false);\r
}\r
- } else {\r
- addModification(s1, s2);\r
- comparableStatements.map(s1, s2);\r
- comparableResources.map(s1.getObject(),s2.getObject());\r
+ i1++;\r
+ i2++;\r
+ break;\r
+ }\r
+ case -1:{\r
+ if (DEBUG) System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
+ addDeletion(s1);\r
+ i1++;\r
+ break;\r
+ }\r
+ \r
+ case 1:{\r
+ if (DEBUG) System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
+ addAddition(s2);\r
+ i2++;\r
+ break;\r
}\r
- i1++;\r
- i2++;\r
- break;\r
- }\r
- case -1:{\r
- System.out.println("Compare Prop diff1s " + printStatement(g,s1));\r
- addDeletion(s1);\r
- i1++;\r
- break;\r
- }\r
- \r
- case 1:{\r
- System.out.println("Compare Prop diff2s " + printStatement(g,s2));\r
- addAddition(s2);\r
- i2++;\r
- break;\r
- }\r
}\r
- \r
- \r
+\r
}\r
\r
ss1.clear();\r
\r
}\r
\r
- \r
public static boolean compareValue(Object v1, Object v2) {\r
if (v1 instanceof Object[] && v2 instanceof Object[])\r
return Arrays.deepEquals((Object[])v1, (Object[])v2);\r
}\r
\r
\r
- \r
public class PredicateComparator implements Comparator<Statement> {\r
@Override\r
public int compare(Statement o1, Statement o2) {\r
}\r
}\r
\r
-\r
- \r
public class ResComparator implements Comparator<Resource> {\r
@Override\r
public int compare(Resource o1, Resource o2) {\r
return 0;\r
}\r
}\r
- \r
- \r
+\r
}\r