diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index 89fe9fbd3b4b048bf4cd5fc789f323bf756605ce..c10d661736cd5e939a2d5fedea4980bf8e7658e2 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -419,12 +419,10 @@ public class AntPathMatcher implements PathMatcher { /** * Combine two patterns into a new pattern. - * *

This implementation simply concatenates the two patterns, unless * the first pattern contains a file extension match (e.g., {@code *.html}). * In that case, the second pattern will be merged into the first. Otherwise, * an {@code IllegalArgumentException} will be thrown. - * *

Examples

* * @@ -442,7 +440,6 @@ public class AntPathMatcher implements PathMatcher { * * *
Pattern 1Pattern 2Result
/*.html/hotels/hotels.html
/*.html/*.txt{@code IllegalArgumentException}
- * * @param pattern1 the first pattern * @param pattern2 the second pattern * @return the combination of the two patterns @@ -460,7 +457,7 @@ public class AntPathMatcher implements PathMatcher { return pattern1; } - boolean pattern1ContainsUriVar = pattern1.indexOf('{') != -1; + boolean pattern1ContainsUriVar = (pattern1.indexOf('{') != -1); if (!pattern1.equals(pattern2) && !pattern1ContainsUriVar && match(pattern1, pattern2)) { // /* + /hotel -> /hotel ; "/*.*" + "/*.html" -> /*.html // However /user + /user -> /usr/user ; /{foo} + /bar -> /{foo}/bar @@ -484,12 +481,18 @@ public class AntPathMatcher implements PathMatcher { // simply concatenate the two patterns return concat(pattern1, pattern2); } - String extension1 = pattern1.substring(starDotPos1 + 1); + + String ext1 = pattern1.substring(starDotPos1 + 1); int dotPos2 = pattern2.indexOf('.'); - String fileName2 = (dotPos2 == -1 ? pattern2 : pattern2.substring(0, dotPos2)); - String extension2 = (dotPos2 == -1 ? "" : pattern2.substring(dotPos2)); - String extension = extension1.startsWith("*") ? extension2 : extension1; - return fileName2 + extension; + String file2 = (dotPos2 == -1 ? pattern2 : pattern2.substring(0, dotPos2)); + String ext2 = (dotPos2 == -1 ? "" : pattern2.substring(dotPos2)); + boolean ext1All = (ext1.equals(".*") || ext1.equals("")); + boolean ext2All = (ext2.equals(".*") || ext2.equals("")); + if (!ext1All && !ext2All) { + throw new IllegalArgumentException("Cannot combine patterns: " + pattern1 + " vs " + pattern2); + } + String ext = (ext1All ? ext2 : ext1); + return file2 + ext; } private String concat(String path1, String path2) { @@ -508,14 +511,18 @@ public class AntPathMatcher implements PathMatcher { } /** - * Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of explicitness. - *

The returned {@code Comparator} will {@linkplain java.util.Collections#sort(java.util.List, - * java.util.Comparator) sort} a list so that more specific patterns (without uri templates or wild cards) come before - * generic patterns. So given a list with the following patterns:

  1. {@code /hotels/new}
  2. - *
  3. {@code /hotels/{hotel}}
  4. {@code /hotels/*}
the returned comparator will sort this - * list so that the order will be as indicated. - *

The full path given as parameter is used to test for exact matches. So when the given path is {@code /hotels/2}, - * the pattern {@code /hotels/2} will be sorted before {@code /hotels/1}. + * Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of + * explicitness. + *

This{@code Comparator} will {@linkplain java.util.Collections#sort(List, Comparator) sort} + * a list so that more specific patterns (without uri templates or wild cards) come before + * generic patterns. So given a list with the following patterns: + *

    + *
  1. {@code /hotels/new}
  2. + *
  3. {@code /hotels/{hotel}}
  4. {@code /hotels/*}
  5. + *
+ * the returned comparator will sort this list so that the order will be as indicated. + *

The full path given as parameter is used to test for exact matches. So when the given path + * is {@code /hotels/2}, the pattern {@code /hotels/2} will be sorted before {@code /hotels/1}. * @param path the full path to use for comparison * @return a comparator capable of sorting patterns in order of explicitness */ diff --git a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java index 4b724929e51d93d1e599549438e48bf996be6554..2de004df88c9c97686d1390cdb6e1390094dd409 100644 --- a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java +++ b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java @@ -44,15 +44,11 @@ import static org.junit.Assert.*; */ public class AntPathMatcherTests { - private AntPathMatcher pathMatcher; + private final AntPathMatcher pathMatcher = new AntPathMatcher(); @Rule - public ExpectedException exception = ExpectedException.none(); + public final ExpectedException exception = ExpectedException.none(); - @Before - public void createMatcher() { - pathMatcher = new AntPathMatcher(); - } @Test public void match() { @@ -432,7 +428,6 @@ public class AntPathMatcherTests { assertEquals("/hotel/booking", pathMatcher.combine("/hotel/", "/booking")); // SPR-12975 } - @Ignore("Disabled until SPR-12998 is resolved") @Test public void combineWithTwoFileExtensionPatterns() { exception.expect(IllegalArgumentException.class);