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
|
||||
* @return the expanded uri components
|
||||
*/
|
||||
public UriComponents expand(Map<String, ?> map) {
|
||||
Assert.notNull(map, "'uriVariables' must not be null");
|
||||
public UriComponents expand(Map<String, ?> uriVariables) {
|
||||
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
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>
|
||||
*/
|
||||
public static enum Type {
|
||||
static enum Type {
|
||||
|
||||
SCHEME {
|
||||
@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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -428,20 +428,9 @@ public class UriComponentsBuilder {
|
|||
}
|
||||
|
||||
public PathComponentBuilder appendPathSegments(String... pathSegments) {
|
||||
for (String pathSegment : pathSegments) {
|
||||
final boolean pathEndsInSlash = path.length() > 0 && path.charAt(path.length() - 1) == '/';
|
||||
final boolean segmentStartsWithSlash = pathSegment.charAt(0) == '/';
|
||||
|
||||
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;
|
||||
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
|
||||
builder.appendPathSegments(pathSegments);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,9 +450,9 @@ public class UriComponentsBuilder {
|
|||
}
|
||||
|
||||
public PathComponentBuilder appendPath(String path) {
|
||||
String[] pathSegments = StringUtils.tokenizeToStringArray(path, "/");
|
||||
Collections.addAll(this.pathSegments, pathSegments);
|
||||
return this;
|
||||
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
|
||||
builder.appendPath(path);
|
||||
return builder;
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -138,6 +138,42 @@ public class UriComponentsBuilderTests {
|
|||
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
|
||||
public void queryParams() throws URISyntaxException {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||
|
|
|
|||
|
|
@ -45,5 +45,13 @@ public class UriComponentsTests {
|
|||
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/hotel list/Z\u00fcrich").build();
|
||||
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