mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-07-27 01:31:55 +03:00
[FIX] Vfs bug fixes
This commit is contained in:
parent
9d3b3031cc
commit
2c74375bd3
5 changed files with 123 additions and 9 deletions
|
@ -415,6 +415,9 @@ public Path initVfsDirectory() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(LogHelper.isDevEnabled()) {
|
||||
Vfs.get().debugPrint(LogHelper.Level.DEV);
|
||||
}
|
||||
return defaultPath;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
import pro.gravit.launcher.base.vfs.VfsDirectory;
|
||||
import pro.gravit.launcher.base.vfs.directory.OverlayVfsDirectory;
|
||||
import pro.gravit.launcher.core.backend.LauncherBackendAPI;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -21,14 +23,23 @@ public ResourceLayerImpl(Path basePath, List<Path> overlayList) {
|
|||
vfsPath = basePath;
|
||||
return;
|
||||
}
|
||||
List<VfsDirectory> overlays = Stream.concat(overlayList.stream(), Stream.of(Path.of("")))
|
||||
.map(basePath::resolve)
|
||||
.map(x -> (VfsDirectory) Vfs.get().resolve(x))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
List<VfsDirectory> overlays = new ArrayList<>();
|
||||
overlays.add((VfsDirectory) Vfs.get().resolve(basePath));
|
||||
for(var e : overlayList) {
|
||||
var dir = (VfsDirectory) Vfs.get().resolve(basePath.resolve(e));
|
||||
if(dir != null) {
|
||||
overlays.add(dir);
|
||||
}
|
||||
}
|
||||
OverlayVfsDirectory directory = new OverlayVfsDirectory(overlays);
|
||||
String randomName = SecurityHelper.randomStringToken();
|
||||
vfsPath = Path.of(randomName);
|
||||
if(LogHelper.isDevEnabled()) {
|
||||
LogHelper.dev("Make overlay %s from %s", vfsPath, basePath);
|
||||
for(var e : overlays) {
|
||||
LogHelper.dev("Layer %s", e.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
Vfs.get().put(vfsPath, directory);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import pro.gravit.launcher.base.vfs.directory.SimpleVfsDirectory;
|
||||
import pro.gravit.launcher.base.vfs.protocol.vfs.VfsURLStreamHandlerProvider;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
@ -17,6 +18,7 @@
|
|||
|
||||
public class Vfs {
|
||||
private final VfsDirectory directory;
|
||||
private volatile String name;
|
||||
private static final Map<String, Vfs> map = new HashMap<>();
|
||||
private static final Vfs defaultImpl = new Vfs();
|
||||
static {
|
||||
|
@ -36,8 +38,33 @@ public VfsEntry resolve(Path path) {
|
|||
return directory.resolve(path);
|
||||
}
|
||||
|
||||
public VfsEntry createDirectories(Path path) {
|
||||
VfsDirectory current = directory;
|
||||
for(int i=0;i<path.getNameCount();++i) {
|
||||
String s = path.getName(i).toString();
|
||||
var value = current.find(s);
|
||||
if(value == null) {
|
||||
value = new SimpleVfsDirectory();
|
||||
if(current instanceof SimpleVfsDirectory simpleVfsDirectory) {
|
||||
simpleVfsDirectory.put(s, value);
|
||||
} else {
|
||||
throw new VfsException(String.format("%s not support add new files", path.getParent()));
|
||||
}
|
||||
}
|
||||
if(value instanceof VfsDirectory vfsDirectory) {
|
||||
current = vfsDirectory;
|
||||
} else {
|
||||
throw new VfsException(String.format("%s not a directory", path.getParent()));
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
public void put(Path path, VfsEntry entry) {
|
||||
VfsEntry parent = resolve(path.getParent());
|
||||
if(parent == null) {
|
||||
parent = createDirectories(path.getParent());
|
||||
}
|
||||
if(parent instanceof SimpleVfsDirectory dir) {
|
||||
dir.put(path.getFileName().toString(), entry);
|
||||
} else {
|
||||
|
@ -45,12 +72,29 @@ public void put(Path path, VfsEntry entry) {
|
|||
}
|
||||
}
|
||||
|
||||
public void debugPrint(LogHelper.Level level) {
|
||||
debugPrint(level, directory, Path.of(""));
|
||||
}
|
||||
|
||||
private void debugPrint(LogHelper.Level level, VfsDirectory vfsDirectory, Path path) {
|
||||
try(var stream = vfsDirectory.getFiles()) {
|
||||
for(var e : stream.toList()) {
|
||||
VfsEntry entry = vfsDirectory.find(e);
|
||||
LogHelper.log(level, String.format("%s - %s", path.resolve(e), entry.getClass().getSimpleName()), false);
|
||||
if(entry instanceof VfsDirectory nextDirectory) {
|
||||
debugPrint(level, nextDirectory, path.resolve(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void register(String name, Vfs vfs) {
|
||||
map.put(name, vfs);
|
||||
vfs.name = name;
|
||||
}
|
||||
|
||||
public static Vfs getByName(String name) {
|
||||
if(name == null) {
|
||||
if(name == null || name.isEmpty()) {
|
||||
return defaultImpl;
|
||||
}
|
||||
return map.get(name);
|
||||
|
@ -74,8 +118,8 @@ public URL getURL(String path) throws IOException {
|
|||
}
|
||||
|
||||
public URL getURL(Path name) throws IOException {
|
||||
try (InputStream stream = defaultImpl.getInputStream(name)) {
|
||||
return new URI("vfs", null, "/"+name, null).toURL();
|
||||
try (InputStream stream = getInputStream(name)) {
|
||||
return new URI("vfs", this.name, "/"+name, null).toURL();
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
throw new FileNotFoundException(name.toString());
|
||||
} catch (URISyntaxException e) {
|
||||
|
|
|
@ -40,7 +40,7 @@ public VfsEntry resolve(Path path) {
|
|||
return entity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return current;
|
||||
}
|
||||
|
||||
public VfsEntry remove(String name) {
|
||||
|
|
56
LauncherAPI/src/test/java/pro/gravit/launcher/VfsTest.java
Normal file
56
LauncherAPI/src/test/java/pro/gravit/launcher/VfsTest.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package pro.gravit.launcher;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import pro.gravit.launcher.base.vfs.Vfs;
|
||||
import pro.gravit.launcher.base.vfs.VfsDirectory;
|
||||
import pro.gravit.launcher.base.vfs.VfsEntry;
|
||||
import pro.gravit.launcher.base.vfs.directory.OverlayVfsDirectory;
|
||||
import pro.gravit.launcher.base.vfs.file.UrlVfsFile;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class VfsTest {
|
||||
@Test
|
||||
public void testVfs() throws Exception {
|
||||
List<Path> paths = List.of(
|
||||
Path.of("test/testfile.txt"),
|
||||
Path.of("test/dir/testfile2.txt")
|
||||
);
|
||||
Map<Path, VfsEntry> testPaths = new HashMap<>();
|
||||
for(var path : paths) {
|
||||
var file = new UrlVfsFile(URI.create("https://example.com").toURL());
|
||||
Vfs.get().put(path, file);
|
||||
testPaths.put(path, file);
|
||||
}
|
||||
for(var path : testPaths.entrySet()) {
|
||||
Assertions.assertSame(Vfs.get().resolve(path.getKey()), path.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVfsWithOverlay() throws Exception {
|
||||
List<Path> paths = List.of(
|
||||
Path.of("test/testfile.txt"),
|
||||
Path.of("test/dir/testfile2.txt")
|
||||
);
|
||||
Path prefix = Path.of("base");
|
||||
Map<Path, VfsEntry> testPaths = new HashMap<>();
|
||||
for(var path : paths) {
|
||||
var file = new UrlVfsFile(URI.create("https://example.com").toURL());
|
||||
Vfs.get().put(prefix.resolve(path), file);
|
||||
testPaths.put(path, file);
|
||||
}
|
||||
Path overlayPrefix = Path.of("oveerlay");
|
||||
OverlayVfsDirectory vfsDirectory = new OverlayVfsDirectory(List.of((VfsDirectory) Vfs.get().resolve(prefix)));
|
||||
Vfs.get().put(overlayPrefix, vfsDirectory);
|
||||
for(var path : testPaths.entrySet()) {
|
||||
Assertions.assertSame(Vfs.get().resolve(overlayPrefix.resolve(path.getKey())), path.getValue());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue