Add PathSegmentContainer subPath extracting method
This commit is contained in:
parent
1018bf771b
commit
97917aa57d
|
@ -19,6 +19,7 @@ import java.nio.charset.Charset;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
@ -56,7 +57,7 @@ class DefaultPathSegmentContainer implements PathSegmentContainer {
|
|||
private final boolean trailingSlash;
|
||||
|
||||
|
||||
DefaultPathSegmentContainer(String path, List<PathSegment> segments) {
|
||||
private DefaultPathSegmentContainer(String path, List<PathSegment> segments) {
|
||||
this.path = path;
|
||||
this.absolute = path.startsWith("/");
|
||||
this.pathSegments = Collections.unmodifiableList(segments);
|
||||
|
@ -188,6 +189,21 @@ class DefaultPathSegmentContainer implements PathSegmentContainer {
|
|||
}
|
||||
}
|
||||
|
||||
static PathSegmentContainer subPath(PathSegmentContainer container, int fromIndex, int toIndex) {
|
||||
List<PathSegment> segments = container.pathSegments();
|
||||
if (fromIndex == 0 && toIndex == segments.size()) {
|
||||
return container;
|
||||
}
|
||||
Assert.isTrue(fromIndex < toIndex, "fromIndex: " + fromIndex + " should be < toIndex " + toIndex);
|
||||
Assert.isTrue(fromIndex >= 0 && fromIndex < segments.size(), "Invalid fromIndex: " + fromIndex);
|
||||
Assert.isTrue(toIndex >= 0 && toIndex <= segments.size(), "Invalid toIndex: " + toIndex);
|
||||
|
||||
List<PathSegment> subList = segments.subList(fromIndex, toIndex);
|
||||
String prefix = fromIndex > 0 || container.isAbsolute() ? "/" : "";
|
||||
String suffix = toIndex == segments.size() && container.hasTrailingSlash() ? "/" : "";
|
||||
String path = subList.stream().map(PathSegment::value).collect(Collectors.joining(prefix, "/", suffix));
|
||||
return new DefaultPathSegmentContainer(path, subList);
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultPathSegment implements PathSegment {
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.springframework.http.server.reactive;
|
|||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
@ -41,16 +40,15 @@ class DefaultRequestPath implements RequestPath {
|
|||
DefaultRequestPath(URI uri, String contextPath, Charset charset) {
|
||||
this.fullPath = PathSegmentContainer.parse(uri.getRawPath(), charset);
|
||||
this.contextPath = initContextPath(this.fullPath, contextPath);
|
||||
this.pathWithinApplication = initPathWithinApplication(this.fullPath, this.contextPath);
|
||||
this.pathWithinApplication = extractPathWithinApplication(this.fullPath, this.contextPath);
|
||||
}
|
||||
|
||||
DefaultRequestPath(RequestPath requestPath, String contextPath) {
|
||||
this.fullPath = requestPath;
|
||||
this.contextPath = initContextPath(this.fullPath, contextPath);
|
||||
this.pathWithinApplication = initPathWithinApplication(this.fullPath, this.contextPath);
|
||||
this.pathWithinApplication = extractPathWithinApplication(this.fullPath, this.contextPath);
|
||||
}
|
||||
|
||||
|
||||
private static PathSegmentContainer initContextPath(PathSegmentContainer path, String contextPath) {
|
||||
if (!StringUtils.hasText(contextPath) || "/".equals(contextPath)) {
|
||||
return DefaultPathSegmentContainer.EMPTY_PATH;
|
||||
|
@ -62,14 +60,13 @@ class DefaultRequestPath implements RequestPath {
|
|||
int length = contextPath.length();
|
||||
int counter = 0;
|
||||
|
||||
List<PathSegment> result = new ArrayList<>();
|
||||
for (PathSegment pathSegment : path.pathSegments()) {
|
||||
result.add(pathSegment);
|
||||
counter += 1; // for '/' separators
|
||||
for (int i=0; i < path.pathSegments().size(); i++) {
|
||||
PathSegment pathSegment = path.pathSegments().get(i);
|
||||
counter += 1; // for slash separators
|
||||
counter += pathSegment.value().length();
|
||||
counter += pathSegment.semicolonContent().length();
|
||||
if (length == counter) {
|
||||
return new DefaultPathSegmentContainer(contextPath, result);
|
||||
return DefaultPathSegmentContainer.subPath(path, 0, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,13 +75,10 @@ class DefaultRequestPath implements RequestPath {
|
|||
" given path='" + path.value() + "'");
|
||||
}
|
||||
|
||||
private static PathSegmentContainer initPathWithinApplication(PathSegmentContainer path,
|
||||
private static PathSegmentContainer extractPathWithinApplication(PathSegmentContainer fullPath,
|
||||
PathSegmentContainer contextPath) {
|
||||
|
||||
String value = path.value().substring(contextPath.value().length());
|
||||
List<PathSegment> pathSegments = new ArrayList<>(path.pathSegments());
|
||||
pathSegments.removeAll(contextPath.pathSegments());
|
||||
return new DefaultPathSegmentContainer(value, pathSegments);
|
||||
return PathSegmentContainer.subPath(fullPath, contextPath.pathSegments().size());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -67,4 +67,14 @@ public interface PathSegmentContainer {
|
|||
return DefaultPathSegmentContainer.parsePath(path, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a sub-path starting at the given offset into the path segment list.
|
||||
* @param path the path to extract from
|
||||
* @param pathSegmentIndex the start index (inclusive)
|
||||
* @return the sub-path
|
||||
*/
|
||||
static PathSegmentContainer subPath(PathSegmentContainer path, int pathSegmentIndex) {
|
||||
return DefaultPathSegmentContainer.subPath(path, pathSegmentIndex, path.pathSegments().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.springframework.util.MultiValueMap;
|
|||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultPathSegmentContainer}.
|
||||
|
@ -121,4 +122,17 @@ public class DefaultPathSegmentContainerTests {
|
|||
assertEquals("hasTrailingSlash: '" + input + "'", trailingSlash, path.hasTrailingSlash());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subPath() throws Exception {
|
||||
// basic
|
||||
PathSegmentContainer path = PathSegmentContainer.parse("/a/b/c", UTF_8);
|
||||
assertSame(path, PathSegmentContainer.subPath(path, 0));
|
||||
assertEquals("/b/c", PathSegmentContainer.subPath(path, 1).value());
|
||||
assertEquals("/c", PathSegmentContainer.subPath(path, 2).value());
|
||||
|
||||
// trailing slash
|
||||
path = PathSegmentContainer.parse("/a/b/", UTF_8);
|
||||
assertEquals("/b/", PathSegmentContainer.subPath(path, 1).value());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue