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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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;
|
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.
|
* 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,
|
* <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
|
* 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:
|
* generic patterns. So given a list with the following patterns: <ol> <li><code>/hotels/new</code></li>
|
||||||
* <ol>
|
* <li><code>/hotels/{hotel}</code></li> <li><code>/hotels/*</code></li> </ol> the returned comparator will sort this
|
||||||
* <li><code>/hotels/new</code></li>
|
* list so that the order will be as indicated.
|
||||||
* <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
|
* @param path the full path to use for comparison
|
||||||
* @return a comparator capable of sorting patterns in order of explicitness
|
* @return a comparator capable of sorting patterns in order of explicitness
|
||||||
|
|
@ -310,7 +388,7 @@ public class AntPathMatcher implements PathMatcher {
|
||||||
return new AntPatternComparator(path);
|
return new AntPatternComparator(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AntPatternComparator implements Comparator<String>{
|
private static class AntPatternComparator implements Comparator<String> {
|
||||||
|
|
||||||
private final String path;
|
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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* Given a pattern and a full path, extract the URI template variables. URI template
|
||||||
* variables are expressed through curly brackets ('{' and '}').
|
* variables are expressed through curly brackets ('{' and '}').
|
||||||
*
|
|
||||||
* <p>For example: For pattern "/hotels/{hotel}" and path "/hotels/1", this method will
|
* <p>For example: For pattern "/hotels/{hotel}" and path "/hotels/1", this method will
|
||||||
* return a map containing "hotel"->"1".
|
* 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.
|
* 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
|
* <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
|
* <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.
|
* 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
|
* @return a comparator capable of sorting patterns in order of explicitness
|
||||||
*/
|
*/
|
||||||
Comparator<String> getPatternComparator(String path);
|
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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -334,6 +334,31 @@ public class AntPathMatcherTests {
|
||||||
assertEquals(expected, result);
|
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
|
@Test
|
||||||
public void patternComparator() {
|
public void patternComparator() {
|
||||||
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
|
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/{hotel}", "/hotels/*"));
|
||||||
assertEquals(1, comparator.compare("/hotels/*", "/hotels/{hotel}"));
|
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/*"));
|
assertEquals(1, comparator.compare("/hotels/*/**", "/hotels/*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue