Skip to content

Commit abfa46b

Browse files
committed
Implement proper automatic path splitting behaviour when paths are resolved which contain the path splitter.
1 parent 4ad8ded commit abfa46b

File tree

5 files changed

+109
-8
lines changed

5 files changed

+109
-8
lines changed

src/main/java/cpw/mods/niofs/layzip/LayeredZipFileSystemProvider.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class LayeredZipFileSystemProvider extends PathFileSystemProvider
1919
public static final String INDICATOR = "!";
2020
public static final String SEPARATOR = INDICATOR + "/";
2121

22-
public static final String URI_SPLIT_REGEX = "!/";
22+
public static final String URI_SPLIT_REGEX = SEPARATOR;
2323

2424

2525
@Override
@@ -136,4 +136,34 @@ protected URI buildUriFor(final PathPath path) throws URISyntaxException, Illega
136136

137137
return URI.create("%s:%s%s".formatted(SCHEME, prefix, path).replace("%s/".formatted(SEPARATOR), SEPARATOR));
138138
}
139+
140+
@Override
141+
public Path adaptResolvedPath(final PathPath path)
142+
{
143+
if (!path.toString().contains(SEPARATOR))
144+
return path;
145+
146+
final Path workingPath = path.getFileSystem().getPath(path.toString().substring(0, path.toString().lastIndexOf(SEPARATOR)) + SEPARATOR);
147+
final FileSystem workingSystem;
148+
try
149+
{
150+
workingSystem = FileSystems.newFileSystem(workingPath.toUri(), Map.of());
151+
}
152+
catch (IOException e)
153+
{
154+
throw new IllegalArgumentException("Failed to get sub file system for path!", e);
155+
}
156+
157+
return workingSystem.getPath(path.endsWith(SEPARATOR) ? "/" : path.toString().substring(path.toString().lastIndexOf(SEPARATOR) + 2));
158+
}
159+
160+
@Override
161+
public String[] adaptPathParts(final String longstring, final String[] pathParts)
162+
{
163+
if(!longstring.endsWith(SEPARATOR))
164+
return pathParts;
165+
166+
pathParts[pathParts.length - 1] = pathParts[pathParts.length - 1] + "/";
167+
return pathParts;
168+
}
139169
}

src/main/java/cpw/mods/niofs/pathfs/PathFileSystem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public PathFileSystem(final PathFileSystemProvider provider, final String key, f
6262
});
6363
}
6464

65-
String getKey()
65+
public String getKey()
6666
{
6767
return this.key;
6868
}

src/main/java/cpw/mods/niofs/pathfs/PathFileSystemProvider.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,14 @@ protected Path createSubPath(final PathFileSystem pathFileSystem, final String..
215215
{
216216
return new PathPath(pathFileSystem, false, args);
217217
}
218+
219+
public Path adaptResolvedPath(final PathPath path)
220+
{
221+
return path;
222+
}
223+
224+
public String[] adaptPathParts(final String longstring, final String[] pathParts)
225+
{
226+
return pathParts;
227+
}
218228
}

src/main/java/cpw/mods/niofs/pathfs/PathPath.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ protected PathPath(final PathFileSystem fileSystem, final Path innerPath) {
3535
}
3636

3737
private String[] getPathParts(final String longstring) {
38-
return longstring.equals(this.getFileSystem().getSeparator()) ? new String[] {""} : longstring.replace("\\", this.getFileSystem().getSeparator()).split(this.getFileSystem().getSeparator());
38+
final String[] localParts = longstring.equals(this.getFileSystem().getSeparator()) ? new String[] {""} : longstring.replace("\\", this.getFileSystem().getSeparator()).split(this.getFileSystem().getSeparator());
39+
40+
if (this.getFileSystem().provider() != null)
41+
return this.getFileSystem().provider().adaptPathParts(longstring, localParts);
42+
43+
return localParts;
3944
}
4045

4146
@Override
@@ -143,9 +148,9 @@ public Path normalize() {
143148
public Path resolve(final Path other) {
144149
if (other instanceof PathPath path) {
145150
if (path.isAbsolute()) {
146-
return path;
151+
return this.getFileSystem().provider().adaptResolvedPath(path);
147152
}
148-
return new PathPath(this.fileSystem, false, this+fileSystem.getSeparator()+other);
153+
return this.getFileSystem().provider().adaptResolvedPath(new PathPath(this.fileSystem, false, this+fileSystem.getSeparator()+other));
149154
}
150155
return other;
151156
}
@@ -228,6 +233,6 @@ public int hashCode() {
228233

229234
@Override
230235
public String toString() {
231-
return String.join(fileSystem.getSeparator(), this.pathParts);
236+
return String.join(fileSystem.getSeparator(), this.pathParts).replace("//", "/");
232237
}
233238
}

src/test/java/cpw/mods/niofs/layfs/TestLayeredZipFS.java

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
import java.util.HashMap;
1010
import java.util.List;
1111

12-
import static org.junit.jupiter.api.Assertions.assertEquals;
13-
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
12+
import static org.junit.jupiter.api.Assertions.*;
1413

1514
public class TestLayeredZipFS
1615
{
@@ -67,4 +66,61 @@ public void testRelativeUriConversion() throws URISyntaxException, IOException {
6766

6867
assertEquals(expectedUri.toString(), uriInFS.toString());
6968
}
69+
70+
@Test
71+
public void testSplitResolving() throws URISyntaxException, IOException {
72+
final URI filePathUri = new URI(
73+
"jij:src/test/resources/dir_in_dir_in_dir.zip"
74+
).normalize();
75+
final FileSystem zipFS = FileSystems.newFileSystem(filePathUri, new HashMap<>());
76+
77+
final Path rootPathInFs = zipFS.getPath("/");
78+
final Path secondLayerZipPath = rootPathInFs.resolve("/dir_in_dir.zip!/");
79+
final Path thirdLayerZipPath = secondLayerZipPath.resolve("dir1.zip!/");
80+
81+
assertNotEquals(rootPathInFs.getFileSystem(), secondLayerZipPath.getFileSystem());
82+
assertNotEquals(secondLayerZipPath.getFileSystem(), thirdLayerZipPath.getFileSystem());
83+
}
84+
85+
@Test
86+
public void testChainedSplitResolving() throws URISyntaxException, IOException {
87+
final URI filePathUri = new URI(
88+
"jij:src/test/resources/dir_in_dir_in_dir.zip"
89+
).normalize();
90+
final FileSystem zipFS = FileSystems.newFileSystem(filePathUri, new HashMap<>());
91+
92+
final Path rootPathInFs = zipFS.getPath("/");
93+
final Path secondLayerZipPath = rootPathInFs.resolve("/dir_in_dir.zip!/dir1.zip!/");
94+
95+
assertNotEquals(rootPathInFs.getFileSystem(), secondLayerZipPath.getFileSystem());
96+
}
97+
98+
99+
@Test
100+
public void testPathSplitResolving() throws URISyntaxException, IOException {
101+
final URI filePathUri = new URI(
102+
"jij:src/test/resources/dir_in_dir_in_dir.zip"
103+
).normalize();
104+
final FileSystem zipFS = FileSystems.newFileSystem(filePathUri, new HashMap<>());
105+
106+
final Path rootPathInFs = zipFS.getPath("/");
107+
final Path secondLayerZipPath = rootPathInFs.resolve(rootPathInFs.getFileSystem().getPath("/dir_in_dir.zip!/"));
108+
final Path thirdLayerZipPath = secondLayerZipPath.resolve(secondLayerZipPath.getFileSystem().getPath("dir1.zip!/"));
109+
110+
assertNotEquals(rootPathInFs.getFileSystem(), secondLayerZipPath.getFileSystem());
111+
assertNotEquals(secondLayerZipPath.getFileSystem(), thirdLayerZipPath.getFileSystem());
112+
}
113+
114+
@Test
115+
public void testChainedPathSplitResolving() throws URISyntaxException, IOException {
116+
final URI filePathUri = new URI(
117+
"jij:src/test/resources/dir_in_dir_in_dir.zip"
118+
).normalize();
119+
final FileSystem zipFS = FileSystems.newFileSystem(filePathUri, new HashMap<>());
120+
121+
final Path rootPathInFs = zipFS.getPath("/");
122+
final Path secondLayerZipPath = rootPathInFs.resolve(rootPathInFs.getFileSystem().getPath("/dir_in_dir.zip!/dir1.zip!/"));
123+
124+
assertNotEquals(rootPathInFs.getFileSystem(), secondLayerZipPath.getFileSystem());
125+
}
70126
}

0 commit comments

Comments
 (0)