Browse Source

SPR-5973: now dealing with path followed by segments (and vice-versa) correctly.

pull/7/head
Arjen Poutsma 13 years ago
parent
commit
aeba9d244a
  1. 54
      org.springframework.web/src/main/java/org/springframework/web/util/UriComponents.java
  2. 53
      org.springframework.web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java
  3. 36
      org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java
  4. 8
      org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsTests.java

54
org.springframework.web/src/main/java/org/springframework/web/util/UriComponents.java

@ -316,10 +316,10 @@ public final class UriComponents { @@ -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 { @@ -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 { @@ -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.
*/

53
org.springframework.web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

@ -428,20 +428,9 @@ public class UriComponentsBuilder { @@ -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,13 +450,45 @@ public class UriComponentsBuilder { @@ -461,13 +450,45 @@ public class UriComponentsBuilder {
}
public PathComponentBuilder appendPath(String path) {
String[] pathSegments = StringUtils.tokenizeToStringArray(path, "/");
PathComponentCompositeBuilder builder = new PathComponentCompositeBuilder(this);
builder.appendPath(path);
return builder;
}
public PathComponentBuilder appendPathSegments(String... pathSegments) {
Collections.addAll(this.pathSegments, pathSegments);
return this;
}
}
/**
* 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) {
Collections.addAll(this.pathSegments, pathSegments);
this.pathComponentBuilders.add(new PathSegmentComponentBuilder(pathSegments));
return this;
}
}

36
org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java

@ -138,6 +138,42 @@ public class UriComponentsBuilderTests { @@ -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();

8
org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsTests.java

@ -45,5 +45,13 @@ public class UriComponentsTests { @@ -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…
Cancel
Save