Fix "**" precedence in AntPathMatcher comparator

Prior to this commit, "**" and "*" pattern elements had
the same priority when comparing two patterns.
So when comparing several patterns, the computed order was:
1- /hotels/{hotel}/bookings/{booking}
2- /hotels/**
3- /hotels/{hotel}/bookings/{booking}/customer/{customer}

This commit updates the comparator so that patterns ending
with "**" (a.k.a "catch-all" patterns) are less specific than
the others; in the previous example, the 2nd pattern would
then end up last.

This commit also optimizes the comparator implementation.

Issue: SPR-6741
This commit is contained in:
Brian Clozel
2014-01-31 15:47:11 +01:00
parent 80a16c6d10
commit f829cd1b35
2 changed files with 89 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -447,11 +447,22 @@ public class AntPathMatcherTests {
assertEquals(-1, comparator.compare("/hotels/{hotel}", "/hotels/*"));
assertEquals(1, comparator.compare("/hotels/*", "/hotels/{hotel}"));
assertEquals(-2, comparator.compare("/hotels/*", "/hotels/*/**"));
assertEquals(2, comparator.compare("/hotels/*/**", "/hotels/*"));
assertEquals(-1, comparator.compare("/hotels/*", "/hotels/*/**"));
assertEquals(1, comparator.compare("/hotels/*/**", "/hotels/*"));
assertEquals(-1, comparator.compare("/hotels/new", "/hotels/new.*"));
//SPR-6741
assertEquals(-1, comparator.compare("/hotels/{hotel}/bookings/{booking}/cutomers/{customer}", "/hotels/**"));
assertEquals(1, comparator.compare("/hotels/**", "/hotels/{hotel}/bookings/{booking}/cutomers/{customer}"));
assertEquals(1, comparator.compare("/hotels/foo/bar/**", "/hotels/{hotel}"));
assertEquals(-1, comparator.compare("/hotels/{hotel}", "/hotels/foo/bar/**"));
assertEquals(-12, comparator.compare("/hotels/**/bookings/**", "/hotels/**"));
assertEquals(12, comparator.compare("/hotels/**", "/hotels/**/bookings/**"));
//SPR-8683
assertEquals(1, comparator.compare("/**", "/hotels/{hotel}"));
// longer is better
assertEquals(1, comparator.compare("/hotels", "/hotels2"));
}