Browse Source

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

pull/7/head
Rossen Stoyanchev 14 years ago
parent
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

12
org.springframework.core/src/main/java/org/springframework/util/AntPathStringMatcher.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 * 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 * <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 Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.0 * @since 3.0
*/ */
class AntPathStringMatcher { 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 = "(.*)"; private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
@ -103,6 +104,11 @@ class AntPathStringMatcher {
Matcher matcher = pattern.matcher(str); Matcher matcher = pattern.matcher(str);
if (matcher.matches()) { if (matcher.matches()) {
if (uriTemplateVariables != null) { 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++) { for (int i = 1; i <= matcher.groupCount(); i++) {
String name = this.variableNames.get(i - 1); String name = this.variableNames.get(i - 1);
String value = matcher.group(i); String value = matcher.group(i);

42
org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java

@ -32,6 +32,7 @@ import org.junit.Test;
* @author Seth Ladd * @author Seth Ladd
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class AntPathMatcherTests { public class AntPathMatcherTests {
@ -335,7 +336,7 @@ public class AntPathMatcherTests {
} }
@Test @Test
public void extractUriTemplateVariablesCustomRegex() { public void extractUriTemplateVariablesRegex() {
Map<String, String> result = pathMatcher Map<String, String> result = pathMatcher
.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar", .extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
"com.example-1.0.0.jar"); "com.example-1.0.0.jar");
@ -347,7 +348,46 @@ public class AntPathMatcherTests {
assertEquals("com.example", result.get("symbolicName")); assertEquals("com.example", result.get("symbolicName"));
assertEquals("1.0.0", result.get("version")); 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 @Test
public void combine() { public void combine() {
assertEquals("", pathMatcher.combine(null, null)); assertEquals("", pathMatcher.combine(null, null));

Loading…
Cancel
Save