SPR-7787 Allow qualifiers in regular expressions of URI template patterns.

master
Rossen Stoyanchev 13 years ago
parent 54c82a53cd
commit 2d29439130
  1. 12
      org.springframework.core/src/main/java/org/springframework/util/AntPathStringMatcher.java
  2. 42
      org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java

@ -24,17 +24,18 @@ import java.util.regex.Pattern;
/**
* Package-protected helper class for {@link AntPathMatcher}. Tests whether or not a string matches against a pattern
* using a regular expression.
* 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.
* 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 Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
@ -103,6 +104,11 @@ class AntPathStringMatcher {
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);

@ -32,6 +32,7 @@ import org.junit.Test;
* @author Seth Ladd
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Rossen Stoyanchev
*/
public class AntPathMatcherTests {
@ -335,7 +336,7 @@ public class AntPathMatcherTests {
}
@Test
public void extractUriTemplateVariablesCustomRegex() {
public void extractUriTemplateVariablesRegex() {
Map<String, String> result = pathMatcher
.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
"com.example-1.0.0.jar");
@ -347,7 +348,46 @@ public class AntPathMatcherTests {
assertEquals("com.example", result.get("symbolicName"));
assertEquals("1.0.0", result.get("version"));
}
// SPR-7787
@Test
public void extractUriTemplateVarsRegexQualifiers() {
Map<String, String> result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar",
"com.example-sources-1.0.0.jar");
assertEquals("com.example", result.get("symbolicName"));
assertEquals("1.0.0", result.get("version"));
result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\w\\.]+}-sources-{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar",
"com.example-sources-1.0.0-20100220.jar");
assertEquals("com.example", result.get("symbolicName"));
assertEquals("1.0.0", result.get("version"));
assertEquals("2010", result.get("year"));
assertEquals("02", result.get("month"));
assertEquals("20", result.get("day"));
result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar",
"com.example-sources-1.0.0.{12}.jar");
assertEquals("com.example", result.get("symbolicName"));
assertEquals("1.0.0.{12}", result.get("version"));
}
// SPR-8455
@Test
public void extractUriTemplateVarsRegexCapturingGroups() {
try {
pathMatcher.extractUriTemplateVariables("/web/{id:foo(bar)?}", "/web/foobar");
fail("Expected exception");
} catch (IllegalArgumentException e) {
assertTrue("Expected helpful message on the use of capturing groups",
e.getMessage().contains("The number of capturing groups in the pattern"));
}
}
@Test
public void combine() {
assertEquals("", pathMatcher.combine(null, null));

Loading…
Cancel
Save