diff --git a/app/src/main/java/io/xpipe/app/ext/DataStore.java b/app/src/main/java/io/xpipe/app/ext/DataStore.java index 10f99ea4c..4ca7c21de 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStore.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStore.java @@ -1,10 +1,15 @@ package io.xpipe.app.ext; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.xpipe.app.storage.DataStoreEntryRef; + +import java.util.List; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") public interface DataStore { + List> getDependencies(); + default boolean isComplete() { try { checkComplete(); diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreDependencies.java b/app/src/main/java/io/xpipe/app/ext/DataStoreDependencies.java new file mode 100644 index 000000000..5acf67e36 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreDependencies.java @@ -0,0 +1,30 @@ +package io.xpipe.app.ext; + +import io.xpipe.app.storage.DataStoreEntryRef; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DataStoreDependencies { + + public static List> of(Object... dependencies) { + var l = new ArrayList>(); + for (Object dependency : dependencies) { + if (dependency instanceof DataStoreEntryRef r) { + l.add(r); + } else if (dependency instanceof List li) { + l.addAll(of(li)); + } + } + return l; + } + + public static List> of(DataStoreEntryRef... dependencies) { + return Arrays.stream(dependencies).toList(); + } + + public static List> of(List> refs) { + return new ArrayList<>(refs); + } +} diff --git a/app/src/main/java/io/xpipe/app/ext/DependentDataStore.java b/app/src/main/java/io/xpipe/app/ext/DependentDataStore.java new file mode 100644 index 000000000..60e3f71bd --- /dev/null +++ b/app/src/main/java/io/xpipe/app/ext/DependentDataStore.java @@ -0,0 +1,10 @@ +package io.xpipe.app.ext; + +import io.xpipe.app.storage.DataStoreEntryRef; + +import java.util.List; + +public interface DependentDataStore extends DataStore { + + List> getDependencies(); +} diff --git a/app/src/main/java/io/xpipe/app/ext/GroupStore.java b/app/src/main/java/io/xpipe/app/ext/GroupStore.java index 355dde3b5..c6967f204 100644 --- a/app/src/main/java/io/xpipe/app/ext/GroupStore.java +++ b/app/src/main/java/io/xpipe/app/ext/GroupStore.java @@ -2,10 +2,17 @@ package io.xpipe.app.ext; import io.xpipe.app.storage.DataStoreEntryRef; +import java.util.List; + public interface GroupStore extends DataStore { DataStoreEntryRef getParent(); + @Override + default List> getDependencies() { + return DataStoreDependencies.of(getParent()); + } + @Override default void checkComplete() throws Throwable { var p = getParent(); diff --git a/app/src/main/java/io/xpipe/app/ext/LocalStore.java b/app/src/main/java/io/xpipe/app/ext/LocalStore.java index 8f6cceeec..b50a166d5 100644 --- a/app/src/main/java/io/xpipe/app/ext/LocalStore.java +++ b/app/src/main/java/io/xpipe/app/ext/LocalStore.java @@ -7,6 +7,8 @@ import io.xpipe.app.storage.DataStoreEntryRef; import com.fasterxml.jackson.annotation.JsonTypeName; import lombok.Value; +import java.util.List; + @JsonTypeName("local") @Value public class LocalStore implements NetworkTunnelStore, ShellStore, StatefulDataStore { @@ -39,4 +41,9 @@ public class LocalStore implements NetworkTunnelStore, ShellStore, StatefulDataS public NetworkTunnelSession createTunnelSession(int localPort, int remotePort, String address) { return null; } + + @Override + public List> getDependencies() { + return List.of(); + } } 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 7a5ddefd8..c94cfada3 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -55,6 +55,7 @@ public abstract class DataStorage { private final Map identityStoreEntryMapCache = new IdentityHashMap<>(); private final Map storeEntryMapCache = new HashMap<>(); private final Map storeMoveCache = new IdentityHashMap<>(); + private final Map>> storeDependencyCache = new HashMap<>(); @Getter protected boolean entriesAvailable; @@ -362,7 +363,7 @@ public abstract class DataStorage { var newParent = DataStorage.get().getDefaultDisplayParent(newEntry); var sameParent = Objects.equals(oldParent, newParent); - finalizeWithChildren(entry); + finalizeWithDependencies(entry); var children = getDeepStoreChildren(entry); if (!sameParent) { @@ -377,6 +378,9 @@ public abstract class DataStorage { synchronized (storeEntryMapCache) { storeEntryMapCache.remove(entry.getStore()); } + synchronized (storeDependencyCache) { + storeDependencyCache.remove(entry); + } } var categoryChanged = !entry.getCategoryUuid().equals(newEntry.getCategoryUuid()); @@ -412,25 +416,42 @@ public abstract class DataStorage { saveAsync(); } - private void finalizeWithChildren(DataStoreEntry entry) { - var c = getDeepStoreChildren(entry); - var l = new ArrayList<>(c); - l.addFirst(entry); - for (int i = l.size() - 1; i >= 0; i--) { - l.get(i).finalizeEntry(); + public void finalizeWithDependencies(DataStoreEntry entry) { + var cached = storeDependencyCache.computeIfAbsent(entry, this::getDependencies); + for (DataStoreEntryRef dataStoreEntryRef : cached) { + dataStoreEntryRef.get().finalizeEntry(); } } + private Collection> getDependencies(DataStoreEntry entry) { + var l = new HashSet>(); + + var store = entry.getStore(); + if (store == null) { + return l; + } + + var deps = store.getDependencies(); + l.addAll(deps); + for (DataStoreEntryRef dep : deps) { + l.addAll(getDependencies(dep.get())); + } + return l; + } + public void updateEntryStore(DataStoreEntry entry, DataStore store) { if (entry.getStore() == store) { return; } - finalizeWithChildren(entry); + finalizeWithDependencies(entry); if (entry.getStore() != null && store != null && !entry.getStore().equals(store)) { synchronized (storeMoveCache) { storeMoveCache.put(entry.getStore(), store); } + synchronized (storeDependencyCache) { + storeDependencyCache.put(entry, getDependencies(entry)); + } } entry.setStoreInternal(store, false); @@ -852,6 +873,9 @@ public abstract class DataStorage { synchronized (storeEntryMapCache) { storeEntryMapCache.remove(td.getStore()); } + synchronized (storeDependencyCache) { + storeDependencyCache.remove(td); + } var parent = getDefaultDisplayParent(td); parent.ifPresent(p -> p.setChildrenCache(null)); } @@ -986,7 +1010,7 @@ public abstract class DataStorage { } public void deleteStoreEntry(@NonNull DataStoreEntry entry) { - finalizeWithChildren(entry); + finalizeWithDependencies(entry); this.storeEntries.remove(entry); synchronized (identityStoreEntryMapCache) { identityStoreEntryMapCache.remove(entry.getStore()); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStore.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStore.java index 8fdc85844..bde10596b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStore.java @@ -1,6 +1,7 @@ package io.xpipe.ext.base.desktop; import io.xpipe.app.ext.DataStore; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.process.CommandBuilder; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; @@ -10,6 +11,9 @@ import lombok.Value; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.Collections; +import java.util.List; + @Value @SuperBuilder @Jacksonized @@ -20,6 +24,11 @@ public class DesktopApplicationStore implements DataStore { String path; String arguments; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(desktop); + } + @Override public void checkComplete() throws Throwable { Validators.nonNull(desktop); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStore.java b/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStore.java index 48ce9b81a..5d6caa572 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStore.java @@ -10,6 +10,8 @@ import lombok.Value; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.List; + @Value @ToString(callSuper = true) @SuperBuilder @@ -20,6 +22,10 @@ public class AbstractHostStore implements DataStore, HostAddressStore, HostAddre String host; DataStoreEntryRef gateway; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(gateway); + } @Override public void checkComplete() throws Throwable { Validators.nonNull(host); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityValue.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityValue.java index a724cb171..9afd9e76b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityValue.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentityValue.java @@ -1,5 +1,6 @@ package io.xpipe.ext.base.identity; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.ext.ValidationException; import io.xpipe.app.secret.EncryptedValue; import io.xpipe.app.secret.SecretNoneStrategy; @@ -19,6 +20,8 @@ import lombok.Builder; import lombok.Value; import lombok.extern.jackson.Jacksonized; +import java.util.List; + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = IdentityValue.InPlace.class), @@ -93,6 +96,8 @@ public interface IdentityValue { boolean isInPlace(); + List> getDependencies(); + default void checkCompleteUser() throws ValidationException { Validators.nonNull(unwrap().getUsername().hasUser() ? new Object() : null, "Identity username"); } @@ -136,6 +141,11 @@ public interface IdentityValue { public boolean isInPlace() { return true; } + + @Override + public List> getDependencies() { + return List.of(); + } } @JsonTypeName("ref") @@ -168,5 +178,10 @@ public interface IdentityValue { public boolean isInPlace() { return false; } + + @Override + public List> getDependencies() { + return DataStoreDependencies.of(ref); + } } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStore.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStore.java index b793a40a5..55df1325b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStore.java @@ -6,12 +6,15 @@ import io.xpipe.app.secret.SecretRetrievalStrategy; import io.xpipe.app.cred.SshIdentityStrategy; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntryRef; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Value; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.List; + @SuperBuilder(toBuilder = true) @JsonTypeName("localIdentity") @Jacksonized @@ -45,4 +48,9 @@ public class LocalIdentityStore extends IdentityStore { EncryptedValue getEncryptedSshIdentity() { return sshIdentity; } + + @Override + public List> getDependencies() { + return List.of(); + } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentityStore.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentityStore.java index 4877a3a12..17049b39d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentityStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentityStore.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName; import io.xpipe.app.core.AppCache; import io.xpipe.app.cred.SshIdentityStrategy; import io.xpipe.app.cred.UsernameStrategy; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.ext.InternalCacheDataStore; import io.xpipe.app.ext.StatefulDataStore; import io.xpipe.app.ext.ValidationException; @@ -63,6 +64,7 @@ public class MultiIdentityStore extends IdentityStore implements StatefulDataSto } setState(MultiIdentityStoreState.builder().selected(entry.get().getUuid()).build()); + DataStorage.get().finalizeWithDependencies(getSelfEntry()); } private DataStoreEntryRef getSelectedOrThrow() { @@ -73,6 +75,11 @@ public class MultiIdentityStore extends IdentityStore implements StatefulDataSto throw ErrorEventFactory.expected(new IllegalStateException("No available identity for multi identity " + getSelfEntry().getName())); } + @Override + public List> getDependencies() { + return DataStoreDependencies.of(getAvailableIdentities()); + } + @Override public void checkComplete() throws Throwable { getSelectedOrThrow(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentitySwitchBranchProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentitySwitchBranchProvider.java index 721068a58..27f18c787 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentitySwitchBranchProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/MultiIdentitySwitchBranchProvider.java @@ -8,6 +8,7 @@ import io.xpipe.app.hub.action.StoreActionCategory; import io.xpipe.app.platform.LabelGraphic; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.ThreadHelper; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.beans.value.ObservableValue; @@ -68,7 +69,9 @@ public class MultiIdentitySwitchBranchProvider implements HubBranchProvider ref) { - ref.getStore().select(identity); + ThreadHelper.runAsync(() -> { + ref.getStore().select(identity); + }); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStore.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStore.java index d7a555c5a..a92c663e5 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStore.java @@ -11,6 +11,7 @@ import io.xpipe.app.process.ShellControl; import io.xpipe.app.pwman.PasswordManager; import io.xpipe.app.secret.*; import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.*; import com.fasterxml.jackson.annotation.JsonTypeName; @@ -212,6 +213,11 @@ public class PasswordManagerIdentityStore extends IdentityStore return new NoIdentityStrategy(); } + @Override + public List> getDependencies() { + return List.of(); + } + @Override public void checkComplete() throws Throwable { Validators.nonNull(key); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStore.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStore.java index e8ed826a4..c146660e1 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/SyncedIdentityStore.java @@ -9,12 +9,15 @@ import io.xpipe.app.cred.KeyFileStrategy; import io.xpipe.app.cred.SshIdentityStrategy; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntryRef; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Value; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.List; + @SuperBuilder @JsonTypeName("syncedIdentity") @Value @@ -44,6 +47,11 @@ public class SyncedIdentityStore extends IdentityStore implements UserScopeStore return sshIdentity != null ? sshIdentity.getValue() : null; } + @Override + public List> getDependencies() { + return List.of(); + } + @Override public void checkComplete() throws Throwable { super.checkComplete(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStore.java index 6dd0fa7b3..a9ea10ccd 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStore.java @@ -1,6 +1,7 @@ package io.xpipe.ext.base.script; import io.xpipe.app.ext.*; +import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; import com.fasterxml.jackson.annotation.JsonTypeName; @@ -20,6 +21,11 @@ public class ScriptCollectionSourceStore ScriptCollectionSource source; + @Override + public List> getDependencies() { + return List.of(); + } + @Override public void checkComplete() throws Throwable { Validators.nonNull(source); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java index 48520787b..e22b1718b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java @@ -114,6 +114,15 @@ public class ScriptStore implements SelfReferentialStore, StatefulDataStore> getDependencies() { + var l = DataStoreDependencies.of(scripts); + if (textSource != null) { + l.addAll(textSource.getDependencies()); + } + return l; + } + @Override public void checkComplete() throws Throwable { if (textSource != null) { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTextSource.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTextSource.java index 19468221d..53ff2ae65 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTextSource.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptTextSource.java @@ -6,6 +6,7 @@ import io.xpipe.app.comp.base.IntegratedTextAreaComp; import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.window.AppDialog; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.ext.ShellDialectChoiceComp; import io.xpipe.app.ext.ValidationException; import io.xpipe.app.hub.comp.StoreChoiceComp; @@ -102,6 +103,11 @@ public interface ScriptTextSource { property); } + @Override + public List> getDependencies() { + return List.of(); + } + @Override public void checkComplete() {} @@ -238,6 +244,11 @@ public interface ScriptTextSource { return ShellScript.empty(); } } + + @Override + public List> getDependencies() { + return List.of(); + } } @JsonTypeName("source") @@ -359,6 +370,11 @@ public interface ScriptTextSource { } } + @Override + public List> getDependencies() { + return DataStoreDependencies.of(ref); + } + private ScriptCollectionSourceEntry findSourceEntryIfPossible() { if (ref == null) { return null; @@ -393,6 +409,8 @@ public interface ScriptTextSource { ShellScript getText(); + List> getDependencies(); + static List> getClasses() { var l = new ArrayList>(); l.add(InPlace.class); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java index 721062204..a7e4fc944 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStore.java @@ -1,6 +1,7 @@ package io.xpipe.ext.base.service; import io.xpipe.app.ext.DataStore; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.ext.GroupStore; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; @@ -12,6 +13,8 @@ import lombok.ToString; import lombok.experimental.FieldDefaults; import lombok.experimental.SuperBuilder; +import java.util.List; + @Getter @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @SuperBuilder diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java index 4543d7abb..da7baf7bf 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java @@ -1,5 +1,6 @@ package io.xpipe.ext.base.service; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.ext.NetworkTunnelStore; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.ext.base.host.AbstractHostStore; @@ -13,6 +14,8 @@ import lombok.ToString; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.List; + @SuperBuilder(toBuilder = true) @Getter @Jacksonized @@ -26,6 +29,11 @@ public final class CustomServiceStore extends AbstractServiceStore implements Ab private final DataStoreEntryRef gateway; private final Boolean tunnelToLocalhost; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(host, gateway); + } + @Override public void checkComplete() throws Throwable { super.checkComplete(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java index 8d1bb919d..9cedc35de 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java @@ -1,6 +1,7 @@ package io.xpipe.ext.base.service; import io.xpipe.app.ext.DataStore; +import io.xpipe.app.ext.DataStoreDependencies; import io.xpipe.app.ext.FixedChildStore; import io.xpipe.app.ext.NetworkTunnelStore; import io.xpipe.app.storage.DataStoreEntryRef; @@ -14,6 +15,7 @@ import lombok.ToString; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.List; import java.util.OptionalInt; @SuperBuilder(toBuilder = true) @@ -28,6 +30,11 @@ public class FixedServiceStore extends AbstractServiceStore implements FixedChil private final DataStoreEntryRef displayParent; private final Boolean tunnelToLocalhost; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(host); + } + @Override public String getAddress() { return null; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStore.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStore.java index dfcec5212..69a97f4cd 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStore.java @@ -44,6 +44,11 @@ public class IncusContainerStore String containerName; IdentityValue identity; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(install, identity != null ? identity.getDependencies() : null); + } + @Override public Class getStateClass() { return NetworkContainerStoreState.class; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStore.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStore.java index e8dbee10b..8e8ed7fbc 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStore.java @@ -1,11 +1,6 @@ package io.xpipe.ext.system.incus; -import io.xpipe.app.ext.DataStoreState; -import io.xpipe.app.ext.FixedChildStore; -import io.xpipe.app.ext.FixedHierarchyStore; -import io.xpipe.app.ext.SelfReferentialStore; -import io.xpipe.app.ext.ShellStore; -import io.xpipe.app.ext.StatefulDataStore; +import io.xpipe.app.ext.*; import io.xpipe.app.process.CommandSupport; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; @@ -34,6 +29,11 @@ public class IncusInstallStore this.host = host; } + @Override + public List> getDependencies() { + return DataStoreDependencies.of(host); + } + @Override public void checkComplete() throws Throwable { Validators.nonNull(host); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStore.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStore.java index c5f00239a..7a9661090 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStore.java @@ -1,11 +1,6 @@ package io.xpipe.ext.system.lxd; -import io.xpipe.app.ext.DataStoreState; -import io.xpipe.app.ext.FixedChildStore; -import io.xpipe.app.ext.FixedHierarchyStore; -import io.xpipe.app.ext.SelfReferentialStore; -import io.xpipe.app.ext.ShellStore; -import io.xpipe.app.ext.StatefulDataStore; +import io.xpipe.app.ext.*; import io.xpipe.app.process.CommandSupport; import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.Validators; @@ -31,6 +26,11 @@ public class LxdCmdStore implements FixedHierarchyStore, StatefulDataStore> getDependencies() { + return DataStoreDependencies.of(host); + } + @Override public void checkComplete() throws Throwable { Validators.nonNull(host); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStore.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStore.java index 5cdbd9cd2..4fd2bcc94 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStore.java @@ -16,6 +16,7 @@ import lombok.Value; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.List; import java.util.Objects; import java.util.OptionalInt; @@ -37,6 +38,11 @@ public class LxdContainerStore String containerName; IdentityValue identity; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(cmd); + } + @Override public String getName() { return containerName; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStore.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStore.java index 020f78abb..804c92275 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStore.java @@ -30,6 +30,11 @@ public class PodmanCmdStore this.host = host; } + @Override + public List> getDependencies() { + return DataStoreDependencies.of(host); + } + @Override public void checkComplete() throws Throwable { Validators.nonNull(host); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java index 6d0342e0e..c83a05204 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java @@ -41,6 +41,11 @@ public class PodmanContainerStore DataStoreEntryRef cmd; String containerName; + @Override + public List> getDependencies() { + return DataStoreDependencies.of(cmd); + } + @Override public String getName() { return containerName;