Inlined AntPathStringMatcher into AntPathMatcher
Also initializing the capacity of the AntPathStringMatcher cache to 256 now.
This commit is contained in:
@@ -18,6 +18,8 @@ package org.springframework.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -43,6 +45,7 @@ import java.util.regex.Pattern;
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 16.07.2003
|
||||
*/
|
||||
public class AntPathMatcher implements PathMatcher {
|
||||
@@ -55,7 +58,7 @@ public class AntPathMatcher implements PathMatcher {
|
||||
private String pathSeparator = DEFAULT_PATH_SEPARATOR;
|
||||
|
||||
private final Map<String, AntPathStringMatcher> stringMatcherCache =
|
||||
new ConcurrentHashMap<String, AntPathStringMatcher>();
|
||||
new ConcurrentHashMap<String, AntPathStringMatcher>(256);
|
||||
|
||||
|
||||
/** Set the path separator to use for pattern parsing. Default is "/", as in Ant. */
|
||||
@@ -213,8 +216,9 @@ public class AntPathMatcher implements PathMatcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether or not a string matches against a pattern. The pattern may contain two special characters:<br> '*'
|
||||
* means zero or more characters<br> '?' means one and only one character
|
||||
* Tests whether or not a string matches against a pattern. The pattern may contain two special characters:
|
||||
* <br>'*' means zero or more characters
|
||||
* <br>'?' means one and only one character
|
||||
* @param pattern pattern to match against. Must not be <code>null</code>.
|
||||
* @param str string which must be matched against the pattern. Must not be <code>null</code>.
|
||||
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
|
||||
@@ -462,4 +466,88 @@ public class AntPathMatcher implements PathMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests whether or not a string matches against a pattern via a {@link Pattern}.
|
||||
* <p>The pattern may contain special characters: '*' means zero or more characters; '?' means one and
|
||||
* only one character; '{' and '}' indicate a URI template pattern. For example <tt>/users/{user}</tt>.
|
||||
*/
|
||||
private static class AntPathStringMatcher {
|
||||
|
||||
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
|
||||
|
||||
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
private final List<String> variableNames = new LinkedList<String>();
|
||||
|
||||
public AntPathStringMatcher(String pattern) {
|
||||
StringBuilder patternBuilder = new StringBuilder();
|
||||
Matcher m = GLOB_PATTERN.matcher(pattern);
|
||||
int end = 0;
|
||||
while (m.find()) {
|
||||
patternBuilder.append(quote(pattern, end, m.start()));
|
||||
String match = m.group();
|
||||
if ("?".equals(match)) {
|
||||
patternBuilder.append('.');
|
||||
}
|
||||
else if ("*".equals(match)) {
|
||||
patternBuilder.append(".*");
|
||||
}
|
||||
else if (match.startsWith("{") && match.endsWith("}")) {
|
||||
int colonIdx = match.indexOf(':');
|
||||
if (colonIdx == -1) {
|
||||
patternBuilder.append(DEFAULT_VARIABLE_PATTERN);
|
||||
this.variableNames.add(m.group(1));
|
||||
}
|
||||
else {
|
||||
String variablePattern = match.substring(colonIdx + 1, match.length() - 1);
|
||||
patternBuilder.append('(');
|
||||
patternBuilder.append(variablePattern);
|
||||
patternBuilder.append(')');
|
||||
String variableName = match.substring(1, colonIdx);
|
||||
this.variableNames.add(variableName);
|
||||
}
|
||||
}
|
||||
end = m.end();
|
||||
}
|
||||
patternBuilder.append(quote(pattern, end, pattern.length()));
|
||||
this.pattern = Pattern.compile(patternBuilder.toString());
|
||||
}
|
||||
|
||||
private String quote(String s, int start, int end) {
|
||||
if (start == end) {
|
||||
return "";
|
||||
}
|
||||
return Pattern.quote(s.substring(start, end));
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) {
|
||||
Matcher matcher = this.pattern.matcher(str);
|
||||
if (matcher.matches()) {
|
||||
if (uriTemplateVariables != null) {
|
||||
// SPR-8455
|
||||
Assert.isTrue(this.variableNames.size() == matcher.groupCount(),
|
||||
"The number of capturing groups in the pattern segment " + this.pattern +
|
||||
" does not match the number of URI template variables it defines, which can occur if " +
|
||||
" capturing groups are used in a URI template regex. Use non-capturing groups instead.");
|
||||
for (int i = 1; i <= matcher.groupCount(); i++) {
|
||||
String name = this.variableNames.get(i - 1);
|
||||
String value = matcher.group(i);
|
||||
uriTemplateVariables.put(name, value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Package-protected helper class for {@link AntPathMatcher}. Tests whether or not a string matches against a pattern
|
||||
* via a {@link Pattern}.
|
||||
*
|
||||
* <p>The pattern may contain special characters: '*' means zero or more characters; '?' means one and only one
|
||||
* character; '{' and '}' indicate a URI template pattern. For example <tt>/users/{user}</tt>.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.0
|
||||
*/
|
||||
class AntPathStringMatcher {
|
||||
|
||||
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
|
||||
|
||||
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
private final List<String> variableNames = new LinkedList<String>();
|
||||
|
||||
|
||||
/** Construct a new instance of the <code>AntPatchStringMatcher</code>. */
|
||||
AntPathStringMatcher(String pattern) {
|
||||
this.pattern = createPattern(pattern);
|
||||
}
|
||||
|
||||
private Pattern createPattern(String pattern) {
|
||||
StringBuilder patternBuilder = new StringBuilder();
|
||||
Matcher m = GLOB_PATTERN.matcher(pattern);
|
||||
int end = 0;
|
||||
while (m.find()) {
|
||||
patternBuilder.append(quote(pattern, end, m.start()));
|
||||
String match = m.group();
|
||||
if ("?".equals(match)) {
|
||||
patternBuilder.append('.');
|
||||
}
|
||||
else if ("*".equals(match)) {
|
||||
patternBuilder.append(".*");
|
||||
}
|
||||
else if (match.startsWith("{") && match.endsWith("}")) {
|
||||
int colonIdx = match.indexOf(':');
|
||||
if (colonIdx == -1) {
|
||||
patternBuilder.append(DEFAULT_VARIABLE_PATTERN);
|
||||
variableNames.add(m.group(1));
|
||||
}
|
||||
else {
|
||||
String variablePattern = match.substring(colonIdx + 1, match.length() - 1);
|
||||
patternBuilder.append('(');
|
||||
patternBuilder.append(variablePattern);
|
||||
patternBuilder.append(')');
|
||||
String variableName = match.substring(1, colonIdx);
|
||||
variableNames.add(variableName);
|
||||
}
|
||||
}
|
||||
end = m.end();
|
||||
}
|
||||
patternBuilder.append(quote(pattern, end, pattern.length()));
|
||||
return Pattern.compile(patternBuilder.toString());
|
||||
}
|
||||
|
||||
private String quote(String s, int start, int end) {
|
||||
if (start == end) {
|
||||
return "";
|
||||
}
|
||||
return Pattern.quote(s.substring(start, end));
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*
|
||||
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) {
|
||||
Matcher matcher = pattern.matcher(str);
|
||||
if (matcher.matches()) {
|
||||
if (uriTemplateVariables != null) {
|
||||
// SPR-8455
|
||||
Assert.isTrue(variableNames.size() == matcher.groupCount(),
|
||||
"The number of capturing groups in the pattern segment " + pattern +
|
||||
" does not match the number of URI template variables it defines, which can occur if " +
|
||||
" capturing groups are used in a URI template regex. Use non-capturing groups instead.");
|
||||
for (int i = 1; i <= matcher.groupCount(); i++) {
|
||||
String name = this.variableNames.get(i - 1);
|
||||
String value = matcher.group(i);
|
||||
uriTemplateVariables.put(name, value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user