mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-10-26 14:00:14 +00:00
Merge pull request #560 from everbuild-org/feat/extend-search-path
feat: add extensible registry interface and integrate into config and meta-config registries
This commit is contained in:
3 files changed
+120
-5
No files matched your search
+93
@@ -0,0 +1,93 @@
|
|||||||
|
package com.dfsek.terra.registry;
|
||||||
|
|
||||||
|
import com.google.errorprone.annotations.MustBeClosed;
|
||||||
|
import org.intellij.lang.annotations.Pattern;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file-discoverable registry that can be extended by system properties
|
||||||
|
* <br>
|
||||||
|
* The main use-case for this is to allow for customized locations of file-system-based key entries,
|
||||||
|
* such as putting config packs into custom locations.
|
||||||
|
* <br>
|
||||||
|
* Two system properties are used to define the search path:
|
||||||
|
* <br>
|
||||||
|
* <code>terra.registry.{searchPathName}.searchPath</code> is a list of "parent folder" paths (like the pack directory) that
|
||||||
|
* will be searched for contained files.
|
||||||
|
* <br>
|
||||||
|
* <code>terra.registry.{searchPathName}.extraPath</code> is a list of files that will be directly evaluated for membership and
|
||||||
|
* as such will be directly treated as members of the registry.
|
||||||
|
* <br>
|
||||||
|
* These system properties are formatted like UNIX-style paths, with each path separated by a colon (':') character.
|
||||||
|
*/
|
||||||
|
public interface ExtensibleRegistry {
|
||||||
|
/**
|
||||||
|
* Get a lowercase search path name for this registry that will get plugged into
|
||||||
|
* <br>
|
||||||
|
* <code>terra.registry.{searchPathName}.searchPath</code>
|
||||||
|
* <br>
|
||||||
|
* and
|
||||||
|
* <br>
|
||||||
|
* <code>terra.registry.{searchPathName}.extraPath</code>
|
||||||
|
*/
|
||||||
|
@Pattern("^[a-z._]+$")
|
||||||
|
String getRegistryName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a path may be a member of this registry heuristically.
|
||||||
|
*
|
||||||
|
* @param path Path to check
|
||||||
|
*
|
||||||
|
* @return True if the path is a member of this registry.
|
||||||
|
*/
|
||||||
|
boolean validatePathIsMember(Path path);
|
||||||
|
|
||||||
|
default @MustBeClosed Stream<Path> getMemberPaths(Path baseSearchPath) {
|
||||||
|
String basePropertyName = "terra.registry." + getRegistryName();
|
||||||
|
|
||||||
|
Stream<Path> searchPath = Stream.concat(
|
||||||
|
parseValidPaths(System.getProperty(basePropertyName + ".search-path")),
|
||||||
|
Stream.of(baseSearchPath)
|
||||||
|
);
|
||||||
|
|
||||||
|
Stream<Path> extraPath = parseValidPaths(System.getProperty(basePropertyName + ".extra-path"));
|
||||||
|
|
||||||
|
return Stream.concat(
|
||||||
|
searchPath
|
||||||
|
.filter(Files::isDirectory)
|
||||||
|
.flatMap(ExtensibleRegistry::listDirectory),
|
||||||
|
extraPath
|
||||||
|
)
|
||||||
|
.filter(this::validatePathIsMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Path> parseValidPaths(@Nullable String paths) {
|
||||||
|
return Stream.ofNullable(paths)
|
||||||
|
.flatMap(p -> Arrays.stream(p.split(":")))
|
||||||
|
.filter(v -> !v.isBlank())
|
||||||
|
.map(v -> {
|
||||||
|
try {
|
||||||
|
return Path.of(v).toAbsolutePath().normalize();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Path> listDirectory(Path dir) {
|
||||||
|
try {
|
||||||
|
return Files.list(dir);
|
||||||
|
} catch(IOException e) {
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-2
@@ -29,13 +29,14 @@ import com.dfsek.terra.api.Platform;
|
|||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
import com.dfsek.terra.config.pack.ConfigPackImpl;
|
import com.dfsek.terra.config.pack.ConfigPackImpl;
|
||||||
|
import com.dfsek.terra.registry.ExtensibleRegistry;
|
||||||
import com.dfsek.terra.registry.OpenRegistryImpl;
|
import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to hold config packs
|
* Class to hold config packs
|
||||||
*/
|
*/
|
||||||
public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
|
public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> implements ExtensibleRegistry {
|
||||||
|
|
||||||
public ConfigRegistry() {
|
public ConfigRegistry() {
|
||||||
super(TypeKey.of(ConfigPack.class));
|
super(TypeKey.of(ConfigPack.class));
|
||||||
@@ -45,7 +46,7 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
|
|||||||
Path packsDirectory = platform.getDataFolder().toPath().resolve("packs");
|
Path packsDirectory = platform.getDataFolder().toPath().resolve("packs");
|
||||||
Files.createDirectories(packsDirectory);
|
Files.createDirectories(packsDirectory);
|
||||||
List<Exception> failedLoads = new CopyOnWriteArrayList<>();
|
List<Exception> failedLoads = new CopyOnWriteArrayList<>();
|
||||||
try(Stream<Path> packs = Files.list(packsDirectory)) {
|
try(Stream<Path> packs = getMemberPaths(packsDirectory)) {
|
||||||
packs.parallel().forEach(path -> {
|
packs.parallel().forEach(path -> {
|
||||||
try {
|
try {
|
||||||
ConfigPack pack = new ConfigPackImpl(path, platform);
|
ConfigPack pack = new ConfigPackImpl(path, platform);
|
||||||
@@ -60,6 +61,16 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRegistryName() {
|
||||||
|
return "config";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validatePathIsMember(Path path) {
|
||||||
|
return Files.isDirectory(path)|| path.getFileName().endsWith(".zip");
|
||||||
|
}
|
||||||
|
|
||||||
public static class PackLoadFailuresException extends Exception {
|
public static class PackLoadFailuresException extends Exception {
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 538998844645186306L;
|
private static final long serialVersionUID = 538998844645186306L;
|
||||||
|
|||||||
+14
-3
@@ -28,6 +28,7 @@ import com.dfsek.terra.api.Platform;
|
|||||||
import com.dfsek.terra.api.config.MetaPack;
|
import com.dfsek.terra.api.config.MetaPack;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
import com.dfsek.terra.config.pack.MetaPackImpl;
|
import com.dfsek.terra.config.pack.MetaPackImpl;
|
||||||
|
import com.dfsek.terra.registry.ExtensibleRegistry;
|
||||||
import com.dfsek.terra.registry.OpenRegistryImpl;
|
import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||||
import com.dfsek.terra.registry.master.ConfigRegistry.PackLoadFailuresException;
|
import com.dfsek.terra.registry.master.ConfigRegistry.PackLoadFailuresException;
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ import com.dfsek.terra.registry.master.ConfigRegistry.PackLoadFailuresException;
|
|||||||
/**
|
/**
|
||||||
* Class to hold config packs
|
* Class to hold config packs
|
||||||
*/
|
*/
|
||||||
public class MetaConfigRegistry extends OpenRegistryImpl<MetaPack> {
|
public class MetaConfigRegistry extends OpenRegistryImpl<MetaPack> implements ExtensibleRegistry {
|
||||||
|
|
||||||
public MetaConfigRegistry() {
|
public MetaConfigRegistry() {
|
||||||
super(TypeKey.of(MetaPack.class));
|
super(TypeKey.of(MetaPack.class));
|
||||||
@@ -45,8 +46,8 @@ public class MetaConfigRegistry extends OpenRegistryImpl<MetaPack> {
|
|||||||
Path packsDirectory = platform.getDataFolder().toPath().resolve("metapacks");
|
Path packsDirectory = platform.getDataFolder().toPath().resolve("metapacks");
|
||||||
Files.createDirectories(packsDirectory);
|
Files.createDirectories(packsDirectory);
|
||||||
List<IOException> failedLoads = new ArrayList<>();
|
List<IOException> failedLoads = new ArrayList<>();
|
||||||
try(Stream<Path> packs = Files.list(packsDirectory)) {
|
try(Stream<Path> paths = getMemberPaths(packsDirectory)) {
|
||||||
packs.forEach(path -> {
|
paths.forEach(path -> {
|
||||||
try {
|
try {
|
||||||
MetaPack pack = new MetaPackImpl(path, platform, configRegistry);
|
MetaPack pack = new MetaPackImpl(path, platform, configRegistry);
|
||||||
registerChecked(pack.getRegistryKey(), pack);
|
registerChecked(pack.getRegistryKey(), pack);
|
||||||
@@ -59,4 +60,14 @@ public class MetaConfigRegistry extends OpenRegistryImpl<MetaPack> {
|
|||||||
throw new PackLoadFailuresException(failedLoads);
|
throw new PackLoadFailuresException(failedLoads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRegistryName() {
|
||||||
|
return "metaconfig";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validatePathIsMember(Path path) {
|
||||||
|
return Files.isDirectory(path) || path.getFileName().endsWith(".zip");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user