From 73bb8cf76ec355e829944ca80afd493e4786ba30 Mon Sep 17 00:00:00 2001 From: crschnick Date: Tue, 4 Mar 2025 17:41:01 +0000 Subject: [PATCH] Rework --- .../app/storage/ContextualFileReference.java | 65 +++++++------------ .../app/terminal/WindowsTerminalType.java | 2 +- .../java/io/xpipe/app/util/RdpConfig.java | 5 +- .../io/xpipe/core/process/CommandBuilder.java | 2 +- .../java/io/xpipe/core/store/FilePath.java | 8 +++ .../base/identity/SshIdentityStrategy.java | 12 ++-- .../identity/SshIdentityStrategyHelper.java | 4 +- .../identity/SyncedIdentityStoreProvider.java | 4 +- 8 files changed, 45 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/storage/ContextualFileReference.java b/app/src/main/java/io/xpipe/app/storage/ContextualFileReference.java index f58ed0f74..b69cc9c46 100644 --- a/app/src/main/java/io/xpipe/app/storage/ContextualFileReference.java +++ b/app/src/main/java/io/xpipe/app/storage/ContextualFileReference.java @@ -19,42 +19,21 @@ import java.util.regex.Matcher; @Value public class ContextualFileReference { - private static String lastDataDir; + private static FilePath lastDataDir; @NonNull String path; - private static String getDataDir() { + private static FilePath getDataDir() { if (DataStorage.get() == null) { - return lastDataDir != null ? lastDataDir : normalized(AppPrefs.DEFAULT_STORAGE_DIR.resolve("data")); + return lastDataDir != null ? lastDataDir : new FilePath(AppPrefs.DEFAULT_STORAGE_DIR.resolve("data")).toUnix(); } - return lastDataDir = normalized(DataStorage.get().getDataDir()); + return lastDataDir = new FilePath(DataStorage.get().getDataDir()).toUnix(); } - private static String normalized(Path p) { - return p.normalize().toString().replaceAll("\\\\", "/"); - } - - private static String normalized(String s) { - try { - return Path.of(s).normalize().toString().replaceAll("\\\\", "/"); - } catch (InvalidPathException ex) { - return s; - } - } - - public static Optional parseIfInDataDirectory(String s) { - var cf = of(s); - if (cf.serialize().contains("")) { - return Optional.of(cf); - } else { - return Optional.empty(); - } - } - - public static Optional resolveIfInDataDirectory(ShellControl shellControl, String s) { - if (s.contains("")) { + public static Optional resolveIfInDataDirectory(ShellControl shellControl, String s) { + if (s.startsWith("")) { var cf = of(s); return Optional.of(cf.toAbsoluteFilePath(shellControl)); } else { @@ -63,30 +42,30 @@ public class ContextualFileReference { } public static ContextualFileReference of(FilePath p) { - return of(p != null ? p.toString() : null); - } - - public static ContextualFileReference of(String s) { - if (s == null) { + if (p == null) { return null; } - var ns = normalized(s.trim()); + var ns = p.normalize().toUnix(); + var home = new FilePath(System.getProperty("user.home")).normalize().toUnix(); String replaced; - var withHomeResolved = ns.replace("~", normalized(System.getProperty("user.home"))); + var withHomeResolved = ns.toString().replace("~", home.toString()); // Only replace ~ if it is part of data dir, otherwise keep it raw - if (withHomeResolved.startsWith(getDataDir())) { - replaced = withHomeResolved.replace("", getDataDir()); + if (withHomeResolved.startsWith(getDataDir().toString())) { + replaced = withHomeResolved.replace("", getDataDir().toString()); } else { - replaced = ns.replace("", getDataDir()); + replaced = ns.toString().replace("", getDataDir().toString()); } - return new ContextualFileReference(normalized(replaced)); + return new ContextualFileReference(replaced); } - public String toAbsoluteFilePath(ShellControl sc) { - return path.replaceAll( - "/", Matcher.quoteReplacement(sc != null ? sc.getOsType().getFileSystemSeparator() : "/")); + public static ContextualFileReference of(String s) { + return of(s != null ? new FilePath(s) : null); + } + + public FilePath toAbsoluteFilePath(ShellControl sc) { + return new FilePath(path.replaceAll("/", Matcher.quoteReplacement(sc != null ? sc.getOsType().getFileSystemSeparator() : "/"))); } public boolean isInDataDirectory() { @@ -95,9 +74,9 @@ public class ContextualFileReference { public String serialize() { var start = getDataDir(); - var normalizedPath = normalized(path); + var normalizedPath = new FilePath(path).normalize().toUnix(); if (normalizedPath.startsWith(start) && !normalizedPath.equals(start)) { - return "" + "/" + FileNames.relativize(start, normalizedPath); + return "" + "/" + start.relativize(normalizedPath); } return path; } diff --git a/app/src/main/java/io/xpipe/app/terminal/WindowsTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/WindowsTerminalType.java index 8d79730ea..f005c36cb 100644 --- a/app/src/main/java/io/xpipe/app/terminal/WindowsTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/WindowsTerminalType.java @@ -59,7 +59,7 @@ public interface WindowsTerminalType extends ExternalTerminalType, TrackableTerm var script = ScriptHelper.createExecScript( shellControl, configuration.getDialectLaunchCommand().buildFull(shellControl)); - return script.toString(); + return script; }); } } else { diff --git a/app/src/main/java/io/xpipe/app/util/RdpConfig.java b/app/src/main/java/io/xpipe/app/util/RdpConfig.java index 4e5d87ed3..ec6f46300 100644 --- a/app/src/main/java/io/xpipe/app/util/RdpConfig.java +++ b/app/src/main/java/io/xpipe/app/util/RdpConfig.java @@ -1,6 +1,7 @@ package io.xpipe.app.util; import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.core.store.FilePath; import io.xpipe.core.util.StreamCharset; import lombok.Value; @@ -20,9 +21,9 @@ public class RdpConfig { Map content; - public static RdpConfig parseFile(String file) throws Exception { + public static RdpConfig parseFile(FilePath file) throws Exception { try (var in = new BufferedReader( - StreamCharset.detectedReader(new BufferedInputStream(Files.newInputStream(Path.of(file)))))) { + StreamCharset.detectedReader(new BufferedInputStream(Files.newInputStream(Path.of(file.toString())))))) { var content = in.lines().collect(Collectors.joining("\n")); return parseContent(content); } catch (NoSuchFileException e) { diff --git a/core/src/main/java/io/xpipe/core/process/CommandBuilder.java b/core/src/main/java/io/xpipe/core/process/CommandBuilder.java index e6766c322..88848f57d 100644 --- a/core/src/main/java/io/xpipe/core/process/CommandBuilder.java +++ b/core/src/main/java/io/xpipe/core/process/CommandBuilder.java @@ -181,7 +181,7 @@ public class CommandBuilder { return prepend("\"" + s + "\""); } - public CommandBuilder addFile(FailableFunction f) { + public CommandBuilder addFile(FailableFunction f) { elements.add(sc -> { if (f == null) { return null; diff --git a/core/src/main/java/io/xpipe/core/store/FilePath.java b/core/src/main/java/io/xpipe/core/store/FilePath.java index 79c5abab2..16be24307 100644 --- a/core/src/main/java/io/xpipe/core/store/FilePath.java +++ b/core/src/main/java/io/xpipe/core/store/FilePath.java @@ -174,6 +174,10 @@ public final class FilePath { return new FilePath(value.substring(0, value.length() - getFileName().length() - 1)); } + public boolean startsWith(String start) { + return startsWith(new FilePath(start)); + } + public boolean startsWith(FilePath start) { return normalize().startsWith(start.normalize()); } @@ -189,6 +193,10 @@ public final class FilePath { return backslash ? toWindows() : toUnix(); } + public FilePath resolveTildeHome(String dir) { + return value.startsWith("~") ? new FilePath(value.replace("~", dir)) : this; + } + private List split() { var split = value.split("[\\\\/]"); return Arrays.stream(split).filter(s -> !s.isEmpty()).toList(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java index 5b7ef784a..ee45063b5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java @@ -170,11 +170,11 @@ public interface SshIdentityStrategy { var s = file.toAbsoluteFilePath(parent); // The ~ is supported on all platforms, so manually replace it here for Windows - if (s.contains("~")) { - s = s.replace("~", parent.getOsType().getUserHomeDirectory(parent)); + if (s.startsWith("~")) { + s = s.resolveTildeHome(parent.getOsType().getUserHomeDirectory(parent)); } var resolved = - parent.getShellDialect().evaluateExpression(parent, s).readStdoutOrThrow(); + parent.getShellDialect().evaluateExpression(parent, s.toString()).readStdoutOrThrow(); if (!parent.getShellDialect() .createFileExistsCommand(parent, resolved) .executeAndCheck()) { @@ -213,11 +213,11 @@ public interface SshIdentityStrategy { var s = file.toAbsoluteFilePath(sc); // The ~ is supported on all platforms, so manually replace it here for Windows - if (s.contains("~")) { - s = s.replace("~", sc.getOsType().getUserHomeDirectory(sc)); + if (s.startsWith("~")) { + s = s.resolveTildeHome(sc.getOsType().getUserHomeDirectory(sc)); } var resolved = - sc.getShellDialect().evaluateExpression(sc, s).readStdoutOrThrow(); + sc.getShellDialect().evaluateExpression(sc, s.toString()).readStdoutOrThrow(); return sc.getShellDialect().fileArgument(resolved); }) .add("-oIdentitiesOnly=yes"); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java index 2c1ffb281..4d90c9f81 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java @@ -95,7 +95,7 @@ public class SshIdentityStrategyHelper { boolean allowSync) { var keyPath = new SimpleObjectProperty( fileProperty.getValue() != null && fileProperty.getValue().getFile() != null - ? new FilePath(fileProperty.getValue().getFile().toAbsoluteFilePath(null)) + ? fileProperty.getValue().getFile().toAbsoluteFilePath(null) : null); fileProperty.addListener((observable, oldValue, newValue) -> { if (keyPath.get() != null @@ -106,7 +106,7 @@ public class SshIdentityStrategyHelper { keyPath.setValue( newValue != null && newValue.getFile() != null - ? new FilePath(newValue.getFile().toAbsoluteFilePath(null)) + ? newValue.getFile().toAbsoluteFilePath(null) : null); }); var keyPasswordProperty = new SimpleObjectProperty<>( diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStoreProvider.java index 85b4c542b..4222ee148 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStoreProvider.java @@ -47,8 +47,8 @@ public class SyncedIdentityStoreProvider extends IdentityStoreProvider { return; } - var source = Path.of(f.getFile().toAbsoluteFilePath(null)); - var target = Path.of("keys", FileNames.getFileName(f.getFile().toAbsoluteFilePath(null))); + var source = Path.of(f.getFile().toAbsoluteFilePath(null).toString()); + var target = Path.of("keys", f.getFile().toAbsoluteFilePath(null).getFileName()); DataStorageSyncHandler.getInstance().addDataFile(source, target, newValue); });