Functional PathPattern comparator

master
Rossen Stoyanchev 7 years ago
parent ef175d7ca6
commit 8c4b1ab781
  1. 58
      spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java
  2. 8
      spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java

@ -692,44 +692,22 @@ public class PathPattern implements Comparable<PathPattern> {
} }
public static final Comparator<PathPattern> SPECIFICITY_COMPARATOR = (p1, p2) -> { /**
// Same object or null == null? * Comparator that sorts patterns by specificity as follows:
if (p1 == p2) { * <ol>
return 0; * <li>Null instances are last.
} * <li>Catch-all patterns are last.
* <li>If both patterns are catch-all, consider the length (longer wins).
// null is sorted last * <li>Compare wildcard and captured variable count (lower wins).
if (p2 == null) { * <li>Consider length (longer wins)
return -1; * </ol>
} */
public static final Comparator<PathPattern> SPECIFICITY_COMPARATOR =
// catchall patterns are sorted last. If both catchall then the Comparator.nullsLast(
// length is considered Comparator.<PathPattern>
if (p1.isCatchAll()) { comparingInt(p -> p.isCatchAll() ? 1 : 0)
if (p2.isCatchAll()) { .thenComparingInt(p -> p.isCatchAll() ? -1 * p.getNormalizedLength() : 0)
int lenDifference = p1.getNormalizedLength() - p2.getNormalizedLength(); .thenComparing(PathPattern::getScore)
if (lenDifference != 0) { .thenComparingInt(p -> -1 * p.getNormalizedLength())
return (lenDifference < 0) ? +1 : -1; );
}
}
else {
return +1;
}
}
else if (p2.isCatchAll()) {
return -1;
}
// 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
int score = p1.getScore() - p2.getScore();
if (score != 0) {
return (score < 0) ? -1 : +1;
}
// longer is better
int lenDifference = p1.getNormalizedLength() - p2.getNormalizedLength();
return Integer.compare(0, lenDifference);
};
} }

@ -967,10 +967,10 @@ public class PathPatternTests {
} }
@Test @Test
public void patternCompareToNull() { public void patternCompareWithNull() {
PathPatternParser p = new PathPatternParser(); assertTrue(PathPattern.SPECIFICITY_COMPARATOR.compare(null, null) == 0);
PathPattern pp = p.parse("/abc"); assertTrue(PathPattern.SPECIFICITY_COMPARATOR.compare(parse("/abc"), null) < 0);
assertEquals(-1, pp.compareTo(null)); assertTrue(PathPattern.SPECIFICITY_COMPARATOR.compare(null, parse("/abc")) > 0);
} }
@Test @Test

Loading…
Cancel
Save