From 56dcf905ef308f85303f60da0feeb0e43e31afb4 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sun, 23 Apr 2023 11:04:39 +0000 Subject: [PATCH] Various fixes --- .../comp/source/store/GuiDsStoreCreator.java | 1 - .../comp/storage/store/StoreEntryComp.java | 5 +++ .../comp/storage/store/StoreEntryWrapper.java | 1 + ...oiceComp.java => DataStoreChoiceComp.java} | 33 +++++++++++-------- .../io/xpipe/app/storage/DataStorage.java | 31 +++++++++++++++++ .../io/xpipe/app/storage/DataStoreEntry.java | 6 ++++ .../core/process/ProcessOutputException.java | 12 ++++--- .../xpipe/core/store/DelegateShellStore.java | 13 ++++++++ .../xpipe/core/store/FixedHierarchyStore.java | 8 +++++ .../java/io/xpipe/core/store/LeafStore.java | 5 +++ .../actions/DeleteStoreChildrenAction.java | 8 +---- 11 files changed, 98 insertions(+), 25 deletions(-) rename app/src/main/java/io/xpipe/app/fxcomps/impl/{ShellStoreChoiceComp.java => DataStoreChoiceComp.java} (71%) create mode 100644 core/src/main/java/io/xpipe/core/store/DelegateShellStore.java create mode 100644 core/src/main/java/io/xpipe/core/store/FixedHierarchyStore.java create mode 100644 core/src/main/java/io/xpipe/core/store/LeafStore.java diff --git a/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java b/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java index ea67e7e92..0d5fa7fc9 100644 --- a/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java +++ b/app/src/main/java/io/xpipe/app/comp/source/store/GuiDsStoreCreator.java @@ -99,7 +99,6 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { e.applyChanges(newE); if (!DataStorage.get().getStoreEntries().contains(e)) { DataStorage.get().addStoreEntry(e); - ScanAlert.showIfNeeded(e.getStore(), true); } DataStorage.get().refresh(); }); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java index b3ab375fd..70145e9e3 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java @@ -19,6 +19,7 @@ import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.DesktopHelper; import io.xpipe.app.util.ThreadHelper; import javafx.beans.binding.Bindings; @@ -156,6 +157,10 @@ public class StoreEntryComp extends SimpleComp { event.consume(); ThreadHelper.runFailableAsync(() -> { var found = entry.getDefaultActionProvider().getValue(); + if (entry.getState().getValue().equals(DataStoreEntry.State.COMPLETE_BUT_INVALID) || found == null) { + entry.getEntry().refresh(true); + } + if (found != null) { entry.getEntry().updateLastUsed(); found.createAction(entry.getEntry().getStore().asNeeded()).execute(); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java index 915e49891..a510c3b3c 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java @@ -65,6 +65,7 @@ public class StoreEntryWrapper implements StorageFilter.Filterable { } public void delete() { + DataStorage.get().deleteChildren(this.entry, true); DataStorage.get().deleteStoreEntry(this.entry); } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java similarity index 71% rename from app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java rename to app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java index 572df41ef..58dec25dd 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/ShellStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java @@ -8,6 +8,7 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.CustomComboBoxBuilder; import io.xpipe.app.util.XPipeDaemon; +import io.xpipe.core.store.DataStore; import io.xpipe.core.store.ShellStore; import javafx.beans.property.Property; import javafx.beans.property.SimpleStringProperty; @@ -22,27 +23,33 @@ import java.util.Optional; import java.util.function.Predicate; @AllArgsConstructor -public class ShellStoreChoiceComp extends SimpleComp { +public class DataStoreChoiceComp extends SimpleComp { - public static ShellStoreChoiceComp proxy(Property selected) { - return new ShellStoreChoiceComp<>(Mode.PROXY_CHOICE, null, selected, ShellStore.class, shellStore -> true); + public static DataStoreChoiceComp proxy(Property selected) { + return new DataStoreChoiceComp<>(Mode.PROXY, null, selected, ShellStore.class, shellStore -> true); } - public static ShellStoreChoiceComp host(Property selected) { - return new ShellStoreChoiceComp<>(Mode.HOST_CHOICE, null, selected, ShellStore.class, shellStore -> true); + public static DataStoreChoiceComp host(Property selected) { + return new DataStoreChoiceComp<>(Mode.HOST, null, selected, ShellStore.class, shellStore -> true); } - public static ShellStoreChoiceComp proxy(ShellStore self, Property selected) { - return new ShellStoreChoiceComp<>(Mode.PROXY_CHOICE, self, selected, ShellStore.class, shellStore -> true); + public static DataStoreChoiceComp environment(ShellStore self, Property selected) { + return new DataStoreChoiceComp<>(Mode.ENVIRONMENT, self, selected, ShellStore.class, shellStore -> true); } - public static ShellStoreChoiceComp host(ShellStore self, Property selected) { - return new ShellStoreChoiceComp<>(Mode.HOST_CHOICE, self, selected, ShellStore.class, shellStore -> true); + public static DataStoreChoiceComp proxy(ShellStore self, Property selected) { + return new DataStoreChoiceComp<>(Mode.PROXY, self, selected, ShellStore.class, shellStore -> true); + } + + public static DataStoreChoiceComp host(ShellStore self, Property selected) { + return new DataStoreChoiceComp<>(Mode.HOST, self, selected, ShellStore.class, shellStore -> true); } public static enum Mode { - HOST_CHOICE, - PROXY_CHOICE + HOST, + ENVIRONMENT, + OTHER, + PROXY } private final Mode mode; @@ -60,7 +67,7 @@ public class ShellStoreChoiceComp extends SimpleComp { .filter(e -> e.equals(s)) .findAny() .flatMap(store -> { - if (ShellStore.isLocal(store.asNeeded()) && mode == Mode.PROXY_CHOICE) { + if (ShellStore.isLocal(store.asNeeded()) && mode == Mode.PROXY) { return Optional.of(AppI18n.get("none")); } @@ -97,7 +104,7 @@ public class ShellStoreChoiceComp extends SimpleComp { continue; } - if (!((ShellStore) s).canHaveSubs()) { + if (!(mode == Mode.ENVIRONMENT) && !((ShellStore) s).canHaveSubs()) { continue; } diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 03140e7ae..ebef8bfda 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -12,6 +12,7 @@ import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.DataSourceReference; import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FixedHierarchyStore; import lombok.Getter; import lombok.NonNull; @@ -95,6 +96,36 @@ public abstract class DataStorage { return internalCollection; } + public synchronized void refreshChildren(DataStoreEntry e) { + if (!(e.getStore() instanceof FixedHierarchyStore)) { + return; + } + + try { + var newChildren = ((FixedHierarchyStore) e.getStore()).listChildren(); + deleteChildren(e, true); + newChildren.forEach((key, value) -> { + try { + addStoreEntry(key, value); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + } catch (Exception ex) { + ErrorEvent.fromThrowable(ex).handle(); + } + } + + public synchronized void deleteChildren(DataStoreEntry e, boolean deep) { + getStoreChildren(e,deep).forEach(entry -> { + if (!entry.getConfiguration().isDeletable()) { + return; + } + + deleteStoreEntry(entry); + }); + } + public synchronized List getStoreChildren(DataStoreEntry entry, boolean deep) { var children = new ArrayList<>(getStoreEntries().stream().filter(other -> { if (!other.getState().isUsable()) { 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 0c6f92b4c..14ec88e30 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -10,6 +10,7 @@ import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FixedHierarchyStore; import io.xpipe.core.util.JacksonMapper; import lombok.*; import lombok.experimental.NonFinal; @@ -218,6 +219,11 @@ public class DataStoreEntry extends StorageElement { state = State.VALIDATING; listeners.forEach(l -> l.onUpdate()); store.validate(); + + if (store instanceof FixedHierarchyStore) { + DataStorage.get().refreshChildren(this); + } + state = State.COMPLETE_AND_VALID; information = getProvider().queryInformationString(getStore(), 50); dirty = true; diff --git a/core/src/main/java/io/xpipe/core/process/ProcessOutputException.java b/core/src/main/java/io/xpipe/core/process/ProcessOutputException.java index 0814cc5e6..53d4b7125 100644 --- a/core/src/main/java/io/xpipe/core/process/ProcessOutputException.java +++ b/core/src/main/java/io/xpipe/core/process/ProcessOutputException.java @@ -11,10 +11,14 @@ public class ProcessOutputException extends Exception { return new ProcessOutputException(message, ex.getExitCode(), ex.getOutput()); } - public static ProcessOutputException of(int exitCode, String output) { - var messageSuffix = output != null && !output.isBlank()?": " + output : ""; - var message = exitCode == CommandControl.TIMEOUT_EXIT_CODE ? "Process timed out" + messageSuffix : "Process returned with exit code " + exitCode + messageSuffix; - return new ProcessOutputException(message, exitCode, output); + public static ProcessOutputException of(int exitCode, String output, String accumulatedError) { + var combinedError = (accumulatedError != null ? accumulatedError.trim() + "\n" : "") + (output != null ? output.trim() : ""); + var message = switch (exitCode) { + case CommandControl.KILLED_EXIT_CODE -> "Process timed out" + combinedError; + case CommandControl.TIMEOUT_EXIT_CODE -> "Process timed out" + combinedError; + default -> "Process returned with exit code " + combinedError; + }; + return new ProcessOutputException(message, exitCode, combinedError); } private final int exitCode; diff --git a/core/src/main/java/io/xpipe/core/store/DelegateShellStore.java b/core/src/main/java/io/xpipe/core/store/DelegateShellStore.java new file mode 100644 index 000000000..e42aebb9b --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/DelegateShellStore.java @@ -0,0 +1,13 @@ +package io.xpipe.core.store; + +import io.xpipe.core.process.ShellControl; + +public interface DelegateShellStore extends ShellStore { + + @Override + default ShellControl createControl() { + return getDelegateHost().create(); + } + + ShellStore getDelegateHost(); +} diff --git a/core/src/main/java/io/xpipe/core/store/FixedHierarchyStore.java b/core/src/main/java/io/xpipe/core/store/FixedHierarchyStore.java new file mode 100644 index 000000000..486034781 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/FixedHierarchyStore.java @@ -0,0 +1,8 @@ +package io.xpipe.core.store; + +import java.util.Map; + +public interface FixedHierarchyStore extends DataStore { + + Map listChildren() throws Exception; +} diff --git a/core/src/main/java/io/xpipe/core/store/LeafStore.java b/core/src/main/java/io/xpipe/core/store/LeafStore.java new file mode 100644 index 000000000..0e4819ccd --- /dev/null +++ b/core/src/main/java/io/xpipe/core/store/LeafStore.java @@ -0,0 +1,5 @@ +package io.xpipe.core.store; + +public interface LeafStore extends DataStore { + +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/actions/DeleteStoreChildrenAction.java b/ext/base/src/main/java/io/xpipe/ext/base/actions/DeleteStoreChildrenAction.java index 46ec14b4f..417ae5c6d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/actions/DeleteStoreChildrenAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/actions/DeleteStoreChildrenAction.java @@ -22,13 +22,7 @@ public class DeleteStoreChildrenAction implements ActionProvider { @Override public void execute() throws Exception { - DataStorage.get().getStoreChildren(store,true).forEach(entry -> { - if (!entry.getConfiguration().isDeletable()) { - return; - } - - DataStorage.get().deleteStoreEntry(entry); - }); + DataStorage.get().deleteChildren(store, true); } }