diff --git a/org.springframework.core/src/main/java/org/springframework/util/AntPatchStringMatcher.java b/org.springframework.core/src/main/java/org/springframework/util/AntPatchStringMatcher.java index fa84d3e36e0..d4c1f0c07a1 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/AntPatchStringMatcher.java +++ b/org.springframework.core/src/main/java/org/springframework/util/AntPatchStringMatcher.java @@ -23,11 +23,11 @@ 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 using a regular expression. + * Package-protected helper class for {@link AntPathMatcher}. Tests whether or not a string matches against a pattern + * using a regular expression. * - *

The pattern may contain special characters: '*' means zero or more characters; - * '?' means one and only one character; '{' and '}' indicate a URI template pattern. + *

The pattern may contain special characters: '*' means zero or more characters; '?' means one and only one + * character; '{' and '}' indicate a URI template pattern. * * @author Arjen Poutsma * @since 3.0 @@ -36,6 +36,8 @@ class AntPatchStringMatcher { private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{([^/]+?)\\}"); + private static final String DEFAULT_VARIABLE_PATTERN = "(.*)"; + private final Pattern pattern; private String str; @@ -65,13 +67,24 @@ class AntPatchStringMatcher { patternBuilder.append(".*"); } else if (match.startsWith("{") && match.endsWith("}")) { - patternBuilder.append("(.*)"); - variableNames.add(m.group(1)); + 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()); + return Pattern.compile(patternBuilder.toString()); } private String quote(String s, int start, int end) { diff --git a/org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java b/org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java index 7681d374498..5856b9970c6 100644 --- a/org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java +++ b/org.springframework.core/src/test/java/org/springframework/util/AntPathMatcherTests.java @@ -334,6 +334,20 @@ public class AntPathMatcherTests { assertEquals(expected, result); } + @Test + public void extractUriTemplateVariablesCustomRegex() { + Map result = pathMatcher + .extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar", + "com.example-1.0.0.jar"); + assertEquals("com.example", result.get("symbolicName")); + assertEquals("1.0.0", result.get("version")); + + result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar", + "com.example-sources-1.0.0.jar"); + assertEquals("com.example", result.get("symbolicName")); + assertEquals("1.0.0", result.get("version")); + } + @Test public void combine() { assertEquals("", pathMatcher.combine(null, null));