diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java index 6c6249df1302..16af8d8ed783 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java @@ -118,6 +118,10 @@ public char[] getChars() { return this.text; } + @Override + public boolean isLiteral() { + return true; + } @Override public String toString() { diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java index df4330172645..699b7bec14b5 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java @@ -25,6 +25,7 @@ * Common supertype for the Ast nodes created to represent a path pattern. * * @author Andy Clement + * @author Brian Clozel * @since 5.0 */ abstract class PathElement { @@ -99,6 +100,14 @@ public int getScore() { return 0; } + /** + * Return whether this PathElement can be strictly {@link String#compareTo(String) compared} + * against another element for matching. + */ + public boolean isLiteral() { + return false; + } + /** * Return if the there are no more PathElements in the pattern. * @return {@code true} if the there are no more elements diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java index 8b5aee9223c5..dcf7382bd527 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java @@ -303,7 +303,7 @@ public PathContainer extractPathWithinPattern(PathContainer path) { // Find first path element that is not a separator or a literal (i.e. the first pattern based element) PathElement elem = this.head; while (elem != null) { - if (elem.getWildcardCount() != 0 || elem.getCaptureCount() != 0) { + if (!elem.isLiteral()) { break; } elem = elem.next; diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java index b140e88b44e3..b6ba087bfb68 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java @@ -67,6 +67,10 @@ public char[] getChars() { return new char[] {this.separator}; } + @Override + public boolean isLiteral() { + return true; + } @Override public String toString() { diff --git a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java index 97aad62e6229..eab9bfd7bcc9 100644 --- a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java @@ -684,6 +684,7 @@ public void extractPathWithinPattern() throws Exception { checkExtractPathWithinPattern("/docs/commit.html", "/docs/commit.html", ""); checkExtractPathWithinPattern("/docs/*", "/docs/cvs/commit", "cvs/commit"); checkExtractPathWithinPattern("/docs/cvs/*.html", "/docs/cvs/commit.html", "commit.html"); + checkExtractPathWithinPattern("/docs/cvs/file.*.html", "/docs/cvs/file.sha.html", "file.sha.html"); checkExtractPathWithinPattern("/docs/**", "/docs/cvs/commit", "cvs/commit"); checkExtractPathWithinPattern("/doo/{*foobar}", "/doo/customer.html", "customer.html"); checkExtractPathWithinPattern("/doo/{*foobar}", "/doo/daa/customer.html", "daa/customer.html");