Skip to content

Commit 7a8b74a

Browse files
committed
Merge branch 'OrionDevelopment_main'
2 parents a17945d + abfa46b commit 7a8b74a

14 files changed

Lines changed: 1503 additions & 6 deletions

File tree

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package cpw.mods.niofs.layzip;
2+
3+
import cpw.mods.niofs.pathfs.PathFileSystemProvider;
4+
import cpw.mods.niofs.pathfs.PathPath;
5+
6+
import java.io.IOException;
7+
import java.io.UncheckedIOException;
8+
import java.net.URI;
9+
import java.net.URISyntaxException;
10+
import java.nio.file.FileSystem;
11+
import java.nio.file.FileSystems;
12+
import java.nio.file.Path;
13+
import java.util.Locale;
14+
import java.util.Map;
15+
16+
public class LayeredZipFileSystemProvider extends PathFileSystemProvider
17+
{
18+
public static final String SCHEME = "jij";
19+
public static final String INDICATOR = "!";
20+
public static final String SEPARATOR = INDICATOR + "/";
21+
22+
public static final String URI_SPLIT_REGEX = SEPARATOR;
23+
24+
25+
@Override
26+
public String getScheme() {
27+
return SCHEME;
28+
}
29+
30+
@Override
31+
public FileSystem newFileSystem(final URI uri, final Map<String, ?> env) throws IOException
32+
{
33+
final String[] sections = uri.getRawSchemeSpecificPart().split(URI_SPLIT_REGEX);
34+
FileSystem workingSystem = FileSystems.getDefault(); //Grab the normal disk FS.
35+
36+
String keyPrefix = "";
37+
38+
if (sections.length > 1) {
39+
for (int i = 0; i < sections.length - 1; i++)
40+
{
41+
String section = sections[i];
42+
if (section.startsWith("//"))
43+
section = section.substring(2);
44+
45+
section = handleAbsolutePrefixOnWindows(workingSystem, section);
46+
final Path path = workingSystem.getPath(section).toAbsolutePath();
47+
workingSystem = getOrCreateNewSystem(keyPrefix, path);
48+
keyPrefix += path.toString().replace("\\", "/") + INDICATOR;
49+
}
50+
}
51+
52+
String lastSection = sections[sections.length - 1];
53+
if (lastSection.startsWith("//"))
54+
lastSection = lastSection.substring(2);
55+
56+
57+
final Path lastPath = workingSystem.getPath(lastSection).toAbsolutePath();
58+
return getOrCreateNewSystem(keyPrefix, lastPath);
59+
}
60+
61+
private String handleAbsolutePrefixOnWindows(final FileSystem workingSystem, String section)
62+
{
63+
if (workingSystem.getClass().getName().toLowerCase(Locale.ROOT).contains("windows")) {
64+
//This special casing is needed, since else the rooted paths crash on Windows system because:
65+
// /D:/something is not a valid path on Windows.
66+
//However, the JDK does not expose the Windows FS types and there are no marker classes, so we use the classname.
67+
//Because we are fancy like that.
68+
if (section.startsWith("/"))
69+
section = section.substring(1); //Turns /D:/something into D:/Something which is a valid windows path.
70+
}
71+
return section;
72+
}
73+
74+
private FileSystem getOrCreateNewSystem(final Path path)
75+
{
76+
return getOrCreateNewSystem("", path);
77+
}
78+
79+
private FileSystem getOrCreateNewSystem(String keyPrefix, final Path path)
80+
{
81+
final Map<String, ?> args = Map.of("packagePath", path.toAbsolutePath());
82+
try
83+
{
84+
return super.newFileSystem(new URI(super.getScheme() + ":" + keyPrefix + path.toString().replace("\\", "/")), args);
85+
}
86+
catch (Exception e)
87+
{
88+
throw new UncheckedIOException("Failed to create intermediary FS.", new IOException("Failed to process data.", e));
89+
}
90+
}
91+
92+
@Override
93+
public Path getPath(final URI uri)
94+
{
95+
final String[] sections = uri.getRawSchemeSpecificPart().split("~");
96+
FileSystem workingSystem = FileSystems.getDefault(); //Grab the normal disk FS.
97+
if (sections.length > 1) {
98+
for (int i = 0; i < sections.length - 1; i++)
99+
{
100+
final String section = sections[i];
101+
final Path path = workingSystem.getPath(section);
102+
workingSystem = getOrCreateNewSystem(path);
103+
}
104+
}
105+
106+
final String lastSection = sections[sections.length - 1];
107+
return workingSystem.getPath(lastSection);
108+
}
109+
110+
@Override
111+
public FileSystem getFileSystem(final URI uri)
112+
{
113+
final String[] sections = uri.getRawSchemeSpecificPart().split("~");
114+
FileSystem workingSystem = FileSystems.getDefault(); //Grab the normal disk FS.
115+
if (sections.length > 1) {
116+
for (int i = 0; i < sections.length - 1; i++)
117+
{
118+
final String section = sections[i];
119+
final Path path = workingSystem.getPath(section);
120+
workingSystem = getOrCreateNewSystem(path);
121+
}
122+
}
123+
124+
final String lastSection = sections[sections.length - 1];
125+
final Path lastPath = workingSystem.getPath(lastSection);
126+
return getOrCreateNewSystem(lastPath);
127+
}
128+
129+
@Override
130+
protected URI buildUriFor(final PathPath path) throws URISyntaxException, IllegalArgumentException
131+
{
132+
String prefix = "";
133+
134+
final URI outerUri = path.getFileSystem().getTarget().toUri();
135+
prefix = outerUri.getRawSchemeSpecificPart() + SEPARATOR;
136+
137+
return URI.create("%s:%s%s".formatted(SCHEME, prefix, path).replace("%s/".formatted(SEPARATOR), SEPARATOR));
138+
}
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+
}
169+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cpw.mods.niofs.pathfs;
2+
3+
import java.io.IOException;
4+
import java.nio.file.DirectoryStream;
5+
import java.nio.file.Path;
6+
import java.util.Iterator;
7+
import java.util.function.Function;
8+
9+
class PathFSUtils
10+
{
11+
12+
private PathFSUtils()
13+
{
14+
throw new IllegalStateException("Can not instantiate an instance of: PathFSUtils. This is a utility class");
15+
}
16+
17+
public static final DirectoryStream<Path> NULL_STREAM = new DirectoryStream<>()
18+
{
19+
@Override
20+
public Iterator<Path> iterator()
21+
{
22+
return new Iterator<>()
23+
{
24+
@Override
25+
public boolean hasNext()
26+
{
27+
return false;
28+
}
29+
30+
@Override
31+
public Path next()
32+
{
33+
return null;
34+
}
35+
};
36+
}
37+
38+
@Override
39+
public void close() throws IOException
40+
{
41+
42+
}
43+
};
44+
45+
public static DirectoryStream<Path> adapt(final DirectoryStream<Path> inner, final Function<Path, Path> adapter) {
46+
return new DirectoryStream<Path>() {
47+
@Override
48+
public Iterator<Path> iterator()
49+
{
50+
final Iterator<Path> targetIterator = inner.iterator();
51+
52+
return new Iterator<Path>() {
53+
@Override
54+
public boolean hasNext()
55+
{
56+
return targetIterator.hasNext();
57+
}
58+
59+
@Override
60+
public Path next()
61+
{
62+
final Path targetPath = targetIterator.next();
63+
return adapter.apply(targetPath);
64+
}
65+
};
66+
}
67+
68+
@Override
69+
public void close() throws IOException
70+
{
71+
inner.close();
72+
}
73+
};
74+
}
75+
}

0 commit comments

Comments
 (0)