diff --git a/README.md b/README.md index f57b7069..b5abc3f0 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,22 @@ The other modules make up the X-Pipe implementation and are licensed under GPL: - [app](app) - Contains the X-Pipe daemon implementation and the X-Pipe desktop application code - [cli](cli) - The X-Pipe CLI implementation, a GraalVM native image application - [dist](dist) - Tools to create a distributable package of X-Pipe -- [ext](ext) - Available X-Pipe extensions. Note that essentially every feature is implemented as an extension +- [ext](ext) - Available X-Pipe extensions. Essentially every feature is implemented as an extension +### Open source model + +X-Pipe utilizes an open core model, which essentially means that +the main application core is open source while certain other components are not. +In this case these non open source components are planned to be future parts of a potential commercialization. +Furthermore, some tests and especially test environments and that run on private servers +are also not included in this repository (Don't want to leak server information). +Finally, scripts and workflows to create signed executables and installers +are also not included to prevent attackers from easily impersonating the shipping the X-Pipe application malware. + +The license model is chosen in such a way that you are +able to use and integrate X-Pipe within your application through the MIT-licensed API. +In any other case where you plan to contribute to the X-Pipe platform itself, which is GPL licensed, +I would still have to figure out how to exactly handle these kinds of contributions. ## Development diff --git a/app/build.gradle b/app/build.gradle index 288f3dfb..d036cc89 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -89,7 +89,7 @@ List jvmRunArgs = [ "--add-exports", "org.apache.commons.lang3/org.apache.commons.lang3.math=io.xpipe.extension", "--add-opens", "java.base/java.lang.reflect=com.jfoenix", "--add-opens", "java.base/java.lang.reflect=com.jfoenix", - "--add-opens", "java.base/java.lang=io.xpipe.app", + "--add-opens", "java.base/java.lang=io.xpipe.core", "--add-opens", "com.dustinredmond.fxtrayicon/com.dustinredmond.fxtrayicon=io.xpipe.app", "--add-opens", "net.synedra.validatorfx/net.synedra.validatorfx=io.xpipe.extension", "-Xmx8g", diff --git a/app/src/main/java/io/xpipe/app/core/App.java b/app/src/main/java/io/xpipe/app/core/App.java index 1fe5e704..18266b46 100644 --- a/app/src/main/java/io/xpipe/app/core/App.java +++ b/app/src/main/java/io/xpipe/app/core/App.java @@ -2,6 +2,7 @@ package io.xpipe.app.core; import io.xpipe.app.Main; import io.xpipe.app.comp.AppLayoutComp; +import io.xpipe.core.process.OsType; import io.xpipe.extension.event.ErrorEvent; import io.xpipe.extension.event.TrackEvent; import io.xpipe.extension.fxcomps.util.PlatformThread; @@ -10,7 +11,6 @@ import javafx.application.Platform; import javafx.scene.image.Image; import javafx.scene.input.MouseEvent; import javafx.stage.Stage; -import org.apache.commons.lang3.SystemUtils; import javax.imageio.ImageIO; import java.awt.*; @@ -38,7 +38,7 @@ public class App extends Application { // Set dock icon explicitly on mac // This is necessary in case X-Pipe was started through a script as it will have no icon otherwise - if (SystemUtils.IS_OS_MAC) { + if (OsType.getLocal().equals(OsType.MACOS)) { try { var iconUrl = Main.class.getResourceAsStream("resources/img/logo.png"); if (iconUrl != null) { diff --git a/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java b/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java index 6f6391ff..184d0138 100644 --- a/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java +++ b/app/src/main/java/io/xpipe/app/launcher/LauncherCommand.java @@ -77,7 +77,7 @@ public class LauncherCommand implements Callable { OpenExchange.Request.builder().arguments(inputs).build()); } - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { Desktop.getDesktop().setOpenURIHandler(e -> { con.performSimpleExchange( OpenExchange.Request.builder().arguments(List.of(e.getURI().toString())).build()); @@ -120,7 +120,7 @@ public class LauncherCommand implements Callable { LauncherInput.handle(inputs); // URL open operations have to be handled in a special way on macOS! - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { Desktop.getDesktop().setOpenURIHandler(e -> { LauncherInput.handle(List.of(e.getURI().toString())); }); diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java index cb3b843e..bcb6713e 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -57,7 +57,7 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue { @Override public boolean isSelectable() { - return OsType.getLocal().equals(OsType.MAC); + return OsType.getLocal().equals(OsType.MACOS); } @Override diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java index b86b5e38..5c8028a2 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java @@ -5,7 +5,6 @@ import io.xpipe.core.process.ShellTypes; import io.xpipe.extension.prefs.PrefsChoiceValue; import io.xpipe.extension.util.ApplicationHelper; import io.xpipe.extension.util.WindowsRegistry; -import org.apache.commons.lang3.SystemUtils; import java.io.IOException; import java.nio.file.Path; @@ -38,13 +37,9 @@ public interface ExternalEditorType extends PrefsChoiceValue { @Override protected Optional determinePath() { - Optional launcherDir = Optional.empty(); - if (SystemUtils.IS_OS_WINDOWS) { - launcherDir = WindowsRegistry.readString( - WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null) - .map(p -> p + "\\notepad++.exe"); - } - + Optional launcherDir; + launcherDir = WindowsRegistry.readString(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null) + .map(p -> p + "\\notepad++.exe"); return launcherDir.map(Path::of); } }; @@ -71,7 +66,8 @@ public interface ExternalEditorType extends PrefsChoiceValue { @Override public void launch(Path file) throws Exception { - ApplicationHelper.executeLocalApplication(List.of("open", "-a", getApplicationPath().orElseThrow().toString(), file.toString())); + ApplicationHelper.executeLocalApplication( + List.of("open", "-a", getApplicationPath().orElseThrow().toString(), file.toString())); } } @@ -92,7 +88,7 @@ public interface ExternalEditorType extends PrefsChoiceValue { var format = customCommand.contains("$file") ? customCommand : customCommand + " $file"; var fileString = file.toString().contains(" ") ? "\"" + file + "\"" : file.toString(); - ApplicationHelper.executeLocalApplication(format.replace("$file",fileString)); + ApplicationHelper.executeLocalApplication(format.replace("$file", fileString)); } @Override @@ -108,7 +104,6 @@ public interface ExternalEditorType extends PrefsChoiceValue { public void launch(Path file) throws Exception; - public static class LinuxPathType extends ExternalApplicationType.PathApplication implements ExternalEditorType { public LinuxPathType(String id, String command) { @@ -127,7 +122,8 @@ public interface ExternalEditorType extends PrefsChoiceValue { } } - public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType implements ExternalEditorType { + public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType + implements ExternalEditorType { public WindowsFullPathType(String id) { super(id); @@ -147,23 +143,23 @@ public interface ExternalEditorType extends PrefsChoiceValue { public static final List WINDOWS_EDITORS = List.of(VSCODE, NOTEPADPLUSPLUS_WINDOWS, NOTEPAD); public static final List LINUX_EDITORS = List.of(VSCODE_LINUX, NOTEPADPLUSPLUS_LINUX, KATE, GEDIT, PLUMA, LEAFPAD, MOUSEPAD); - public static final List MACOS_EDITORS = - List.of(VSCODE_MACOS, SUBLIME_MACOS, TEXT_EDIT); + public static final List MACOS_EDITORS = List.of(VSCODE_MACOS, SUBLIME_MACOS, TEXT_EDIT); public static final List ALL = ((Supplier>) () -> { - var all = new ArrayList(); - if (OsType.getLocal().equals(OsType.WINDOWS)) { - all.addAll(WINDOWS_EDITORS); - } - if (OsType.getLocal().equals(OsType.LINUX)) { - all.addAll(LINUX_EDITORS); - } - if (OsType.getLocal().equals(OsType.MAC)) { - all.addAll(MACOS_EDITORS); - } - all.add(CUSTOM); - return all; - }).get(); + var all = new ArrayList(); + if (OsType.getLocal().equals(OsType.WINDOWS)) { + all.addAll(WINDOWS_EDITORS); + } + if (OsType.getLocal().equals(OsType.LINUX)) { + all.addAll(LINUX_EDITORS); + } + if (OsType.getLocal().equals(OsType.MACOS)) { + all.addAll(MACOS_EDITORS); + } + all.add(CUSTOM); + return all; + }) + .get(); public static void detectDefault() { var typeProperty = AppPrefs.get().externalEditor; @@ -190,13 +186,13 @@ public interface ExternalEditorType extends PrefsChoiceValue { } } else { typeProperty.set(LINUX_EDITORS.stream() - .filter(externalEditorType -> externalEditorType.isAvailable()) - .findFirst() - .orElse(null)); + .filter(externalEditorType -> externalEditorType.isAvailable()) + .findFirst() + .orElse(null)); } } - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { typeProperty.set(MACOS_EDITORS.stream() .filter(externalEditorType -> externalEditorType.isAvailable()) .findFirst() diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index f493384b..cbd7ca18 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -121,6 +121,7 @@ public class DataStoreEntry extends StorageElement { var information = Optional.ofNullable(json.get("information")) .map(JsonNode::textValue) .orElse(null); + var lastUsed = Instant.parse(json.required("lastUsed").textValue()); var lastModified = Instant.parse(json.required("lastModified").textValue()); var configuration = Optional.ofNullable(json.get("configuration")) diff --git a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java index 5670ae24..77610060 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -1,16 +1,14 @@ package io.xpipe.app.storage; -import io.xpipe.core.util.XPipeTempDirectory; +import io.xpipe.core.util.XPipeSession; import io.xpipe.extension.event.ErrorEvent; import io.xpipe.extension.event.TrackEvent; import lombok.NonNull; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.SystemUtils; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -22,44 +20,7 @@ public class StandardStorage extends DataStorage { private DataSourceCollection recovery; private boolean isNewSession() { - try { - if (SystemUtils.IS_OS_WINDOWS) { - var sessionFile = dir.resolve("session"); - if (!Files.exists(sessionFile)) { - return true; - } - - var lastSessionEndTime = Instant.parse(Files.readString(sessionFile)); - var pf = Path.of("C:\\pagefile.sys"); - var lastBootTime = Files.getLastModifiedTime(pf).toInstant(); - return lastSessionEndTime.isBefore(lastBootTime); - } else { - var sessionFile = XPipeTempDirectory.getLocal().resolve("xpipe_session"); - return !Files.exists(sessionFile); - } - - } catch (Exception ex) { - ErrorEvent.fromThrowable(ex).omitted(true).build().handle(); - return true; - } - } - - private void writeSessionInfo() { - try { - if (SystemUtils.IS_OS_WINDOWS) { - var sessionFile = dir.resolve("session"); - var now = Instant.now().toString(); - Files.writeString(sessionFile, now); - } else { - var sessionFile = XPipeTempDirectory.getLocal().resolve("xpipe_session"); - if (!Files.exists(sessionFile)) { - Files.createFile(sessionFile); - } - } - - } catch (Exception ex) { - ErrorEvent.fromThrowable(ex).omitted(true).build().handle(); - } + return XPipeSession.get().isNewSystemSession(); } private void deleteLeftovers() { @@ -322,8 +283,6 @@ public class StandardStorage extends DataStorage { } deleteLeftovers(); - - writeSessionInfo(); } @Override diff --git a/app/src/main/java/io/xpipe/app/update/AppInstaller.java b/app/src/main/java/io/xpipe/app/update/AppInstaller.java index 9b062db9..04c381c1 100644 --- a/app/src/main/java/io/xpipe/app/update/AppInstaller.java +++ b/app/src/main/java/io/xpipe/app/update/AppInstaller.java @@ -63,7 +63,7 @@ public class AppInstaller { return Files.exists(Path.of("/etc/debian_version")) ? new InstallerAssetType.Debian() : new InstallerAssetType.Rpm(); } - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { return new InstallerAssetType.Pkg(); } @@ -82,7 +82,7 @@ public class AppInstaller { } } - if (p.getOsType().equals(OsType.MAC)) { + if (p.getOsType().equals(OsType.MACOS)) { return new InstallerAssetType.Pkg(); } diff --git a/app/src/main/java/io/xpipe/app/update/AppUpdater.java b/app/src/main/java/io/xpipe/app/update/AppUpdater.java index 9d3aa848..f2ac8cff 100644 --- a/app/src/main/java/io/xpipe/app/update/AppUpdater.java +++ b/app/src/main/java/io/xpipe/app/update/AppUpdater.java @@ -6,7 +6,7 @@ import io.xpipe.app.core.AppExtensionManager; import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.core.impl.ProcessControlProvider; +import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.util.XPipeSession; import io.xpipe.extension.event.ErrorEvent; import io.xpipe.extension.event.TrackEvent; diff --git a/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java b/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java index 87ad202a..b3159f52 100644 --- a/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java +++ b/core/src/main/java/io/xpipe/core/charsetter/Charsetter.java @@ -112,9 +112,7 @@ public abstract class Charsetter { if (store instanceof FileStore fileStore && fileStore.getFileSystem() instanceof MachineStore m) { if (result.getNewLine() == null) { - try (var pc = m.create().start()) { - result = new Result(result.getCharset(), pc.getShellType().getNewLine()); - } + result = new Result(result.getCharset(), m.getShellType() != null ? m.getShellType().getNewLine() : null); } } diff --git a/core/src/main/java/io/xpipe/core/impl/LocalStore.java b/core/src/main/java/io/xpipe/core/impl/LocalStore.java index 2ebc9732..c70afc33 100644 --- a/core/src/main/java/io/xpipe/core/impl/LocalStore.java +++ b/core/src/main/java/io/xpipe/core/impl/LocalStore.java @@ -1,6 +1,7 @@ package io.xpipe.core.impl; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.store.FileSystemStore; import io.xpipe.core.store.MachineStore; @@ -47,7 +48,7 @@ public class LocalStore extends JacksonizedValue implements FileSystemStore, Mac } @Override - public ShellProcessControl create() { + public ShellProcessControl createControl() { return ProcessControlProvider.createLocal(); } diff --git a/core/src/main/java/io/xpipe/core/impl/ProcessControlProvider.java b/core/src/main/java/io/xpipe/core/impl/ProcessControlProvider.java deleted file mode 100644 index 1eff1f09..00000000 --- a/core/src/main/java/io/xpipe/core/impl/ProcessControlProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.xpipe.core.impl; - -import io.xpipe.core.process.CommandProcessControl; -import io.xpipe.core.process.ShellProcessControl; -import lombok.NonNull; - -import java.util.List; -import java.util.ServiceLoader; -import java.util.function.BiFunction; -import java.util.function.Function; - -public abstract class ProcessControlProvider { - - private static List INSTANCES; - - public static void init(ModuleLayer layer) { - INSTANCES = ServiceLoader.load(layer, ProcessControlProvider.class) - .stream().map(localProcessControlProviderProvider -> localProcessControlProviderProvider.get()).toList(); - } - - public static ShellProcessControl createLocal() { - return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.createLocalProcessControl()).findFirst().orElseThrow(); - } - - public static ShellProcessControl createSub( - ShellProcessControl parent, - @NonNull Function commandFunction, - BiFunction terminalCommand) { - return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.sub(parent, commandFunction, terminalCommand)).findFirst().orElseThrow(); - } - - public static CommandProcessControl createCommand( - ShellProcessControl parent, - @NonNull Function command, - Function terminalCommand) { - return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.command(parent, command, terminalCommand)).findFirst().orElseThrow(); - } - - public abstract ShellProcessControl sub( - ShellProcessControl parent, - @NonNull Function commandFunction, - BiFunction terminalCommand); - - public abstract CommandProcessControl command( - ShellProcessControl parent, - @NonNull Function command, - Function terminalCommand); - - public abstract ShellProcessControl createLocalProcessControl(); -} diff --git a/core/src/main/java/io/xpipe/core/process/OsType.java b/core/src/main/java/io/xpipe/core/process/OsType.java index e99b6334..236beb61 100644 --- a/core/src/main/java/io/xpipe/core/process/OsType.java +++ b/core/src/main/java/io/xpipe/core/process/OsType.java @@ -7,12 +7,12 @@ public interface OsType { Windows WINDOWS = new Windows(); Linux LINUX = new Linux(); - Mac MAC = new Mac(); + MacOs MACOS = new MacOs(); public static OsType getLocal() { String osName = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); if ((osName.contains("mac")) || (osName.contains("darwin"))) { - return MAC; + return MACOS; } else if (osName.contains("win")) { return WINDOWS; } else if (osName.contains("nux")) { @@ -124,7 +124,7 @@ public interface OsType { } } - static class Mac implements OsType { + static class MacOs implements OsType { @Override public String getTempDirectory(ShellProcessControl pc) throws Exception { diff --git a/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java b/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java index 0fbee11b..903ecaa9 100644 --- a/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java +++ b/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java @@ -1,6 +1,58 @@ package io.xpipe.core.process; +import lombok.NonNull; + +import java.util.List; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.function.BiFunction; +import java.util.function.Function; + public abstract class ProcessControlProvider { - public abstract ProcessControl local(); + private static List INSTANCES; + + public static void init(ModuleLayer layer) { + INSTANCES = ServiceLoader.load(layer, ProcessControlProvider.class) + .stream().map(localProcessControlProviderProvider -> localProcessControlProviderProvider.get()).toList(); + } + + public static ShellProcessControl createLocal() { + return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.createLocalProcessControl()).findFirst().orElseThrow(); + } + + public static ShellProcessControl createSub( + ShellProcessControl parent, + @NonNull Function commandFunction, + BiFunction terminalCommand) { + return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.sub(parent, commandFunction, terminalCommand)).filter( + Objects::nonNull).findFirst().orElseThrow(); + } + + public static CommandProcessControl createCommand( + ShellProcessControl parent, + @NonNull Function command, + Function terminalCommand) { + return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.command(parent, command, terminalCommand)).filter( + Objects::nonNull).findFirst().orElseThrow(); + } + + public static ShellProcessControl createSsh(Object sshStore) { + return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.createSshControl(sshStore)).filter( + Objects::nonNull).findFirst().orElseThrow(); + } + + public abstract ShellProcessControl sub( + ShellProcessControl parent, + @NonNull Function commandFunction, + BiFunction terminalCommand); + + public abstract CommandProcessControl command( + ShellProcessControl parent, + @NonNull Function command, + Function terminalCommand); + + public abstract ShellProcessControl createLocalProcessControl(); + + public abstract ShellProcessControl createSshControl(Object sshStore); } diff --git a/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java b/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java index 5e38444a..3e789fa8 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java +++ b/core/src/main/java/io/xpipe/core/process/ShellProcessControl.java @@ -6,11 +6,14 @@ import lombok.NonNull; import java.io.IOException; import java.util.List; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; public interface ShellProcessControl extends ProcessControl { + void onInit(Consumer pc); + String prepareTerminalOpen() throws Exception; String prepareIntermediateTerminalOpen(String content) throws Exception; diff --git a/core/src/main/java/io/xpipe/core/store/ShellStore.java b/core/src/main/java/io/xpipe/core/store/ShellStore.java index 3cebb016..38088551 100644 --- a/core/src/main/java/io/xpipe/core/store/ShellStore.java +++ b/core/src/main/java/io/xpipe/core/store/ShellStore.java @@ -2,10 +2,14 @@ package io.xpipe.core.store; import io.xpipe.core.charsetter.Charsetter; import io.xpipe.core.impl.LocalStore; +import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.process.ShellType; -public interface ShellStore extends DataStore { +import java.nio.charset.Charset; + +public interface ShellStore extends DataStore, StatefulDataStore +{ public static MachineStore local() { return new LocalStore(); @@ -21,7 +25,28 @@ public interface ShellStore extends DataStore { return s instanceof LocalStore; } - ShellProcessControl create(); + default ShellProcessControl create() { + var pc = createControl(); + pc.onInit(processControl -> { + setState("type", processControl.getShellType()); + setState("os", processControl.getOsType()); + setState("charset", processControl.getCharset()); + }); + return pc; + } + + default ShellType getShellType() { + return getState("type", ShellType.class, null); + } + + default OsType getOsType() { + return getState("os", OsType.class, null); + } + default Charset getCharset() { + return getState("charset", Charset.class, null); + } + + ShellProcessControl createControl(); public default ShellType determineType() throws Exception { try (var pc = create().start()) { diff --git a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java index 0442fa7a..c6eda0cb 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -20,7 +20,7 @@ public class XPipeInstallation { if (OsType.getLocal().equals(OsType.LINUX)) { return "nohup \"" + installationBase + "/app/bin/xpiped\" --mode " + mode.getDisplayName() + suffix + " & disown"; - } else if (OsType.getLocal().equals(OsType.MAC)) { + } else if (OsType.getLocal().equals(OsType.MACOS)) { return "open \"" + installationBase + "\" --args --mode " + mode.getDisplayName() + suffix; } @@ -55,7 +55,7 @@ public class XPipeInstallation { public static boolean isInstallationDistribution() { var base = getLocalInstallationBasePath(); - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { if (!base.toString().equals(getLocalDefaultInstallationBasePath(false))) { return false; } @@ -93,13 +93,13 @@ public class XPipeInstallation { public static Path getLocalExtensionsDirectory() { Path path = getLocalInstallationBasePath(); - return OsType.getLocal().equals(OsType.MAC) + return OsType.getLocal().equals(OsType.MACOS) ? path.resolve("Contents").resolve("Resources").resolve("extensions") : path.resolve("app").resolve("extensions"); } private static Path getLocalInstallationBasePathForJavaExecutable(Path executable) { - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { return executable .getParent() .getParent() @@ -115,7 +115,7 @@ public class XPipeInstallation { } private static Path getLocalInstallationBasePathForDaemonExecutable(Path executable) { - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { return executable.getParent().getParent().getParent(); } else if (OsType.getLocal().equals(OsType.LINUX)) { return executable.getParent().getParent().getParent(); @@ -138,7 +138,7 @@ public class XPipeInstallation { return defaultInstallation; } - if (OsType.getLocal().equals(OsType.MAC)) { + if (OsType.getLocal().equals(OsType.MACOS)) { return FileNames.getParent(FileNames.getParent(FileNames.getParent(cliExecutable))); } else { return FileNames.getParent(FileNames.getParent(cliExecutable)); diff --git a/core/src/main/java/io/xpipe/core/util/XPipeTempDirectory.java b/core/src/main/java/io/xpipe/core/util/XPipeTempDirectory.java index 0d1f3309..6f9eb2fa 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeTempDirectory.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeTempDirectory.java @@ -26,7 +26,7 @@ public class XPipeTempDirectory { if (!proc.executeBooleanSimpleCommand(proc.getShellType().getFileExistsCommand(dir))) { proc.executeSimpleCommand(proc.getShellType().flatten(proc.getShellType().getMkdirsCommand(dir)), "Unable to access or create temporary directory " + dir); - if (proc.getOsType().equals(OsType.LINUX) || proc.getOsType().equals(OsType.MAC)) { + if (proc.getOsType().equals(OsType.LINUX) || proc.getOsType().equals(OsType.MACOS)) { proc.executeSimpleCommand("chmod -f 777 \"" + dir + "\""); } } diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index 4caf8088..c2d408bf 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -1,4 +1,4 @@ -import io.xpipe.core.impl.ProcessControlProvider; +import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.source.WriteMode; import io.xpipe.core.util.CoreJacksonModule; diff --git a/ext/pdx/src/main/java/io/xpipe/ext/pdx/parser/TextFormatParser.java b/ext/pdx/src/main/java/io/xpipe/ext/pdx/parser/TextFormatParser.java index 9a8c48de..f3f436f3 100644 --- a/ext/pdx/src/main/java/io/xpipe/ext/pdx/parser/TextFormatParser.java +++ b/ext/pdx/src/main/java/io/xpipe/ext/pdx/parser/TextFormatParser.java @@ -3,7 +3,6 @@ package io.xpipe.ext.pdx.parser; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.TupleNode; import io.xpipe.core.data.node.ValueNode; -import org.apache.commons.lang3.SystemUtils; import java.io.IOException; import java.nio.charset.Charset; @@ -40,7 +39,7 @@ public final class TextFormatParser { public static TextFormatParser eu4() { return new TextFormatParser( - SystemUtils.IS_OS_MAC ? StandardCharsets.UTF_8 : Charset.forName("windows-1252"), + Charset.forName("windows-1252"), TaggedNodes.NO_TAGS, s -> s.equals("map_area_data")); } @@ -59,14 +58,14 @@ public final class TextFormatParser { public static TextFormatParser ck2() { return new TextFormatParser( - SystemUtils.IS_OS_MAC ? StandardCharsets.UTF_8 : Charset.forName("windows-1252"), + Charset.forName("windows-1252"), TaggedNodes.NO_TAGS, s -> false); } public static TextFormatParser vic2() { return new TextFormatParser( - SystemUtils.IS_OS_MAC ? StandardCharsets.UTF_8 : Charset.forName("windows-1252"), + Charset.forName("windows-1252"), TaggedNodes.NO_TAGS, s -> false); } diff --git a/ext/procx/build.gradle b/ext/procx/build.gradle new file mode 100644 index 00000000..fce335e8 --- /dev/null +++ b/ext/procx/build.gradle @@ -0,0 +1 @@ +plugins { id 'java' } diff --git a/ext/procx/src/main/java/module-info.java b/ext/procx/src/main/java/module-info.java new file mode 100644 index 00000000..6eb3057c --- /dev/null +++ b/ext/procx/src/main/java/module-info.java @@ -0,0 +1 @@ +module io.xpipe.ext.procx {} diff --git a/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java b/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java index e91c63ae..44afb998 100644 --- a/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java +++ b/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java @@ -79,7 +79,7 @@ public interface DataStoreProvider { } default String getModuleName() { - var n = getClass().getPackageName(); + var n = getClass().getModule().getName(); var i = n.lastIndexOf('.'); return i != -1 ? n.substring(i + 1) : n; } diff --git a/extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java b/extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java index ae10f8a6..db124a99 100644 --- a/extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java +++ b/extension/src/main/java/io/xpipe/extension/XPipeServiceProviders.java @@ -1,7 +1,7 @@ package io.xpipe.extension; import com.fasterxml.jackson.databind.jsontype.NamedType; -import io.xpipe.core.impl.ProcessControlProvider; +import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.ProxyFunction; import io.xpipe.extension.event.TrackEvent; diff --git a/extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java b/extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java index bcf1abb8..e70ac4a3 100644 --- a/extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java +++ b/extension/src/main/java/io/xpipe/extension/util/XPipeDistributionType.java @@ -42,7 +42,7 @@ public interface XPipeDistributionType { @Override public boolean supportsURLs() { - return OsType.getLocal().equals(OsType.MAC); + return OsType.getLocal().equals(OsType.MACOS); } @Override