Added combine method to PathMatcher, for combining two patterns.
This commit is contained in:
parent
6e7e107621
commit
56ddc76712
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -290,18 +290,96 @@ public class AntPathMatcher implements PathMatcher {
|
|||
return variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines two patterns into a new pattern that is returned.
|
||||
* <p>This implementation simply concatenates the two patterns, unless the
|
||||
* first pattern contains a file extension match (such as {@code *.html}. In
|
||||
* that case, the second pattern should be included in the first, or an
|
||||
* {@code IllegalArgumentException} is thrown.
|
||||
* <p>For example:
|
||||
* <table>
|
||||
* <tr><th>Pattern 1</th><th>Pattern 2</th><th>Result</th></tr>
|
||||
* <tr><td>/hotels</td><td>{@code null}</td><td>/hotels</td></tr>
|
||||
* <tr><td>{@code null}</td><td>/hotels</td><td>/hotels</td></tr>
|
||||
* <tr><td>/hotels</td><td>/bookings</td><td>/hotels/bookings</td></tr>
|
||||
* <tr><td>/hotels</td><td>bookings</td><td>/hotels/bookings</td></tr>
|
||||
* <tr><td>/hotels/*</td><td>/bookings</td><td>/hotels/bookings</td></tr>
|
||||
* <tr><td>/hotels/**</td><td>/bookings</td><td>/hotels/**/bookings</td></tr>
|
||||
* <tr><td>/hotels</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr>
|
||||
* <tr><td>/hotels/*</td><td>{hotel}</td><td>/hotels/{hotel}</td></tr>
|
||||
* <tr><td>/hotels/**</td><td>{hotel}</td><td>/hotels/**/{hotel}</td></tr>
|
||||
* <tr><td>/*.html</td><td>/hotels.html</td><td>/hotels.html</td></tr>
|
||||
* <tr><td>/*.html</td><td>/hotels</td><td>IllegalArgumentException</td></tr>
|
||||
* </table>
|
||||
*
|
||||
* @param pattern1 the first pattern
|
||||
* @param pattern2 the second pattern
|
||||
* @return the combination of the two patterns
|
||||
* @throws IllegalArgumentException when the two patterns cannot be combined
|
||||
*/
|
||||
public String combine(String pattern1, String pattern2) {
|
||||
if (!StringUtils.hasText(pattern1) && !StringUtils.hasText(pattern2)) {
|
||||
return "";
|
||||
}
|
||||
else if (!StringUtils.hasText(pattern1)) {
|
||||
return pattern2;
|
||||
}
|
||||
else if (!StringUtils.hasText(pattern2)) {
|
||||
return pattern1;
|
||||
}
|
||||
else if (pattern1.endsWith("/*")) {
|
||||
if (pattern2.startsWith("/")) {
|
||||
// /hotels/* + /booking -> /hotels/booking
|
||||
return pattern1.substring(0, pattern1.length() - 1) + pattern2.substring(1);
|
||||
}
|
||||
else {
|
||||
// /hotels/* + booking -> /hotels/booking
|
||||
return pattern1.substring(0, pattern1.length() - 1) + pattern2;
|
||||
}
|
||||
}
|
||||
else if (pattern1.endsWith("/**")) {
|
||||
if (pattern2.startsWith("/")) {
|
||||
// /hotels/** + /booking -> /hotels/**/booking
|
||||
return pattern1 + pattern2;
|
||||
}
|
||||
else {
|
||||
// /hotels/** + booking -> /hotels/**/booking
|
||||
return pattern1 + "/" + pattern2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int idx = pattern1.indexOf("*.");
|
||||
if (idx == -1) {
|
||||
if (pattern1.endsWith("/") || pattern2.startsWith("/")) {
|
||||
return pattern1 + pattern2;
|
||||
}
|
||||
else {
|
||||
return pattern1 + "/" + pattern2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// /*.html + /hotels.html -> /hotels.html
|
||||
String extension = pattern1.substring(idx + 1);
|
||||
if (pattern2.endsWith(extension)) {
|
||||
return pattern2;
|
||||
}
|
||||
else {
|
||||
// /*.html + /hotels -> exception
|
||||
throw new IllegalArgumentException(
|
||||
"Conflicting paths: \"" + pattern1 + "\" does not include \"" + pattern2 + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of explicitness.
|
||||
*
|
||||
* <p>The returned <code>Comparator</code> 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:
|
||||
* <ol>
|
||||
* <li><code>/hotels/new</code></li>
|
||||
* <li><code>/hotels/{hotel}</code></li>
|
||||
* <li><code>/hotels/*</code></li>
|
||||
* </ol>
|
||||
* the returned comparator will sort this list so that the order will be as indicated.
|
||||
* generic patterns. So given a list with the following patterns: <ol> <li><code>/hotels/new</code></li>
|
||||
* <li><code>/hotels/{hotel}</code></li> <li><code>/hotels/*</code></li> </ol> the returned comparator will sort this
|
||||
* list so that the order will be as indicated.
|
||||
*
|
||||
* @param path the full path to use for comparison
|
||||
* @return a comparator capable of sorting patterns in order of explicitness
|
||||
|
|
@ -310,7 +388,7 @@ public class AntPathMatcher implements PathMatcher {
|
|||
return new AntPatternComparator(path);
|
||||
}
|
||||
|
||||
private static class AntPatternComparator implements Comparator<String>{
|
||||
private static class AntPatternComparator implements Comparator<String> {
|
||||
|
||||
private final String path;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -94,7 +94,6 @@ public interface PathMatcher {
|
|||
/**
|
||||
* Given a pattern and a full path, extract the URI template variables. URI template
|
||||
* variables are expressed through curly brackets ('{' and '}').
|
||||
*
|
||||
* <p>For example: For pattern "/hotels/{hotel}" and path "/hotels/1", this method will
|
||||
* return a map containing "hotel"->"1".
|
||||
*
|
||||
|
|
@ -106,7 +105,6 @@ public interface PathMatcher {
|
|||
|
||||
/**
|
||||
* Given a full path, returns a {@link Comparator} suitable for sorting patterns in order of explicitness.
|
||||
*
|
||||
* <p>The full algorithm used depends on the underlying implementation, but generally, the returned
|
||||
* <code>Comparator</code> will {@linkplain java.util.Collections#sort(java.util.List, java.util.Comparator) sort} a
|
||||
* list so that more specific patterns come before generic patterns.
|
||||
|
|
@ -115,4 +113,15 @@ public interface PathMatcher {
|
|||
* @return a comparator capable of sorting patterns in order of explicitness
|
||||
*/
|
||||
Comparator<String> getPatternComparator(String path);
|
||||
|
||||
/**
|
||||
* Combines two patterns into a new pattern that is returned.
|
||||
* <p>The full algorithm used for combining the two pattern depends on the underlying implementation.
|
||||
*
|
||||
* @param pattern1 the first pattern
|
||||
* @param pattern2 the second pattern
|
||||
* @return the combination of the two patterns
|
||||
* @throws IllegalArgumentException when the two patterns cannot be combined
|
||||
*/
|
||||
String combine(String pattern1, String pattern2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -334,6 +334,31 @@ public class AntPathMatcherTests {
|
|||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combine() {
|
||||
assertEquals("", pathMatcher.combine(null, null));
|
||||
assertEquals("/hotels", pathMatcher.combine("/hotels", null));
|
||||
assertEquals("/hotels", pathMatcher.combine(null, "/hotels"));
|
||||
assertEquals("/hotels/booking", pathMatcher.combine("/hotels/*", "booking"));
|
||||
assertEquals("/hotels/booking", pathMatcher.combine("/hotels/*", "/booking"));
|
||||
assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "booking"));
|
||||
assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "/booking"));
|
||||
assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "/booking"));
|
||||
assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "booking"));
|
||||
assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels/*", "{hotel}"));
|
||||
assertEquals("/hotels/**/{hotel}", pathMatcher.combine("/hotels/**", "{hotel}"));
|
||||
assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels", "{hotel}"));
|
||||
assertEquals("/hotels/*/booking/{booking}", pathMatcher.combine("/hotels/*/booking", "{booking}"));
|
||||
assertEquals("/hotel.html", pathMatcher.combine("/*.html", "/hotel.html"));
|
||||
try {
|
||||
assertEquals("/hotel.html", pathMatcher.combine("/*.html", "/hotel"));
|
||||
fail("IllegalArgumentException expected");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternComparator() {
|
||||
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
|
||||
|
|
@ -355,7 +380,7 @@ public class AntPathMatcherTests {
|
|||
assertEquals(-1, comparator.compare("/hotels/{hotel}", "/hotels/*"));
|
||||
assertEquals(1, comparator.compare("/hotels/*", "/hotels/{hotel}"));
|
||||
|
||||
assertEquals(-1, comparator.compare("/hotels/*","/hotels/*/**"));
|
||||
assertEquals(-1, comparator.compare("/hotels/*", "/hotels/*/**"));
|
||||
assertEquals(1, comparator.compare("/hotels/*/**", "/hotels/*"));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue