SPR-5973: now dealing with path followed by segments (and vice-versa) correctly.
This commit is contained in:
parent
1300da06a6
commit
aeba9d244a
|
|
@ -316,10 +316,10 @@ public final class UriComponents {
|
||||||
* @param uriVariables the map of URI variables
|
* @param uriVariables the map of URI variables
|
||||||
* @return the expanded uri components
|
* @return the expanded uri components
|
||||||
*/
|
*/
|
||||||
public UriComponents expand(Map<String, ?> map) {
|
public UriComponents expand(Map<String, ?> uriVariables) {
|
||||||
Assert.notNull(map, "'uriVariables' must not be null");
|
Assert.notNull(uriVariables, "'uriVariables' must not be null");
|
||||||
|
|
||||||
return expandInternal(new MapTemplateVariables(map));
|
return expandInternal(new MapTemplateVariables(uriVariables));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -526,7 +526,7 @@ public final class UriComponents {
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>
|
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>
|
||||||
*/
|
*/
|
||||||
public static enum Type {
|
static enum Type {
|
||||||
|
|
||||||
SCHEME {
|
SCHEME {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -797,6 +797,52 @@ public final class UriComponents {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a collection of PathComponents.
|
||||||
|
*/
|
||||||
|
final static class PathComponentComposite implements PathComponent {
|
||||||
|
|
||||||
|
private final List<PathComponent> pathComponents;
|
||||||
|
|
||||||
|
PathComponentComposite(List<PathComponent> pathComponents) {
|
||||||
|
this.pathComponents = pathComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
StringBuilder pathBuilder = new StringBuilder();
|
||||||
|
for (PathComponent pathComponent : pathComponents) {
|
||||||
|
pathBuilder.append(pathComponent.getPath());
|
||||||
|
}
|
||||||
|
return pathBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPathSegments() {
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
for (PathComponent pathComponent : pathComponents) {
|
||||||
|
result.addAll(pathComponent.getPathSegments());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathComponent encode(String encoding) throws UnsupportedEncodingException {
|
||||||
|
List<PathComponent> encodedComponents = new ArrayList<PathComponent>(pathComponents.size());
|
||||||
|
for (PathComponent pathComponent : pathComponents) {
|
||||||
|
encodedComponents.add(pathComponent.encode(encoding));
|
||||||
|
}
|
||||||
|
return new PathComponentComposite(encodedComponents);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathComponent expand(UriTemplateVariables uriVariables) {
|
||||||
|
List<PathComponent> expandedComponents = new ArrayList<PathComponent>(pathComponents.size());
|
||||||
|
for (PathComponent pathComponent : pathComponents) {
|
||||||
|
expandedComponents.add(pathComponent.expand(uriVariables));
|
||||||
|
}
|
||||||
|
return new PathComponentComposite(expandedComponents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an empty path.
|
* Represents an empty path.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -428,20 +428,9 @@ public class UriComponentsBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||||
for (String pathSegment : pathSegments) {
|
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
|
||||||
final boolean pathEndsInSlash = path.length() > 0 && path.charAt(path.length() - 1) == '/';
|
builder.appendPathSegments(pathSegments);
|
||||||
final boolean segmentStartsWithSlash = pathSegment.charAt(0) == '/';
|
return builder;
|
||||||
|
|
||||||
if (path.length() > 0 && !pathEndsInSlash && !segmentStartsWithSlash) {
|
|
||||||
path.append('/');
|
|
||||||
} else if (pathEndsInSlash && segmentStartsWithSlash) {
|
|
||||||
pathSegment = pathSegment.substring(1);
|
|
||||||
if (pathSegment.length() == 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
path.append(pathSegment);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,9 +450,9 @@ public class UriComponentsBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathComponentBuilder appendPath(String path) {
|
public PathComponentBuilder appendPath(String path) {
|
||||||
String[] pathSegments = StringUtils.tokenizeToStringArray(path, "/");
|
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
|
||||||
Collections.addAll(this.pathSegments, pathSegments);
|
builder.appendPath(path);
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||||
|
|
@ -472,6 +461,38 @@ public class UriComponentsBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a builder for a collection of PathComponents.
|
||||||
|
*/
|
||||||
|
private static class PathComponentCompositeBuilder implements PathComponentBuilder {
|
||||||
|
|
||||||
|
private final List<PathComponentBuilder> pathComponentBuilders = new ArrayList<PathComponentBuilder>();
|
||||||
|
|
||||||
|
private PathComponentCompositeBuilder(PathComponentBuilder builder) {
|
||||||
|
pathComponentBuilders.add(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UriComponents.PathComponent build() {
|
||||||
|
List<UriComponents.PathComponent> pathComponents =
|
||||||
|
new ArrayList<UriComponents.PathComponent>(pathComponentBuilders.size());
|
||||||
|
|
||||||
|
for (PathComponentBuilder pathComponentBuilder : pathComponentBuilders) {
|
||||||
|
pathComponents.add(pathComponentBuilder.build());
|
||||||
|
}
|
||||||
|
return new UriComponents.PathComponentComposite(pathComponents);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathComponentBuilder appendPath(String path) {
|
||||||
|
this.pathComponentBuilders.add(new FullPathComponentBuilder(path));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||||
|
this.pathComponentBuilders.add(new PathSegmentComponentBuilder(pathSegments));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a builder for an empty path.
|
* Represents a builder for an empty path.
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,42 @@ public class UriComponentsBuilderTests {
|
||||||
assertEquals(Arrays.asList("foo", "bar"), result.getPathSegments());
|
assertEquals(Arrays.asList("foo", "bar"), result.getPathSegments());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathThenPath() {
|
||||||
|
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar").path("ba/z");
|
||||||
|
UriComponents result = builder.build().encode();
|
||||||
|
|
||||||
|
assertEquals("/foo/barba/z", result.getPath());
|
||||||
|
assertEquals(Arrays.asList("foo", "barba", "z"), result.getPathSegments());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathThenPathSegments() {
|
||||||
|
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar").pathSegment("ba/z");
|
||||||
|
UriComponents result = builder.build().encode();
|
||||||
|
|
||||||
|
assertEquals("/foo/bar/ba%2Fz", result.getPath());
|
||||||
|
assertEquals(Arrays.asList("foo", "bar", "ba%2Fz"), result.getPathSegments());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathSegmentsThenPathSegments() {
|
||||||
|
UriComponentsBuilder builder = UriComponentsBuilder.newInstance().pathSegment("foo").pathSegment("bar");
|
||||||
|
UriComponents result = builder.build();
|
||||||
|
|
||||||
|
assertEquals("/foo/bar", result.getPath());
|
||||||
|
assertEquals(Arrays.asList("foo", "bar"), result.getPathSegments());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathSegmentsThenPath() {
|
||||||
|
UriComponentsBuilder builder = UriComponentsBuilder.newInstance().pathSegment("foo").path("/");
|
||||||
|
UriComponents result = builder.build();
|
||||||
|
|
||||||
|
assertEquals("/foo/", result.getPath());
|
||||||
|
assertEquals(Arrays.asList("foo"), result.getPathSegments());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void queryParams() throws URISyntaxException {
|
public void queryParams() throws URISyntaxException {
|
||||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,12 @@ public class UriComponentsTests {
|
||||||
assertEquals(new URI("http://example.com/hotel%20list/Z\u00fcrich"), uriComponents.toUri());
|
assertEquals(new URI("http://example.com/hotel%20list/Z\u00fcrich"), uriComponents.toUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void expand() {
|
||||||
|
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com").path("/{foo} {bar}").build();
|
||||||
|
uriComponents = uriComponents.expand("1 2", "3 4");
|
||||||
|
assertEquals("/1 2 3 4", uriComponents.getPath());
|
||||||
|
assertEquals("http://example.com/1 2 3 4", uriComponents.toUriString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue