|
|
|
@ -594,15 +594,16 @@ public class AntPathMatcher implements PathMatcher {
@@ -594,15 +594,16 @@ public class AntPathMatcher implements PathMatcher {
|
|
|
|
|
@Override |
|
|
|
|
public int compare(String pattern1, String pattern2) { |
|
|
|
|
|
|
|
|
|
boolean pattern1NullCaptureAll = isNullOrCaptureAllPattern(pattern1); |
|
|
|
|
boolean pattern2NullCaptureAll = isNullOrCaptureAllPattern(pattern2); |
|
|
|
|
if (pattern1NullCaptureAll && pattern2NullCaptureAll) { |
|
|
|
|
PatternInfo info1 = new PatternInfo(pattern1); |
|
|
|
|
PatternInfo info2 = new PatternInfo(pattern2); |
|
|
|
|
|
|
|
|
|
if (info1.isLeastSpecific() && info2.isLeastSpecific()) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
else if (pattern1NullCaptureAll) { |
|
|
|
|
else if (info1.isLeastSpecific()) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
else if (pattern2NullCaptureAll) { |
|
|
|
|
else if (info2.isLeastSpecific()) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -618,93 +619,126 @@ public class AntPathMatcher implements PathMatcher {
@@ -618,93 +619,126 @@ public class AntPathMatcher implements PathMatcher {
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PatternElements pattern1Elements = new PatternElements(pattern1); |
|
|
|
|
PatternElements pattern2Elements = new PatternElements(pattern2); |
|
|
|
|
|
|
|
|
|
if(pattern1Elements.endsWithCatchAll && pattern2Elements.catchAllCount == 0) { |
|
|
|
|
if (info1.isPrefixPattern() && info2.getDoubleWildcards() == 0) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
else if(pattern2Elements.endsWithCatchAll && pattern1Elements.catchAllCount == 0) { |
|
|
|
|
else if (info2.isPrefixPattern() && info1.getDoubleWildcards() == 0) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int totalCount1 = pattern1Elements.bracketCount + pattern1Elements.wildcardsCount; |
|
|
|
|
int totalCount2 = pattern2Elements.bracketCount + pattern2Elements.wildcardsCount; |
|
|
|
|
|
|
|
|
|
if (totalCount1 != totalCount2) { |
|
|
|
|
return totalCount1 - totalCount2; |
|
|
|
|
if (info1.getTotalCount() != info2.getTotalCount()) { |
|
|
|
|
return info1.getTotalCount() - info2.getTotalCount(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int pattern1Length = getPatternLength(pattern1); |
|
|
|
|
int pattern2Length = getPatternLength(pattern2); |
|
|
|
|
|
|
|
|
|
if (pattern1Length != pattern2Length) { |
|
|
|
|
return pattern2Length - pattern1Length; |
|
|
|
|
if (info1.getLength() != info2.getLength()) { |
|
|
|
|
return info2.getLength() - info1.getLength(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pattern1Elements.wildcardsCount < pattern2Elements.wildcardsCount) { |
|
|
|
|
if (info1.getSingleWildcards() < info2.getSingleWildcards()) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
else if (pattern2Elements.wildcardsCount < pattern1Elements.wildcardsCount) { |
|
|
|
|
else if (info2.getSingleWildcards() < info1.getSingleWildcards()) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pattern1Elements.bracketCount < pattern2Elements.bracketCount) { |
|
|
|
|
if (info1.getUriVars() < info2.getUriVars()) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
else if (pattern2Elements.bracketCount < pattern1Elements.bracketCount) { |
|
|
|
|
else if (info2.getUriVars() < info1.getUriVars()) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private boolean isNullOrCaptureAllPattern(String pattern) { |
|
|
|
|
return pattern == null || "/**".equals(pattern); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns the length of the given pattern, where template variables are considered to be 1 long. |
|
|
|
|
* Value class that holds information about the pattern, e.g. number of |
|
|
|
|
* occurrences of "*", "**", and "{" pattern elements. |
|
|
|
|
*/ |
|
|
|
|
private int getPatternLength(String pattern) { |
|
|
|
|
return VARIABLE_PATTERN.matcher(pattern).replaceAll("#").length(); |
|
|
|
|
} |
|
|
|
|
private static class PatternInfo { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Value class that holds the number of occurrences for "*", "**", and "{" pattern elements |
|
|
|
|
*/ |
|
|
|
|
private class PatternElements { |
|
|
|
|
int bracketCount = 0; |
|
|
|
|
int wildcardsCount = 0; |
|
|
|
|
int catchAllCount = 0; |
|
|
|
|
boolean endsWithCatchAll; |
|
|
|
|
private final String pattern; |
|
|
|
|
|
|
|
|
|
public PatternElements(String pattern) { |
|
|
|
|
private int uriVars; |
|
|
|
|
|
|
|
|
|
if(pattern == null || pattern.length() == 0) { |
|
|
|
|
return; |
|
|
|
|
private int singleWildcards; |
|
|
|
|
|
|
|
|
|
private int doubleWildcards; |
|
|
|
|
|
|
|
|
|
private boolean catchAllPattern; |
|
|
|
|
|
|
|
|
|
private boolean prefixPattern; |
|
|
|
|
|
|
|
|
|
private Integer length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public PatternInfo(String pattern) { |
|
|
|
|
this.pattern = pattern; |
|
|
|
|
if (this.pattern != null) { |
|
|
|
|
initCounters(); |
|
|
|
|
this.catchAllPattern = this.pattern.equals("/**"); |
|
|
|
|
this.prefixPattern = !this.catchAllPattern && this.pattern.endsWith("/**"); |
|
|
|
|
} |
|
|
|
|
int pos = 0; |
|
|
|
|
if (this.uriVars == 0) { |
|
|
|
|
this.length = (this.pattern != null ? this.pattern.length() : 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while(pos < pattern.length()) { |
|
|
|
|
if(pattern.charAt(pos) == '{') { |
|
|
|
|
bracketCount++; |
|
|
|
|
protected void initCounters() { |
|
|
|
|
int pos = 0; |
|
|
|
|
while (pos < this.pattern.length()) { |
|
|
|
|
if(this.pattern.charAt(pos) == '{') { |
|
|
|
|
this.uriVars++; |
|
|
|
|
pos++; |
|
|
|
|
} else if(pattern.charAt(pos) == '*') { |
|
|
|
|
if(pos + 1 < pattern.length() && pattern.charAt(pos + 1) == '*') { |
|
|
|
|
catchAllCount++; |
|
|
|
|
} |
|
|
|
|
else if(this.pattern.charAt(pos) == '*') { |
|
|
|
|
if(pos + 1 < this.pattern.length() && this.pattern.charAt(pos + 1) == '*') { |
|
|
|
|
this.doubleWildcards++; |
|
|
|
|
pos += 2; |
|
|
|
|
} else { |
|
|
|
|
wildcardsCount++; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
this.singleWildcards++; |
|
|
|
|
pos++; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
pos++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
endsWithCatchAll = pattern.endsWith("**"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int getUriVars() { |
|
|
|
|
return this.uriVars; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int getSingleWildcards() { |
|
|
|
|
return this.singleWildcards; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int getDoubleWildcards() { |
|
|
|
|
return this.doubleWildcards; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public boolean isLeastSpecific() { |
|
|
|
|
return (this.pattern == null || this.catchAllPattern); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public boolean isPrefixPattern() { |
|
|
|
|
return this.prefixPattern; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public int getTotalCount() { |
|
|
|
|
return this.uriVars + this.singleWildcards + (2 * this.doubleWildcards); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns the length of the given pattern, where template variables are considered to be 1 long. |
|
|
|
|
*/ |
|
|
|
|
public int getLength() { |
|
|
|
|
if (this.length == null) { |
|
|
|
|
this.length = VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length(); |
|
|
|
|
} |
|
|
|
|
return this.length; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|