From ecc11bd7316373e429475b4efc35c8313352b7e6 Mon Sep 17 00:00:00 2001 From: Marcel Hekman Date: Fri, 18 Jan 2019 11:49:32 +0100 Subject: [PATCH] 3Path: Implement 'normalize()'. --- .../carlspring/cloud/storage/s3fs/S3Path.java | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/carlspring/cloud/storage/s3fs/S3Path.java b/src/main/java/org/carlspring/cloud/storage/s3fs/S3Path.java index 181f9bae..a3989f21 100644 --- a/src/main/java/org/carlspring/cloud/storage/s3fs/S3Path.java +++ b/src/main/java/org/carlspring/cloud/storage/s3fs/S3Path.java @@ -12,9 +12,12 @@ import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.Iterator; import java.util.List; +import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; @@ -433,10 +436,80 @@ public boolean endsWith(String other) return this.endsWith(new S3Path(this.fileSystem, other)); } + // Inspired by "JimfsPath.isNormal()" @Override public Path normalize() { - return this; + List pathParts = uriToList(); + if (isNormal(pathParts)) + return this; + + Deque newPathParts = new ArrayDeque<>(); + for (String pathPart : pathParts) + { + if (pathPart.equals("..")) + { + String lastPathPart = newPathParts.peekLast(); + if (lastPathPart != null && !lastPathPart.equals("..")) + { + newPathParts.removeLast(); + } + else if (!isAbsolute()) + { + // if there's a root and we have an extra ".." that would go + // up above the root, ignore it + newPathParts.add(pathPart); + } + } + else if (!pathPart.equals(".")) + { + newPathParts.add(pathPart); + } + } + StringBuilder pathBuilder = new StringBuilder(); + if (this.isAbsolute()) + { + pathBuilder.append(PATH_SEPARATOR).append(this.fileStore.name()).append(PATH_SEPARATOR); + } + pathBuilder.append(Joiner.on(PATH_SEPARATOR).join(newPathParts)); + if (newPathParts.size() > 0 && uri.endsWith(PATH_SEPARATOR)) + { + pathBuilder.append(PATH_SEPARATOR); + } + return new S3Path(this.fileSystem, pathBuilder.toString()); + } + + // Inspired by "JimfsPath.isNormal()" + private boolean isNormal(List pathParts) + { + if (getNameCount() == 0 || getNameCount() == 1 && !isAbsolute()) + { + return true; + } + boolean foundNonParentName = isAbsolute(); // if there's a root, the + // path doesn't start with .. + boolean normal = true; + for (String pathPart : pathParts) + { + if (pathPart.equals("..")) + { + if (foundNonParentName) + { + normal = false; + break; + } + } + else + { + if (pathPart.equals(".")) + { + normal = false; + break; + } + foundNonParentName = true; + } + } + return normal; } @Override