mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-07-27 09:41:56 +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;
|
return defaultPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
import pro.gravit.launcher.base.vfs.VfsDirectory;
|
import pro.gravit.launcher.base.vfs.VfsDirectory;
|
||||||
import pro.gravit.launcher.base.vfs.directory.OverlayVfsDirectory;
|
import pro.gravit.launcher.base.vfs.directory.OverlayVfsDirectory;
|
||||||
import pro.gravit.launcher.core.backend.LauncherBackendAPI;
|
import pro.gravit.launcher.core.backend.LauncherBackendAPI;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -21,14 +23,23 @@ public ResourceLayerImpl(Path basePath, List<Path> overlayList) {
|
||||||
vfsPath = basePath;
|
vfsPath = basePath;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<VfsDirectory> overlays = Stream.concat(overlayList.stream(), Stream.of(Path.of("")))
|
List<VfsDirectory> overlays = new ArrayList<>();
|
||||||
.map(basePath::resolve)
|
overlays.add((VfsDirectory) Vfs.get().resolve(basePath));
|
||||||
.map(x -> (VfsDirectory) Vfs.get().resolve(x))
|
for(var e : overlayList) {
|
||||||
.filter(Objects::nonNull)
|
var dir = (VfsDirectory) Vfs.get().resolve(basePath.resolve(e));
|
||||||
.toList();
|
if(dir != null) {
|
||||||
|
overlays.add(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
OverlayVfsDirectory directory = new OverlayVfsDirectory(overlays);
|
OverlayVfsDirectory directory = new OverlayVfsDirectory(overlays);
|
||||||
String randomName = SecurityHelper.randomStringToken();
|
String randomName = SecurityHelper.randomStringToken();
|
||||||
vfsPath = Path.of(randomName);
|
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);
|
Vfs.get().put(vfsPath, directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import pro.gravit.launcher.base.vfs.directory.SimpleVfsDirectory;
|
import pro.gravit.launcher.base.vfs.directory.SimpleVfsDirectory;
|
||||||
import pro.gravit.launcher.base.vfs.protocol.vfs.VfsURLStreamHandlerProvider;
|
import pro.gravit.launcher.base.vfs.protocol.vfs.VfsURLStreamHandlerProvider;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
|
|
||||||
public class Vfs {
|
public class Vfs {
|
||||||
private final VfsDirectory directory;
|
private final VfsDirectory directory;
|
||||||
|
private volatile String name;
|
||||||
private static final Map<String, Vfs> map = new HashMap<>();
|
private static final Map<String, Vfs> map = new HashMap<>();
|
||||||
private static final Vfs defaultImpl = new Vfs();
|
private static final Vfs defaultImpl = new Vfs();
|
||||||
static {
|
static {
|
||||||
|
@ -36,8 +38,33 @@ public VfsEntry resolve(Path path) {
|
||||||
return directory.resolve(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) {
|
public void put(Path path, VfsEntry entry) {
|
||||||
VfsEntry parent = resolve(path.getParent());
|
VfsEntry parent = resolve(path.getParent());
|
||||||
|
if(parent == null) {
|
||||||
|
parent = createDirectories(path.getParent());
|
||||||
|
}
|
||||||
if(parent instanceof SimpleVfsDirectory dir) {
|
if(parent instanceof SimpleVfsDirectory dir) {
|
||||||
dir.put(path.getFileName().toString(), entry);
|
dir.put(path.getFileName().toString(), entry);
|
||||||
} else {
|
} 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) {
|
public static void register(String name, Vfs vfs) {
|
||||||
map.put(name, vfs);
|
map.put(name, vfs);
|
||||||
|
vfs.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vfs getByName(String name) {
|
public static Vfs getByName(String name) {
|
||||||
if(name == null) {
|
if(name == null || name.isEmpty()) {
|
||||||
return defaultImpl;
|
return defaultImpl;
|
||||||
}
|
}
|
||||||
return map.get(name);
|
return map.get(name);
|
||||||
|
@ -74,8 +118,8 @@ public URL getURL(String path) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getURL(Path name) throws IOException {
|
public URL getURL(Path name) throws IOException {
|
||||||
try (InputStream stream = defaultImpl.getInputStream(name)) {
|
try (InputStream stream = getInputStream(name)) {
|
||||||
return new URI("vfs", null, "/"+name, null).toURL();
|
return new URI("vfs", this.name, "/"+name, null).toURL();
|
||||||
} catch (UnsupportedOperationException ex) {
|
} catch (UnsupportedOperationException ex) {
|
||||||
throw new FileNotFoundException(name.toString());
|
throw new FileNotFoundException(name.toString());
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ public VfsEntry resolve(Path path) {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VfsEntry remove(String name) {
|
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