Proper null handling in PathPattern comparator
This commit is contained in:
parent
adeb521ce4
commit
631b546d1c
|
|
@ -693,12 +693,17 @@ public class PathPattern implements Comparable<PathPattern> {
|
||||||
|
|
||||||
|
|
||||||
public static final Comparator<PathPattern> SPECIFICITY_COMPARATOR = (p1, p2) -> {
|
public static final Comparator<PathPattern> SPECIFICITY_COMPARATOR = (p1, p2) -> {
|
||||||
// 1) null is sorted last
|
// Same object or null == null?
|
||||||
|
if (p1 == p2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// null is sorted last
|
||||||
if (p2 == null) {
|
if (p2 == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2) catchall patterns are sorted last. If both catchall then the
|
// catchall patterns are sorted last. If both catchall then the
|
||||||
// length is considered
|
// length is considered
|
||||||
if (p1.isCatchAll()) {
|
if (p1.isCatchAll()) {
|
||||||
if (p2.isCatchAll()) {
|
if (p2.isCatchAll()) {
|
||||||
|
|
@ -715,14 +720,14 @@ public class PathPattern implements Comparable<PathPattern> {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) This will sort such that if they differ in terms of wildcards or
|
// This will sort such that if they differ in terms of wildcards or
|
||||||
// captured variable counts, the one with the most will be sorted last
|
// captured variable counts, the one with the most will be sorted last
|
||||||
int score = p1.getScore() - p2.getScore();
|
int score = p1.getScore() - p2.getScore();
|
||||||
if (score != 0) {
|
if (score != 0) {
|
||||||
return (score < 0) ? -1 : +1;
|
return (score < 0) ? -1 : +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) longer is better
|
// longer is better
|
||||||
int lenDifference = p1.getNormalizedLength() - p2.getNormalizedLength();
|
int lenDifference = p1.getNormalizedLength() - p2.getNormalizedLength();
|
||||||
return Integer.compare(0, lenDifference);
|
return Integer.compare(0, lenDifference);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -886,10 +886,7 @@ public class PathPatternTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void patternComparator() {
|
public void patternComparator() {
|
||||||
Comparator<PathPattern> comparator = (p1, p2) -> {
|
Comparator<PathPattern> comparator = PathPattern.SPECIFICITY_COMPARATOR;
|
||||||
int index = p1.compareTo(p2);
|
|
||||||
return (index != 0 ? index : p1.getPatternString().compareTo(p2.getPatternString()));
|
|
||||||
};
|
|
||||||
|
|
||||||
assertEquals(0, comparator.compare(parse("/hotels/new"), parse("/hotels/new")));
|
assertEquals(0, comparator.compare(parse("/hotels/new"), parse("/hotels/new")));
|
||||||
|
|
||||||
|
|
@ -970,7 +967,7 @@ public class PathPatternTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void patternCompareTo() {
|
public void patternCompareToNull() {
|
||||||
PathPatternParser p = new PathPatternParser();
|
PathPatternParser p = new PathPatternParser();
|
||||||
PathPattern pp = p.parse("/abc");
|
PathPattern pp = p.parse("/abc");
|
||||||
assertEquals(-1, pp.compareTo(null));
|
assertEquals(-1, pp.compareTo(null));
|
||||||
|
|
@ -978,58 +975,62 @@ public class PathPatternTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void patternComparatorSort() {
|
public void patternComparatorSort() {
|
||||||
Comparator<PathPattern> comparator = (p1, p2) -> {
|
Comparator<PathPattern> comparator = PathPattern.SPECIFICITY_COMPARATOR;
|
||||||
int index = p1.compareTo(p2);
|
|
||||||
return (index != 0 ? index : p1.getPatternString().compareTo(p2.getPatternString()));
|
|
||||||
};
|
|
||||||
|
|
||||||
List<PathPattern> paths = new ArrayList<>(3);
|
List<PathPattern> paths = new ArrayList<>(3);
|
||||||
PathPatternParser pp = new PathPatternParser();
|
PathPatternParser pp = new PathPatternParser();
|
||||||
|
paths.add(null);
|
||||||
|
paths.add(null);
|
||||||
|
paths.sort(comparator);
|
||||||
|
assertNull(paths.get(0));
|
||||||
|
assertNull(paths.get(1));
|
||||||
|
paths.clear();
|
||||||
|
|
||||||
paths.add(null);
|
paths.add(null);
|
||||||
paths.add(pp.parse("/hotels/new"));
|
paths.add(pp.parse("/hotels/new"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
||||||
assertNull(paths.get(1));
|
assertNull(paths.get(1));
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
||||||
paths.add(pp.parse("/hotels/*"));
|
paths.add(pp.parse("/hotels/*"));
|
||||||
paths.add(pp.parse("/hotels/new"));
|
paths.add(pp.parse("/hotels/new"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/*", paths.get(1).getPatternString());
|
assertEquals("/hotels/*", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
||||||
paths.add(pp.parse("/hotels/new"));
|
paths.add(pp.parse("/hotels/new"));
|
||||||
paths.add(pp.parse("/hotels/*"));
|
paths.add(pp.parse("/hotels/*"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/*", paths.get(1).getPatternString());
|
assertEquals("/hotels/*", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
||||||
paths.add(pp.parse("/hotels/**"));
|
paths.add(pp.parse("/hotels/**"));
|
||||||
paths.add(pp.parse("/hotels/*"));
|
paths.add(pp.parse("/hotels/*"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/*", paths.get(0).getPatternString());
|
assertEquals("/hotels/*", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/**", paths.get(1).getPatternString());
|
assertEquals("/hotels/**", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
||||||
paths.add(pp.parse("/hotels/*"));
|
paths.add(pp.parse("/hotels/*"));
|
||||||
paths.add(pp.parse("/hotels/**"));
|
paths.add(pp.parse("/hotels/**"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/*", paths.get(0).getPatternString());
|
assertEquals("/hotels/*", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/**", paths.get(1).getPatternString());
|
assertEquals("/hotels/**", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
||||||
paths.add(pp.parse("/hotels/{hotel}"));
|
paths.add(pp.parse("/hotels/{hotel}"));
|
||||||
paths.add(pp.parse("/hotels/new"));
|
paths.add(pp.parse("/hotels/new"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/{hotel}", paths.get(1).getPatternString());
|
assertEquals("/hotels/{hotel}", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
||||||
paths.add(pp.parse("/hotels/new"));
|
paths.add(pp.parse("/hotels/new"));
|
||||||
paths.add(pp.parse("/hotels/{hotel}"));
|
paths.add(pp.parse("/hotels/{hotel}"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/{hotel}", paths.get(1).getPatternString());
|
assertEquals("/hotels/{hotel}", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
@ -1037,7 +1038,7 @@ public class PathPatternTests {
|
||||||
paths.add(pp.parse("/hotels/*"));
|
paths.add(pp.parse("/hotels/*"));
|
||||||
paths.add(pp.parse("/hotels/{hotel}"));
|
paths.add(pp.parse("/hotels/{hotel}"));
|
||||||
paths.add(pp.parse("/hotels/new"));
|
paths.add(pp.parse("/hotels/new"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
assertEquals("/hotels/new", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/{hotel}", paths.get(1).getPatternString());
|
assertEquals("/hotels/{hotel}", paths.get(1).getPatternString());
|
||||||
assertEquals("/hotels/*", paths.get(2).getPatternString());
|
assertEquals("/hotels/*", paths.get(2).getPatternString());
|
||||||
|
|
@ -1046,7 +1047,7 @@ public class PathPatternTests {
|
||||||
paths.add(pp.parse("/hotels/ne*"));
|
paths.add(pp.parse("/hotels/ne*"));
|
||||||
paths.add(pp.parse("/hotels/n*"));
|
paths.add(pp.parse("/hotels/n*"));
|
||||||
Collections.shuffle(paths);
|
Collections.shuffle(paths);
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/hotels/ne*", paths.get(0).getPatternString());
|
assertEquals("/hotels/ne*", paths.get(0).getPatternString());
|
||||||
assertEquals("/hotels/n*", paths.get(1).getPatternString());
|
assertEquals("/hotels/n*", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
@ -1066,7 +1067,7 @@ public class PathPatternTests {
|
||||||
};
|
};
|
||||||
paths.add(pp.parse("/*/login.*"));
|
paths.add(pp.parse("/*/login.*"));
|
||||||
paths.add(pp.parse("/*/endUser/action/login.*"));
|
paths.add(pp.parse("/*/endUser/action/login.*"));
|
||||||
Collections.sort(paths, comparator);
|
paths.sort(comparator);
|
||||||
assertEquals("/*/endUser/action/login.*", paths.get(0).getPatternString());
|
assertEquals("/*/endUser/action/login.*", paths.get(0).getPatternString());
|
||||||
assertEquals("/*/login.*", paths.get(1).getPatternString());
|
assertEquals("/*/login.*", paths.get(1).getPatternString());
|
||||||
paths.clear();
|
paths.clear();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue