Assert.notNull(result, () -> "Expected bestPattern: " + bestPattern + " to match lookupPath " + lookupPath); uriVariables = result.getUriVariables(); matrixVariables = result.getMatrixVariables();
private PathPattern.PathMatchInfo checkCapture(String uriTemplate, String path, String... keyValues) { PathPatternParser parser = new PathPatternParser(); PathPattern pattern = parser.parse(uriTemplate); PathPattern.PathMatchInfo matchResult = pattern.matchAndExtract(toPathContainer(path)); Map<String, String> expectedKeyValues = new HashMap<>(); for (int i = 0; i < keyValues.length; i += 2) { expectedKeyValues.put(keyValues[i], keyValues[i + 1]); } for (Map.Entry<String, String> me : expectedKeyValues.entrySet()) { String value = matchResult.getUriVariables().get(me.getKey()); if (value == null) { fail("Did not find key '" + me.getKey() + "' in captured variables: " + matchResult.getUriVariables()); } if (!value.equals(me.getValue())) { fail("Expected value '" + me.getValue() + "' for key '" + me.getKey() + "' but was '" + value + "'"); } } return matchResult; }
@Override public Predicate<ServerWebExchange> apply(Config config) { final ArrayList<PathPattern> pathPatterns = new ArrayList<>(); synchronized (this.pathPatternParser) { pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchOptionalTrailingSeparator()); config.getPatterns().forEach(pattern -> { PathPattern pathPattern = this.pathPatternParser.parse(pattern); pathPatterns.add(pathPattern); }); } return exchange -> { PathContainer path = parsePath(exchange.getRequest().getURI().getPath()); Optional<PathPattern> optionalPathPattern = pathPatterns.stream() .filter(pattern -> pattern.matches(path)) .findFirst(); if (optionalPathPattern.isPresent()) { PathPattern pathPattern = optionalPathPattern.get(); traceMatch("Pattern", pathPattern.getPatternString(), path, true); PathMatchInfo pathMatchInfo = pathPattern.matchAndExtract(path); putUriTemplateVariables(exchange, pathMatchInfo.getUriVariables()); return true; } else { traceMatch("Pattern", config.getPatterns(), path, false); return false; } }; }
@Override public Mono<MatchResult> matches(ServerWebExchange exchange) { ServerHttpRequest request = exchange.getRequest(); if (this.method != null && !this.method.equals(request.getMethod())) { return MatchResult.notMatch(); } PathContainer path = request.getPath().pathWithinApplication(); boolean match = this.pattern.matches(path); if (!match) { return MatchResult.notMatch(); } Map<String, String> pathVariables = this.pattern.matchAndExtract(path).getUriVariables(); Map<String, Object> variables = new HashMap<>(pathVariables); return MatchResult.match(variables); }
@Override public Mono<MatchResult> matches(ServerWebExchange exchange) { ServerHttpRequest request = exchange.getRequest(); if(this.method != null && !this.method.equals(request.getMethod())) { return MatchResult.notMatch(); } PathContainer path = request.getPath().pathWithinApplication(); boolean match = this.pattern.matches(path); if(!match) { return MatchResult.notMatch(); } Map<String,String> pathVariables = this.pattern.matchAndExtract(path).getUriVariables(); Map<String,Object> variables = new HashMap<>(pathVariables); return MatchResult.match(variables); }
/** * Return variables that were bound in the part of the path that was * successfully matched or an empty map. */ public Map<String, String> getUriVariables() { return this.pathMatchInfo.getUriVariables(); }
/** * Return variables that were bound in the part of the path that was * successfully matched or an empty map. */ public Map<String, String> getUriVariables() { return this.pathMatchInfo.getUriVariables(); }
assertEquals("resource",pp.matchAndExtract(toPathContainer("/resource")).getUriVariables().get("var")); assertMatches(pp,"/resource/"); assertEquals("resource",pp.matchAndExtract(toPathContainer("/resource/")).getUriVariables().get("var")); assertNoMatch(pp,"/resource//"); pp = parse("/{var}/"); assertNoMatch(pp,"/resource"); assertMatches(pp,"/resource/"); assertEquals("resource",pp.matchAndExtract(toPathContainer("/resource/")).getUriVariables().get("var")); assertNoMatch(pp,"/resource//"); assertEquals("/resource",pp.matchAndExtract(toPathContainer("/resource")).getUriVariables().get("var")); assertMatches(pp,"/resource/"); assertEquals("/resource/",pp.matchAndExtract(toPathContainer("/resource/")).getUriVariables().get("var")); assertMatches(pp,"/resource//"); assertEquals("/resource//",pp.matchAndExtract(toPathContainer("/resource//")).getUriVariables().get("var")); assertMatches(pp,"//resource//"); assertEquals("//resource//",pp.matchAndExtract(toPathContainer("//resource//")).getUriVariables().get("var")); assertEquals("res1",pp.matchAndExtract(toPathContainer("/res1_res2")).getUriVariables().get("var1")); assertEquals("res2",pp.matchAndExtract(toPathContainer("/res1_res2")).getUriVariables().get("var2")); assertMatches(pp,"/res1_res2/"); assertEquals("res1",pp.matchAndExtract(toPathContainer("/res1_res2/")).getUriVariables().get("var1")); assertEquals("res2",pp.matchAndExtract(toPathContainer("/res1_res2/")).getUriVariables().get("var2")); assertNoMatch(pp,"/res1_res2//"); pp = parse("/{var1}_{var2}/"); assertNoMatch(pp,"/res1_res2"); assertMatches(pp,"/res1_res2/"); assertEquals("res1",pp.matchAndExtract(toPathContainer("/res1_res2/")).getUriVariables().get("var1")); assertEquals("res2",pp.matchAndExtract(toPathContainer("/res1_res2/")).getUriVariables().get("var2"));
assertEquals(CaptureVariablePathElement.class.getName(), next.getClass().getName()); PathPattern.PathMatchInfo result = matchAndExtract(pathPattern,"/foo"); assertEquals("foo", result.getUriVariables().get("var")); assertEquals(CaptureVariablePathElement.class.getName(), next.getClass().getName()); result = matchAndExtract(pathPattern,"/[[["); assertEquals("[[[", result.getUriVariables().get("var")); assertEquals(CaptureVariablePathElement.class.getName(), next.getClass().getName()); result = matchAndExtract(pathPattern,"/{{{"); assertEquals("{{{", result.getUriVariables().get("var")); assertEquals(CaptureVariablePathElement.class.getName(), next.getClass().getName()); result = matchAndExtract(pathPattern,"/}}}"); assertEquals("}}}", result.getUriVariables().get("var"));
assertEquals("one",result.getUriVariables().get("var")); assertEquals("three",result.getMatrixVariables().get("var").getFirst("two")); assertEquals("five",result.getMatrixVariables().get("var").getFirst("four")); assertEquals("123",result.getUriVariables().get("var1")); assertEquals("456",result.getUriVariables().get("var2")); assertEquals("/abc/123_456",result.getUriVariables().get("var")); assertEquals("b",result.getMatrixVariables().get("var").getFirst("a")); assertEquals("d",result.getMatrixVariables().get("var").getFirst("c")); result = matchAndExtract("/{*var}","/abc/123_456;a=b;c=d/789;a=e;f=g"); assertEquals("/abc/123_456/789",result.getUriVariables().get("var")); assertEquals("[b, e]",result.getMatrixVariables().get("var").get("a").toString()); assertEquals("d",result.getMatrixVariables().get("var").getFirst("c")); assertEquals("one",result.getUriVariables().get("var")); assertNull(result.getMatrixVariables().get("var"));
/** * Return variables that were bound in the part of the path that was * successfully matched or an empty map. */ public Map<String, String> getUriVariables() { return this.pathMatchInfo.getUriVariables(); }
@Test public void extractUriTemplateVariables() throws Exception { assertMatches(parse("{hotel}"),"1"); assertMatches(parse("/hotels/{hotel}"),"/hotels/1"); checkCapture("/hotels/{hotel}", "/hotels/1", "hotel", "1"); checkCapture("/h?tels/{hotel}", "/hotels/1", "hotel", "1"); checkCapture("/hotels/{hotel}/bookings/{booking}", "/hotels/1/bookings/2", "hotel", "1", "booking", "2"); checkCapture("/*/hotels/*/{hotel}", "/foo/hotels/bar/1", "hotel", "1"); checkCapture("/{page}.html", "/42.html", "page", "42"); checkNoMatch("/{var}","/"); checkCapture("/{page}.*", "/42.html", "page", "42"); checkCapture("/A-{B}-C", "/A-b-C", "B", "b"); checkCapture("/{name}.{extension}", "/test.html", "name", "test", "extension", "html"); assertNull(checkCapture("/{one}/", "//")); assertNull(checkCapture("", "/abc")); assertEquals(0, checkCapture("", "").getUriVariables().size()); checkCapture("{id}", "99", "id", "99"); checkCapture("/customer/{customerId}", "/customer/78", "customerId", "78"); checkCapture("/customer/{customerId}/banana", "/customer/42/banana", "customerId", "42"); checkCapture("{id}/{id2}", "99/98", "id", "99", "id2", "98"); checkCapture("/foo/{bar}/boo/{baz}", "/foo/plum/boo/apple", "bar", "plum", "baz", "apple"); checkCapture("/{bla}.*", "/testing.html", "bla", "testing"); PathPattern.PathMatchInfo extracted = checkCapture("/abc", "/abc"); assertEquals(0, extracted.getUriVariables().size()); checkCapture("/{bla}/foo","/a/foo"); }
@Test public void extractUriTemplateVarsRegexQualifiers() { PathPatternParser pp = new PathPatternParser(); PathPattern p = pp.parse("{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar"); PathPattern.PathMatchInfo result = p.matchAndExtract(toPathContainer("com.example-sources-1.0.0.jar")); assertEquals("com.example", result.getUriVariables().get("symbolicName")); assertEquals("1.0.0", result.getUriVariables().get("version")); p = pp.parse("{symbolicName:[\\w\\.]+}-sources-" + "{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar"); result = matchAndExtract(p,"com.example-sources-1.0.0-20100220.jar"); assertEquals("com.example", result.getUriVariables().get("symbolicName")); assertEquals("1.0.0", result.getUriVariables().get("version")); assertEquals("2010", result.getUriVariables().get("year")); assertEquals("02", result.getUriVariables().get("month")); assertEquals("20", result.getUriVariables().get("day")); p = pp.parse("{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar"); result = matchAndExtract(p, "com.example-sources-1.0.0.{12}.jar"); assertEquals("com.example", result.getUriVariables().get("symbolicName")); assertEquals("1.0.0.{12}", result.getUriVariables().get("version")); }
@Test public void compare_spr15597() { PathPatternParser parser = new PathPatternParser(); PathPattern p1 = parser.parse("/{foo}"); PathPattern p2 = parser.parse("/{foo}.*"); PathPattern.PathMatchInfo r1 = matchAndExtract(p1, "/file.txt"); PathPattern.PathMatchInfo r2 = matchAndExtract(p2, "/file.txt"); // works fine assertEquals("file.txt", r1.getUriVariables().get("foo")); assertEquals("file", r2.getUriVariables().get("foo")); // This produces 2 (see comments in https://jira.spring.io/browse/SPR-14544 ) // Comparator<String> patternComparator = new AntPathMatcher().getPatternComparator(""); // System.out.println(patternComparator.compare("/{foo}","/{foo}.*")); assertThat(p1.compareTo(p2), Matchers.greaterThan(0)); }
@Override public boolean test(ServerRequest request) { PathContainer pathContainer = request.pathContainer(); PathPattern.PathMatchInfo info = this.pattern.matchAndExtract(pathContainer); traceMatch("Pattern", this.pattern.getPatternString(), request.path(), info != null); if (info != null) { mergeAttributes(request, info.getUriVariables(), this.pattern); return true; } else { return false; } }
@Test public void extractUriTemplateVariablesRegex() { PathPatternParser pp = new PathPatternParser(); PathPattern p = null; p = pp.parse("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar"); PathPattern.PathMatchInfo result = matchAndExtract(p, "com.example-1.0.0.jar"); assertEquals("com.example", result.getUriVariables().get("symbolicName")); assertEquals("1.0.0", result.getUriVariables().get("version")); p = pp.parse("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar"); result = matchAndExtract(p, "com.example-sources-1.0.0.jar"); assertEquals("com.example", result.getUriVariables().get("symbolicName")); assertEquals("1.0.0", result.getUriVariables().get("version")); }
/** * Return variables that were bound in the part of the path that was * successfully matched or an empty map. */ public Map<String, String> getUriVariables() { return this.pathMatchInfo.getUriVariables(); }