Add unified application path resolver
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package com.example.workutils.system.support;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
/** Resolves every WorkUtils runtime path from one stable application home. */
|
||||
public final class ApplicationPaths {
|
||||
|
||||
public static final String HOME_PROPERTY = "workutils.home";
|
||||
public static final String HOME_ENV = "WORKUTILS_HOME";
|
||||
|
||||
private final Path home;
|
||||
|
||||
private ApplicationPaths(Path home) {
|
||||
this.home = home.toAbsolutePath().normalize();
|
||||
}
|
||||
|
||||
public static ApplicationPaths current() {
|
||||
return resolve(System.getProperty(HOME_PROPERTY), System.getenv(HOME_ENV),
|
||||
System.getProperty("user.dir"));
|
||||
}
|
||||
|
||||
public static ApplicationPaths of(Path home) {
|
||||
if (home == null) {
|
||||
throw new IllegalArgumentException("Application home must not be null");
|
||||
}
|
||||
return new ApplicationPaths(home);
|
||||
}
|
||||
|
||||
static ApplicationPaths resolve(String property, String environment, String userDirectory) {
|
||||
String selected = firstNonBlank(property, environment, userDirectory);
|
||||
if (selected == null) {
|
||||
throw new IllegalStateException("Application home is unavailable");
|
||||
}
|
||||
return new ApplicationPaths(Path.of(selected.trim()));
|
||||
}
|
||||
|
||||
public Path home() {
|
||||
return home;
|
||||
}
|
||||
|
||||
public Path resolve(String first, String... more) {
|
||||
return home.resolve(Path.of(first, more)).normalize();
|
||||
}
|
||||
|
||||
public Path resolveConfigured(String configured, String... fallbackSegments) {
|
||||
Path value;
|
||||
if (configured == null || configured.isBlank()) {
|
||||
if (fallbackSegments.length == 0) {
|
||||
throw new IllegalArgumentException("A fallback path is required");
|
||||
}
|
||||
value = Path.of(fallbackSegments[0],
|
||||
Arrays.copyOfRange(fallbackSegments, 1, fallbackSegments.length));
|
||||
} else {
|
||||
value = Path.of(configured.trim());
|
||||
}
|
||||
return (value.isAbsolute() ? value : home.resolve(value)).normalize();
|
||||
}
|
||||
|
||||
private static String firstNonBlank(String... values) {
|
||||
for (String value : values) {
|
||||
if (value != null && !value.isBlank()) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.example.workutils.system.support;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class ApplicationPathsTest {
|
||||
|
||||
@Test
|
||||
void systemPropertyWinsOverEnvironmentAndWorkingDirectory() {
|
||||
ApplicationPaths paths = ApplicationPaths.resolve(
|
||||
" build/系统 属性 ", "build/环境变量", "build/工作目录");
|
||||
|
||||
assertEquals(Path.of("build", "系统 属性").toAbsolutePath().normalize(), paths.home());
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentWinsWhenSystemPropertyIsBlank() {
|
||||
ApplicationPaths paths = ApplicationPaths.resolve(
|
||||
" ", "build/环境 变量", "build/工作目录");
|
||||
|
||||
assertEquals(Path.of("build", "环境 变量").toAbsolutePath().normalize(), paths.home());
|
||||
}
|
||||
|
||||
@Test
|
||||
void blankOverridesFallBackToWorkingDirectory() {
|
||||
ApplicationPaths paths = ApplicationPaths.resolve(" ", "", "build/工作 目录");
|
||||
|
||||
assertEquals(Path.of("build", "工作 目录").toAbsolutePath().normalize(), paths.home());
|
||||
}
|
||||
|
||||
@Test
|
||||
void missingAllSourcesIsRejected() {
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> ApplicationPaths.resolve(null, " ", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void configuredRelativePathUsesApplicationHome() {
|
||||
ApplicationPaths paths = ApplicationPaths.of(Path.of("build", "运行 根目录"));
|
||||
|
||||
assertEquals(paths.home().resolve(Path.of("data", "plugins.config")),
|
||||
paths.resolveConfigured("data/plugins.config"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void configuredAbsolutePathIsPreserved() {
|
||||
ApplicationPaths paths = ApplicationPaths.of(Path.of("build", "运行 根目录"));
|
||||
Path absolute = Path.of(System.getProperty("java.io.tmpdir"), "绝对 配置").toAbsolutePath().normalize();
|
||||
|
||||
assertEquals(absolute, paths.resolveConfigured(absolute.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fallbackSegmentsAreResolvedWithoutEmbeddedSeparators() {
|
||||
ApplicationPaths paths = ApplicationPaths.of(Path.of("build", "运行 根目录"));
|
||||
|
||||
assertEquals(paths.home().resolve(Path.of("data", "api_base_classes.json")),
|
||||
paths.resolveConfigured(null, "data", "api_base_classes.json"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user