From a57d42829ccd680b49faac18cb75bb3852554539 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 20 Mar 2015 15:33:56 -0400 Subject: [PATCH] Support {/var} syntax in UriComponentsBuilder Issue: SPR-12750 --- .../web/util/UriComponentsBuilder.java | 39 +++++++++++++------ .../web/util/UriComponentsBuilderTests.java | 10 +++++ .../web/util/UriTemplateTests.java | 15 ++++++- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index e2251a3ece4..32f0172fda1 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -716,18 +716,35 @@ public class UriComponentsBuilder implements Cloneable { } public void addPath(String path) { - if (StringUtils.hasText(path)) { - PathSegmentComponentBuilder psBuilder = getLastBuilder(PathSegmentComponentBuilder.class); - FullPathComponentBuilder fpBuilder = getLastBuilder(FullPathComponentBuilder.class); - if (psBuilder != null) { - path = path.startsWith("/") ? path : "/" + path; - } - if (fpBuilder == null) { - fpBuilder = new FullPathComponentBuilder(); - this.builders.add(fpBuilder); - } - fpBuilder.append(path); + if (!StringUtils.hasText(path)) { + return; + } + int startIndex = path.indexOf("{/"); + while (startIndex != -1) { + String pathToAdd = path.substring(0, startIndex); + addPathInternal(pathToAdd); + + int endIndex = path.indexOf("}", startIndex); + String pathSegmentToAdd = "{" + path.substring(startIndex + 2, endIndex) + "}"; + addPathSegments(pathSegmentToAdd); + + path = (endIndex >= path.length()) ? "" : path.substring(endIndex + 1); + startIndex = path.indexOf("{/"); + } + addPathInternal(path); + } + + private void addPathInternal(String path) { + PathSegmentComponentBuilder psBuilder = getLastBuilder(PathSegmentComponentBuilder.class); + FullPathComponentBuilder fpBuilder = getLastBuilder(FullPathComponentBuilder.class); + if (psBuilder != null) { + path = path.startsWith("/") ? path : "/" + path; + } + if (fpBuilder == null) { + fpBuilder = new FullPathComponentBuilder(); + this.builders.add(fpBuilder); } + fpBuilder.append(path); } @SuppressWarnings("unchecked") diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index b5ee2eba692..917f147eb60 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -195,6 +195,16 @@ public class UriComponentsBuilderTests { assertEquals("1USD=?EUR", result.getQueryParams().getFirst("q")); } + //SPR-12750 + + @Test + public void fromUriStringWithVariablesRfc6570() { + String url = "http://example.com/part1/{/part2}/{var1}/url/{/urlvar}/"; + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url); + UriComponents uriComponents = builder.build().expand("part/2", "var/1", "url/var").encode(); + assertEquals("/part1/part%2F2/var/1/url/url%2Fvar/", uriComponents.getPath()); + } + // SPR-10779 @Test diff --git a/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java b/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java index ebd3cea2174..5a98e6c37ba 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -98,6 +98,19 @@ public class UriTemplateTests { template.expand(uriVariables); } + //SPR-12750 + + @Test + public void expandMapForRFC6570() throws Exception { + Map uriVariables = new HashMap(2); + uriVariables.put("hotel", "1"); + uriVariables.put("publicpath", "pics/logo.png"); + uriVariables.put("scale", "150x150"); + UriTemplate template = new UriTemplate("/hotels/{hotel}/pic/{/publicpath}/size/{scale}"); + URI result = template.expand(uriVariables); + assertEquals("Invalid expanded template", new URI("/hotels/1/pic/pics%2Flogo.png/size/150x150"), result); + } + @Test public void expandEncoded() throws Exception { UriTemplate template = new UriTemplate("http://example.com/hotel list/{hotel}");