PathPattern#matchAndExtract minor refactoring

Consistent behavior with matches(PathContainer), the two had slightly
different logic for handling of empty paths.

Make matchAndExtract independantly usable without the need to call
matches(PathContainer) first. Essentially no longer raising ISE if the
pattern doesn't match but simply returning null.
This commit is contained in:
Rossen Stoyanchev 2017-08-02 16:31:06 +02:00
parent dccedd5ad5
commit 62fa20fd6f
3 changed files with 21 additions and 29 deletions

View File

@ -180,21 +180,23 @@ public class PathPattern implements Comparable<PathPattern> {
* Match this pattern to the given URI path and return extracted URI template * Match this pattern to the given URI path and return extracted URI template
* variables as well as path parameters (matrix variables). * variables as well as path parameters (matrix variables).
* @param pathContainer the candidate path to attempt to match against * @param pathContainer the candidate path to attempt to match against
* @return info object with the extracted variables * @return info object with the extracted variables, or {@code null} for no match
* @throws IllegalStateException if the path does not match the pattern
*/ */
@Nullable
public PathMatchInfo matchAndExtract(PathContainer pathContainer) { public PathMatchInfo matchAndExtract(PathContainer pathContainer) {
MatchingContext matchingContext = new MatchingContext(pathContainer, true); if (this.head == null) {
if (this.head != null && this.head.matches(0, matchingContext)) { return hasLength(pathContainer) ? null : PathMatchInfo.EMPTY;
return matchingContext.getPathMatchResult();
} }
else if (!hasLength(pathContainer)) { else if (!hasLength(pathContainer)) {
return PathMatchInfo.EMPTY; if (this.head instanceof WildcardTheRestPathElement || this.head instanceof CaptureTheRestPathElement) {
} pathContainer = EMPTY_PATH; // Will allow CaptureTheRest to bind the variable to empty
else { }
throw new IllegalStateException( else {
"Pattern \"" + this + "\" is not a match for \"" + pathContainer.value() + "\""); return null;
}
} }
MatchingContext matchingContext = new MatchingContext(pathContainer, true);
return this.head.matches(0, matchingContext) ? matchingContext.getPathMatchResult() : null;
} }
/** /**

View File

@ -768,20 +768,10 @@ public class PathPatternTests {
checkCapture("/{page}.*", "/42.html", "page", "42"); checkCapture("/{page}.*", "/42.html", "page", "42");
checkCapture("/A-{B}-C", "/A-b-C", "B", "b"); checkCapture("/A-{B}-C", "/A-b-C", "B", "b");
checkCapture("/{name}.{extension}", "/test.html", "name", "test", "extension", "html"); checkCapture("/{name}.{extension}", "/test.html", "name", "test", "extension", "html");
try {
checkCapture("/{one}/", "//", "one", ""); assertNull(checkCapture("/{one}/", "//"));
fail("Expected exception"); assertNull(checkCapture("", "/abc"));
}
catch (IllegalStateException e) {
assertEquals("Pattern \"/{one}/\" is not a match for \"//\"", e.getMessage());
}
try {
checkCapture("", "/abc");
fail("Expected exception");
}
catch (IllegalStateException e) {
assertEquals("Pattern \"\" is not a match for \"/abc\"", e.getMessage());
}
assertEquals(0, checkCapture("", "").getUriVariables().size()); assertEquals(0, checkCapture("", "").getUriVariables().size());
checkCapture("{id}", "99", "id", "99"); checkCapture("{id}", "99", "id", "99");
checkCapture("/customer/{customerId}", "/customer/78", "customerId", "78"); checkCapture("/customer/{customerId}", "/customer/78", "customerId", "78");

View File

@ -343,10 +343,10 @@ public abstract class RequestPredicates {
@Override @Override
public boolean test(ServerRequest request) { public boolean test(ServerRequest request) {
PathContainer pathContainer = request.pathContainer(); PathContainer pathContainer = request.pathContainer();
boolean match = this.pattern.matches(pathContainer); PathPattern.PathMatchInfo info = this.pattern.matchAndExtract(pathContainer);
traceMatch("Pattern", this.pattern.getPatternString(), request.path(), match); traceMatch("Pattern", this.pattern.getPatternString(), request.path(), info != null);
if (match) { if (info != null) {
mergeTemplateVariables(request, this.pattern.matchAndExtract(pathContainer).getUriVariables()); mergeTemplateVariables(request, info.getUriVariables());
return true; return true;
} }
else { else {