Added Pattern comparitor
This commit is contained in:
parent
61c9397c01
commit
5d5e41269b
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -52,6 +53,7 @@ import java.util.Map;
|
|||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Arjen Poutsma
|
||||
* @since 16.07.2003
|
||||
*/
|
||||
public class AntPathMatcher implements PathMatcher {
|
||||
|
|
@ -288,4 +290,73 @@ public class AntPathMatcher implements PathMatcher {
|
|||
return variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param path the full path to use for comparison
|
||||
* @return a comparator capable of sorting patterns in order of explicitness
|
||||
*/
|
||||
public Comparator<String> getPatternComparator(String path) {
|
||||
return new AntPatternComparator(path);
|
||||
}
|
||||
|
||||
private static class AntPatternComparator implements Comparator<String>{
|
||||
|
||||
private final String path;
|
||||
|
||||
private AntPatternComparator(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int compare(String pattern1, String pattern2) {
|
||||
if (pattern1 == null && pattern2 == null) {
|
||||
return 0;
|
||||
}
|
||||
else if (pattern1 == null) {
|
||||
return 1;
|
||||
}
|
||||
else if (pattern2 == null) {
|
||||
return -1;
|
||||
}
|
||||
boolean pattern1EqualsPath = pattern1.equals(path);
|
||||
boolean pattern2EqualsPath = pattern2.equals(path);
|
||||
if (pattern1EqualsPath && pattern2EqualsPath) {
|
||||
return 0;
|
||||
}
|
||||
else if (pattern1EqualsPath) {
|
||||
return -1;
|
||||
}
|
||||
else if (pattern2EqualsPath) {
|
||||
return 1;
|
||||
}
|
||||
int wildCardCount1 = StringUtils.countOccurrencesOf(pattern1, "*");
|
||||
int wildCardCount2 = StringUtils.countOccurrencesOf(pattern2, "*");
|
||||
if (wildCardCount1 < wildCardCount2) {
|
||||
return -1;
|
||||
}
|
||||
else if (wildCardCount2 < wildCardCount1) {
|
||||
return 1;
|
||||
}
|
||||
int bracketCount1 = StringUtils.countOccurrencesOf(pattern1, "{");
|
||||
int bracketCount2 = StringUtils.countOccurrencesOf(pattern1, "{");
|
||||
if (bracketCount1 < bracketCount2) {
|
||||
return -1;
|
||||
}
|
||||
else if (bracketCount1 < bracketCount2) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
|
@ -102,4 +103,16 @@ public interface PathMatcher {
|
|||
* @return a map, containing variable names as keys; variables values as values
|
||||
*/
|
||||
Map<String, String> extractUriTemplateVariables(String pattern, String path);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param path the full path to use for comparison
|
||||
* @return a comparator capable of sorting patterns in order of explicitness
|
||||
*/
|
||||
Comparator<String> getPatternComparator(String path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,11 @@
|
|||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
|
@ -320,5 +323,98 @@ public class AntPathMatcherTests {
|
|||
assertEquals(Collections.singletonMap("B", "b"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternComparator() {
|
||||
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
|
||||
|
||||
assertEquals(0, comparator.compare(null, null));
|
||||
assertEquals(1, comparator.compare(null, "/hotels/new"));
|
||||
assertEquals(-1, comparator.compare("/hotels/new", null));
|
||||
|
||||
assertEquals(0, comparator.compare("/hotels/new", "/hotels/new"));
|
||||
|
||||
assertEquals(-1, comparator.compare("/hotels/new", "/hotels/*"));
|
||||
assertEquals(1, comparator.compare("/hotels/*", "/hotels/new"));
|
||||
assertEquals(0, comparator.compare("/hotels/*", "/hotels/*"));
|
||||
|
||||
assertEquals(-1, comparator.compare("/hotels/new", "/hotels/{hotel}"));
|
||||
assertEquals(1, comparator.compare("/hotels/{hotel}", "/hotels/new"));
|
||||
assertEquals(0, comparator.compare("/hotels/{hotel}", "/hotels/{hotel}"));
|
||||
|
||||
assertEquals(-1, comparator.compare("/hotels/{hotel}", "/hotels/*"));
|
||||
assertEquals(1, comparator.compare("/hotels/*", "/hotels/{hotel}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternComparatorSort() {
|
||||
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
|
||||
List<String> paths = new ArrayList<String>(3);
|
||||
|
||||
paths.add(null);
|
||||
paths.add("/hotels/new");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertNull(paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/new");
|
||||
paths.add(null);
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertNull(paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/*");
|
||||
paths.add("/hotels/new");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertEquals("/hotels/*", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/new");
|
||||
paths.add("/hotels/*");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertEquals("/hotels/*", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/**");
|
||||
paths.add("/hotels/*");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/*", paths.get(0));
|
||||
assertEquals("/hotels/**", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/*");
|
||||
paths.add("/hotels/**");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/*", paths.get(0));
|
||||
assertEquals("/hotels/**", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/{hotel}");
|
||||
paths.add("/hotels/new");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertEquals("/hotels/{hotel}", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/new");
|
||||
paths.add("/hotels/{hotel}");
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertEquals("/hotels/{hotel}", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
paths.add("/hotels/*");
|
||||
paths.add("/hotels/{hotel}");
|
||||
paths.add("/hotels/new");
|
||||
Collections.shuffle(paths);
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertEquals("/hotels/{hotel}", paths.get(1));
|
||||
assertEquals("/hotels/*", paths.get(2));
|
||||
paths.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue