From b9501bad43a6c293061d480df88f10740c715e95 Mon Sep 17 00:00:00 2001 From: Christopher Schnick Date: Fri, 30 Dec 2022 12:53:16 +0100 Subject: [PATCH] Implement module installations and rework some exchanges --- .../beacon/exchange/QueryStoreExchange.java | 50 ++++++++++++++++ .../beacon/exchange/cli/ConvertExchange.java | 1 - .../exchange/cli/RenameEntryExchange.java | 4 +- beacon/src/main/java/module-info.java | 1 + .../io/xpipe/core/util/XPipeInstallation.java | 4 +- .../main/java/io/xpipe/extension/Cache.java | 7 ++- .../io/xpipe/extension/DataStoreProvider.java | 4 ++ .../extension/DownloadModuleInstall.java | 32 +++++++++++ .../io/xpipe/extension/ModuleInstall.java | 24 ++++++++ .../io/xpipe/extension/event/TrackEvent.java | 13 ++++- .../fxcomps/impl/DynamicOptionsComp.java | 34 +++++------ .../io/xpipe/extension/util/HttpHelper.java | 57 +++++++++++++++++++ 12 files changed, 205 insertions(+), 26 deletions(-) create mode 100644 beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java create mode 100644 extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java create mode 100644 extension/src/main/java/io/xpipe/extension/ModuleInstall.java create mode 100644 extension/src/main/java/io/xpipe/extension/util/HttpHelper.java diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java new file mode 100644 index 00000000..1553e8e1 --- /dev/null +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/QueryStoreExchange.java @@ -0,0 +1,50 @@ +package io.xpipe.beacon.exchange; + +import io.xpipe.beacon.RequestMessage; +import io.xpipe.beacon.ResponseMessage; +import io.xpipe.core.store.DataStore; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +import java.util.LinkedHashMap; + +/** + * Queries general information about a data source. + */ +public class QueryStoreExchange implements MessageExchange { + + @Override + public String getId() { + return "queryStore"; + } + + @Jacksonized + @Builder + @Value + public static class Request implements RequestMessage { + @NonNull + String name; + } + + @Jacksonized + @Builder + @Value + public static class Response implements ResponseMessage { + @NonNull + String name; + + String information; + + String summary; + + @NonNull + String provider; + + @NonNull + LinkedHashMap config; + + DataStore internalStore; + } +} diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ConvertExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ConvertExchange.java index 32123884..c42bef58 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ConvertExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ConvertExchange.java @@ -37,7 +37,6 @@ public class ConvertExchange implements MessageExchange { @Builder @Value public static class Response implements ResponseMessage { - @NonNull DialogReference config; } } diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameEntryExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameEntryExchange.java index e3e24bd5..094a0321 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameEntryExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/RenameEntryExchange.java @@ -25,14 +25,12 @@ public class RenameEntryExchange implements MessageExchange { DataSourceReference ref; @NonNull - String newName; + DataSourceId newId; } @Jacksonized @Builder @Value public static class Response implements ResponseMessage { - @NonNull - DataSourceId newId; } } diff --git a/beacon/src/main/java/module-info.java b/beacon/src/main/java/module-info.java index 5b33ba8c..6b7d5efe 100644 --- a/beacon/src/main/java/module-info.java +++ b/beacon/src/main/java/module-info.java @@ -47,6 +47,7 @@ module io.xpipe.beacon { ModeExchange, ProxyWriteConnectionExchange, ProxyFunctionExchange, + QueryStoreExchange, StatusExchange, StopExchange, RenameStoreExchange, 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 f90a0435..f62f882d 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -122,7 +122,7 @@ public class XPipeInstallation { } else if (OsType.getLocal().equals(OsType.LINUX)) { path = "/opt/xpipe"; } else { - path = "~/Applications/X-Pipe.app"; + path = "/Applications/X-Pipe.app"; } return path; @@ -143,7 +143,7 @@ public class XPipeInstallation { } else if (p.getOsType().equals(OsType.LINUX)) { path = "/opt/xpipe"; } else { - path = "~/Applications/X-Pipe.app"; + path = "/Applications/X-Pipe.app"; } return path; diff --git a/extension/src/main/java/io/xpipe/extension/Cache.java b/extension/src/main/java/io/xpipe/extension/Cache.java index d4fcfc9e..31680234 100644 --- a/extension/src/main/java/io/xpipe/extension/Cache.java +++ b/extension/src/main/java/io/xpipe/extension/Cache.java @@ -8,8 +8,9 @@ public interface Cache { Cache INSTANCE = ServiceLoader.load(Cache.class).findFirst().orElseThrow(); - public static T get(String key, Class type, Supplier notPresent) { - return INSTANCE.getValue(key, type, notPresent); + @SuppressWarnings("unchecked") + public static V get(String key, Class type, Supplier notPresent) { + return (V) INSTANCE.getValue(key, type, notPresent); } public static Optional getIfPresent(String key, Class type) { @@ -17,7 +18,7 @@ public interface Cache { } public static void update(String key, T val) { - INSTANCE.updateValue(key, key); + INSTANCE.updateValue(key, val); } public T getValue(String key, Class type, Supplier notPresent); diff --git a/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java b/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java index ade94f8d..9c9bcae1 100644 --- a/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java +++ b/extension/src/main/java/io/xpipe/extension/DataStoreProvider.java @@ -12,6 +12,10 @@ import java.util.List; public interface DataStoreProvider { + default ModuleInstall getRequiredAdditionalInstallation() { + return null; + } + default void validate() throws Exception { getCategory(); for (Class storeClass : getStoreClasses()) { diff --git a/extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java b/extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java new file mode 100644 index 00000000..89323013 --- /dev/null +++ b/extension/src/main/java/io/xpipe/extension/DownloadModuleInstall.java @@ -0,0 +1,32 @@ +package io.xpipe.extension; + +import lombok.Getter; + +import java.util.List; + +public abstract class DownloadModuleInstall extends ModuleInstall { + + private String licenseFile; + private String vendorURL; + @Getter + private List assets; + + public DownloadModuleInstall( + String id, String module, String licenseFile, String vendorURL, List assets + ) { + super(id, module); + this.licenseFile = licenseFile; + this.vendorURL = vendorURL; + this.assets = assets; + } + + @Override + public String getLicenseFile() { + return licenseFile; + } + + @Override + public String getVendorURL() { + return vendorURL; + } +} diff --git a/extension/src/main/java/io/xpipe/extension/ModuleInstall.java b/extension/src/main/java/io/xpipe/extension/ModuleInstall.java new file mode 100644 index 00000000..8d15e7ff --- /dev/null +++ b/extension/src/main/java/io/xpipe/extension/ModuleInstall.java @@ -0,0 +1,24 @@ +package io.xpipe.extension; + +import lombok.Getter; + +import java.nio.file.Path; + +public abstract class ModuleInstall { + + @Getter + private final String id; + @Getter + private final String module; + + protected ModuleInstall(String id, String module) { + this.id = id; + this.module = module; + } + + public abstract String getLicenseFile(); + + public abstract String getVendorURL(); + + public abstract void installInternal(Path directory) throws Exception; +} diff --git a/extension/src/main/java/io/xpipe/extension/event/TrackEvent.java b/extension/src/main/java/io/xpipe/extension/event/TrackEvent.java index e6a23ce3..d70e1bc8 100644 --- a/extension/src/main/java/io/xpipe/extension/event/TrackEvent.java +++ b/extension/src/main/java/io/xpipe/extension/event/TrackEvent.java @@ -28,7 +28,7 @@ public class TrackEvent { private Map tags; @Singular - private List elements; + private List elements; public static TrackEventBuilder fromMessage(String type, String message) { return builder().type(type).message(message); @@ -128,6 +128,17 @@ public class TrackEvent { } s.append("}"); } + + if (elements.size() > 0) { + s.append(" [\n"); + for (var e : elements) { + s.append(" ") + .append(e != null ? e.toString() : "null") + .append("\n"); + } + s.append("]"); + } + return s.toString(); } diff --git a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java b/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java index 2f61fbcc..0dfde6ae 100644 --- a/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java +++ b/extension/src/main/java/io/xpipe/extension/fxcomps/impl/DynamicOptionsComp.java @@ -43,7 +43,6 @@ public class DynamicOptionsComp extends Comp> { pane = content; } else { var content = new VBox(); - content.setAlignment(Pos.CENTER); content.setSpacing(7); pane = content; } @@ -52,19 +51,19 @@ public class DynamicOptionsComp extends Comp> { var compRegions = new ArrayList(); for (var entry : getEntries()) { - var line = new HBox(); - line.setFillHeight(true); - if (!wrap) { - line.prefWidthProperty().bind(pane.widthProperty()); - } - line.setSpacing(8); - Region compRegion = null; if (entry.comp() != null) { compRegion = entry.comp().createRegion(); } if (entry.name() != null) { + var line = new HBox(); + line.setFillHeight(true); + if (!wrap) { + line.prefWidthProperty().bind(pane.widthProperty()); + } + line.setSpacing(8); + var name = new Label(); name.textProperty().bind(entry.name()); name.prefHeightProperty().bind(line.heightProperty()); @@ -76,17 +75,20 @@ public class DynamicOptionsComp extends Comp> { } nameRegions.add(name); line.getChildren().add(name); - } - if (entry.comp() != null) { - compRegions.add(compRegion); - line.getChildren().add(compRegion); - if (!wrap) { - HBox.setHgrow(compRegion, Priority.ALWAYS); + if (compRegion != null) { + compRegions.add(compRegion); + line.getChildren().add(compRegion); + if (!wrap) { + HBox.setHgrow(compRegion, Priority.ALWAYS); + } } - } - pane.getChildren().add(line); + pane.getChildren().add(line); + } else { + compRegions.add(compRegion); + pane.getChildren().add(compRegion); + } } if (wrap) { diff --git a/extension/src/main/java/io/xpipe/extension/util/HttpHelper.java b/extension/src/main/java/io/xpipe/extension/util/HttpHelper.java new file mode 100644 index 00000000..a64587ba --- /dev/null +++ b/extension/src/main/java/io/xpipe/extension/util/HttpHelper.java @@ -0,0 +1,57 @@ +package io.xpipe.extension.util; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.function.Consumer; + +public class HttpHelper { + + public static Path downloadFile(String urlS) throws Exception { + var url = new URL(urlS); + var bytes = HttpHelper.executeGet(url, aFloat -> {}); + var downloadFile = Files.createTempFile(null, null); + Files.write(downloadFile, bytes); + return downloadFile; + } + + public static byte[] executeGet(URL targetURL, Consumer progress) throws Exception { + HttpURLConnection connection = null; + + try { + // Create connection + connection = (HttpURLConnection) targetURL.openConnection(); + connection.setRequestMethod("GET"); + connection.addRequestProperty("User-Agent", "https://github.com/xpipe-io/xpipe-app"); + connection.addRequestProperty("Accept", "*/*"); + + int responseCode = connection.getResponseCode(); + if (responseCode != 200) { + throw new IOException("Got http " + responseCode + " for " + targetURL); + } + + InputStream is = connection.getInputStream(); + int size = Integer.parseInt(connection.getHeaderField("Content-Length")); + + byte[] line; + int bytes = 0; + ByteBuffer b = ByteBuffer.allocate(size); + while ((line = is.readNBytes(500000)).length > 0) { + b.put(line); + bytes += line.length; + if (progress != null) { + progress.accept((float) bytes / (float) size); + } + } + return b.array(); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } +}