diff --git a/api/src/main/java/io/xpipe/api/DataSource.java b/api/src/main/java/io/xpipe/api/DataSource.java index b81f8233b..62cc8d65c 100644 --- a/api/src/main/java/io/xpipe/api/DataSource.java +++ b/api/src/main/java/io/xpipe/api/DataSource.java @@ -1,7 +1,7 @@ package io.xpipe.api; import io.xpipe.api.impl.DataSourceImpl; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceReference; import io.xpipe.core.source.DataSourceType; import io.xpipe.core.store.DataStore; @@ -96,16 +96,16 @@ public interface DataSource { } /** - * Wrapper for {@link #create(DataSourceId, String, InputStream)} that creates an anonymous data source. + * Wrapper for {@link #create(DataStoreId, String, InputStream)} that creates an anonymous data source. */ static DataSource createAnonymous(String type, Path path) { return create(null, type, path); } /** - * Wrapper for {@link #create(DataSourceId, String, InputStream)}. + * Wrapper for {@link #create(DataStoreId, String, InputStream)}. */ - static DataSource create(DataSourceId id, String type, Path path) { + static DataSource create(DataStoreId id, String type, Path path) { try (var in = Files.newInputStream(path)) { return create(id, type, in); } catch (IOException e) { @@ -114,16 +114,16 @@ public interface DataSource { } /** - * Wrapper for {@link #create(DataSourceId, String, InputStream)} that creates an anonymous data source. + * Wrapper for {@link #create(DataStoreId, String, InputStream)} that creates an anonymous data source. */ static DataSource createAnonymous(String type, URL url) { return create(null, type, url); } /** - * Wrapper for {@link #create(DataSourceId, String, InputStream)}. + * Wrapper for {@link #create(DataStoreId, String, InputStream)}. */ - static DataSource create(DataSourceId id, String type, URL url) { + static DataSource create(DataStoreId id, String type, URL url) { try (var in = url.openStream()) { return create(id, type, in); } catch (IOException e) { @@ -132,7 +132,7 @@ public interface DataSource { } /** - * Wrapper for {@link #create(DataSourceId, String, InputStream)} that creates an anonymous data source. + * Wrapper for {@link #create(DataStoreId, String, InputStream)} that creates an anonymous data source. */ static DataSource createAnonymous(String type, InputStream in) { return create(null, type, in); @@ -146,7 +146,7 @@ public interface DataSource { * @param in the input stream to read * @return a {@link DataSource} instances that can be used to access the underlying data */ - static DataSource create(DataSourceId id, String type, InputStream in) { + static DataSource create(DataStoreId id, String type, InputStream in) { return DataSourceImpl.create(id, type, in); } @@ -156,7 +156,7 @@ public interface DataSource { * @param id the data source id * @return a {@link DataSource} instances that can be used to access the underlying data */ - static DataSource create(DataSourceId id, io.xpipe.core.source.DataSource source) { + static DataSource create(DataStoreId id, io.xpipe.core.source.DataSource source) { return DataSourceImpl.create(id, source); } @@ -169,7 +169,7 @@ public interface DataSource { * @param in the data store to add * @return a {@link DataSource} instances that can be used to access the underlying data */ - static DataSource create(DataSourceId id, String type, DataStore in) { + static DataSource create(DataStoreId id, String type, DataStore in) { return DataSourceImpl.create(id, type, in); } @@ -182,7 +182,7 @@ public interface DataSource { /** * Returns the id of this data source. */ - DataSourceId getId(); + DataStoreId getId(); /** * Returns the type of this data source. diff --git a/api/src/main/java/io/xpipe/api/DataTableAccumulator.java b/api/src/main/java/io/xpipe/api/DataTableAccumulator.java index 5b8897946..768037193 100644 --- a/api/src/main/java/io/xpipe/api/DataTableAccumulator.java +++ b/api/src/main/java/io/xpipe/api/DataTableAccumulator.java @@ -4,14 +4,14 @@ import io.xpipe.api.impl.DataTableAccumulatorImpl; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.DataStructureNodeAcceptor; import io.xpipe.core.data.type.TupleType; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; /** * An accumulator for table data. *

* This class can be used to construct new table data sources by * accumulating the rows using {@link #add(DataStructureNode)} or {@link #acceptor()} and then calling - * {@link #finish(DataSourceId)} to complete the construction process and create a new data source. + * {@link #finish(DataStoreId)} to complete the construction process and create a new data source. */ public interface DataTableAccumulator { @@ -20,10 +20,10 @@ public interface DataTableAccumulator { } /** - * Wrapper for {@link #finish(DataSourceId)}. + * Wrapper for {@link #finish(DataStoreId)}. */ default DataTable finish(String id) { - return finish(DataSourceId.fromString(id)); + return finish(DataStoreId.fromString(id)); } /** @@ -31,7 +31,7 @@ public interface DataTableAccumulator { * * @param id the data source id to assign */ - DataTable finish(DataSourceId id); + DataTable finish(DataStoreId id); /** * Adds a row to the table. diff --git a/api/src/main/java/io/xpipe/api/impl/DataRawImpl.java b/api/src/main/java/io/xpipe/api/impl/DataRawImpl.java index d9059ee02..4f63432f1 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataRawImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataRawImpl.java @@ -2,7 +2,7 @@ package io.xpipe.api.impl; import io.xpipe.api.DataRaw; import io.xpipe.api.DataSourceConfig; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceType; import java.io.InputStream; @@ -10,7 +10,7 @@ import java.io.InputStream; public class DataRawImpl extends DataSourceImpl implements DataRaw { public DataRawImpl( - DataSourceId sourceId, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { + DataStoreId sourceId, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { super(sourceId, sourceConfig, internalSource); } diff --git a/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java b/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java index 4d3b904be..e43af2464 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java @@ -4,7 +4,7 @@ import io.xpipe.api.DataSource; import io.xpipe.api.DataSourceConfig; import io.xpipe.api.connector.XPipeApiConnection; import io.xpipe.beacon.exchange.*; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceReference; import io.xpipe.core.store.DataStore; import io.xpipe.core.store.StreamDataStore; @@ -13,12 +13,12 @@ import java.io.InputStream; public abstract class DataSourceImpl implements DataSource { - private final DataSourceId sourceId; + private final DataStoreId sourceId; private final DataSourceConfig config; private final io.xpipe.core.source.DataSource internalSource; public DataSourceImpl( - DataSourceId sourceId, DataSourceConfig config, io.xpipe.core.source.DataSource internalSource) { + DataStoreId sourceId, DataSourceConfig config, io.xpipe.core.source.DataSource internalSource) { this.sourceId = sourceId; this.config = config; this.internalSource = internalSource; @@ -48,7 +48,7 @@ public abstract class DataSourceImpl implements DataSource { }); } - public static DataSource create(DataSourceId id, io.xpipe.core.source.DataSource source) { + public static DataSource create(DataStoreId id, io.xpipe.core.source.DataSource source) { var startReq = AddSourceExchange.Request.builder().source(source).target(id).build(); var returnedId = XPipeApiConnection.execute(con -> { @@ -60,7 +60,7 @@ public abstract class DataSourceImpl implements DataSource { return get(ref); } - public static DataSource create(DataSourceId id, String type, DataStore store) { + public static DataSource create(DataStoreId id, String type, DataStore store) { if (store instanceof StreamDataStore s && s.isContentExclusivelyAccessible()) { store = XPipeApiConnection.execute(con -> { var internal = con.createInternalStreamStore(); @@ -94,7 +94,7 @@ public abstract class DataSourceImpl implements DataSource { return get(ref); } - public static DataSource create(DataSourceId id, String type, InputStream in) { + public static DataSource create(DataStoreId id, String type, InputStream in) { var store = XPipeApiConnection.execute(con -> { var internal = con.createInternalStreamStore(); var req = WriteStreamExchange.Request.builder() @@ -152,7 +152,7 @@ public abstract class DataSourceImpl implements DataSource { } @Override - public DataSourceId getId() { + public DataStoreId getId() { return sourceId; } diff --git a/api/src/main/java/io/xpipe/api/impl/DataStructureImpl.java b/api/src/main/java/io/xpipe/api/impl/DataStructureImpl.java index d21a37e14..f1e2f8ca1 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataStructureImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataStructureImpl.java @@ -3,13 +3,13 @@ package io.xpipe.api.impl; import io.xpipe.api.DataSourceConfig; import io.xpipe.api.DataStructure; import io.xpipe.core.data.node.DataStructureNode; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceType; public class DataStructureImpl extends DataSourceImpl implements DataStructure { DataStructureImpl( - DataSourceId sourceId, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { + DataStoreId sourceId, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { super(sourceId, sourceConfig, internalSource); } diff --git a/api/src/main/java/io/xpipe/api/impl/DataTableAccumulatorImpl.java b/api/src/main/java/io/xpipe/api/impl/DataTableAccumulatorImpl.java index 1a9a65838..cf89065d9 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataTableAccumulatorImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataTableAccumulatorImpl.java @@ -16,7 +16,7 @@ import io.xpipe.core.data.node.TupleNode; import io.xpipe.core.data.type.TupleType; import io.xpipe.core.data.typed.TypedDataStreamWriter; import io.xpipe.core.impl.InternalStreamStore; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceReference; import java.io.IOException; @@ -51,7 +51,7 @@ public class DataTableAccumulatorImpl implements DataTableAccumulator { } @Override - public synchronized DataTable finish(DataSourceId id) { + public synchronized DataTable finish(DataStoreId id) { try { bodyOutput.close(); } catch (IOException e) { diff --git a/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java b/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java index 436ac3167..4862964c6 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataTableImpl.java @@ -5,7 +5,7 @@ import io.xpipe.api.DataTable; import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.TupleNode; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceType; import java.util.ArrayList; @@ -15,7 +15,7 @@ import java.util.stream.Stream; public class DataTableImpl extends DataSourceImpl implements DataTable { - DataTableImpl(DataSourceId id, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { + DataTableImpl(DataStoreId id, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { super(id, sourceConfig, internalSource); } diff --git a/api/src/main/java/io/xpipe/api/impl/DataTextImpl.java b/api/src/main/java/io/xpipe/api/impl/DataTextImpl.java index c4c72f22a..19658e9ce 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataTextImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataTextImpl.java @@ -2,7 +2,7 @@ package io.xpipe.api.impl; import io.xpipe.api.DataSourceConfig; import io.xpipe.api.DataText; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import io.xpipe.core.source.DataSourceType; import java.util.List; @@ -12,7 +12,7 @@ import java.util.stream.Stream; public class DataTextImpl extends DataSourceImpl implements DataText { DataTextImpl( - DataSourceId sourceId, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { + DataStoreId sourceId, DataSourceConfig sourceConfig, io.xpipe.core.source.DataSource internalSource) { super(sourceId, sourceConfig, internalSource); } diff --git a/api/src/test/java/io/xpipe/api/test/DataTableTest.java b/api/src/test/java/io/xpipe/api/test/DataTableTest.java index e8138be46..95ef63d3b 100644 --- a/api/src/test/java/io/xpipe/api/test/DataTableTest.java +++ b/api/src/test/java/io/xpipe/api/test/DataTableTest.java @@ -1,7 +1,7 @@ package io.xpipe.api.test; import io.xpipe.api.DataSource; -import io.xpipe.core.source.DataSourceId; +import io.xpipe.core.source.DataStoreId; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -10,7 +10,7 @@ public class DataTableTest extends ApiTest { @BeforeAll public static void setupStorage() throws Exception { DataSource.create( - DataSourceId.fromString(":usernames"), "csv", DataTableTest.class.getResource("username.csv")); + DataStoreId.fromString(":usernames"), "csv", DataTableTest.class.getResource("username.csv")); } @Test diff --git a/app/build.gradle b/app/build.gradle index 24d0a9d3d..f4049fdbb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -156,11 +156,12 @@ run { // systemProperty "io.xpipe.beacon.localProxy", "true" - systemProperties System.getProperties() systemProperty 'java.library.path', "./lib" + workingDir = rootDir } task runAttachedDebugger(type: JavaExec) { + workingDir = rootDir classpath = run.classpath mainModule = 'io.xpipe.app' mainClass = 'io.xpipe.app.Main' diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserBreadcrumbBar.java b/app/src/main/java/io/xpipe/app/browser/BrowserBreadcrumbBar.java index e955e76cf..5b8b55a1f 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserBreadcrumbBar.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserBreadcrumbBar.java @@ -4,6 +4,7 @@ import atlantafx.base.controls.Breadcrumbs; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.impl.FileNames; import javafx.scene.Node; import javafx.scene.control.Button; @@ -80,7 +81,9 @@ public class BrowserBreadcrumbBar extends SimpleComp { } breadcrumbs.selectedCrumbProperty().addListener((obs, old, val) -> { - model.cd(val != null ? val.getValue() : null); + ThreadHelper.runFailableAsync(() -> { + model.cdSync(val != null ? val.getValue() : null); + }); }); return breadcrumbs; diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileListCompEntry.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileListCompEntry.java index b6ef2b4b4..5514c1cfd 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileListCompEntry.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileListCompEntry.java @@ -200,7 +200,7 @@ public class BrowserFileListCompEntry { return; } - model.getFileSystemModel().cd(item.getRawFileEntry().getPath()); + model.getFileSystemModel().cdSync(item.getRawFileEntry().getPath()); } }; DROP_TIMER.schedule(activeTask, 1000); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java index 1b05d7074..c9af527b5 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileListModel.java @@ -128,7 +128,7 @@ public final class BrowserFileListModel { } if (entry.getRawFileEntry().resolved().getKind() == FileKind.DIRECTORY) { - fileSystemModel.cd(entry.getRawFileEntry().resolved().getPath()); + fileSystemModel.cdSync(entry.getRawFileEntry().resolved().getPath()); } } } diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileOverviewComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileOverviewComp.java index 0bb081633..bb35dd139 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileOverviewComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileOverviewComp.java @@ -31,7 +31,7 @@ public class BrowserFileOverviewComp extends SimpleComp { var icon = BrowserIcons.createIcon(entry); var l = new Button(entry.getPath(), icon.createRegion()); l.setOnAction(event -> { - model.cd(entry.getPath()); + model.cdSync(entry.getPath()); event.consume(); }); l.setAlignment(Pos.CENTER_LEFT); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java index 89880b896..457d154fb 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java @@ -11,6 +11,8 @@ import io.xpipe.app.fxcomps.impl.PrettyImageComp; import io.xpipe.app.fxcomps.impl.StackComp; import io.xpipe.app.fxcomps.impl.TextFieldComp; import io.xpipe.app.fxcomps.util.SimpleChangeListener; +import io.xpipe.app.util.ThreadHelper; +import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; import javafx.css.PseudoClass; @@ -42,8 +44,10 @@ public class BrowserNavBar extends SimpleComp { path.set(newValue); }); path.addListener((observable, oldValue, newValue) -> { - var changed = model.cdOrRetry(newValue, true); - changed.ifPresent(path::set); + ThreadHelper.runFailableAsync(() -> { + var changed = model.cdSyncOrRetry(newValue, true); + changed.ifPresent(s -> Platform.runLater(() -> path.set(s))); + }); }); var pathBar = new TextFieldComp(path, true) diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java index 2a5316821..38a2b2531 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java @@ -57,6 +57,10 @@ public class BrowserWelcomeComp extends SimpleComp { return; } + if (!entry.get().getState().isUsable()) { + return; + } + var graphic = entry.get().getProvider().getDisplayIconFileName(entry.get().getStore()); var view = new PrettyImageComp(new SimpleStringProperty(graphic), 45, 45); diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java index 1977fb5d3..e44efd795 100644 --- a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java @@ -43,7 +43,7 @@ public class OpenFileSystemComp extends SimpleComp { private Region createContent() { var overview = new Button(null, new FontIcon("mdi2m-monitor")); - overview.setOnAction(e -> model.cd(null)); + overview.setOnAction(e -> model.cdSync(null)); overview.disableProperty().bind(model.getInOverview()); overview.setAccessibleText("System overview"); diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java index a8b528117..bd4051973 100644 --- a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java @@ -107,11 +107,11 @@ public final class OpenFileSystemModel { return new FileSystem.FileEntry(fileSystem, currentPath.get(), null, false, false, 0, null, FileKind.DIRECTORY); } - public void cd(String path) { - cdOrRetry(path, false).ifPresent(s -> cdOrRetry(s, false)); + public void cdSync(String path) { + cdSyncOrRetry(path, false).ifPresent(s -> cdSyncOrRetry(s, false)); } - public Optional cdOrRetry(String path, boolean allowCommands) { + public Optional cdSyncOrRetry(String path, boolean allowCommands) { if (Objects.equals(path, currentPath.get())) { return Optional.empty(); } @@ -179,16 +179,12 @@ public final class OpenFileSystemModel { try { FileSystemHelper.validateDirectoryPath(this, resolvedPath); + cdSyncWithoutCheck(path); } catch (Exception ex) { ErrorEvent.fromThrowable(ex).handle(); return Optional.ofNullable(currentPath.get()); } - ThreadHelper.runFailableAsync(() -> { - try (var ignored = new BusyProperty(busy)) { - cdSyncWithoutCheck(path); - } - }); return Optional.empty(); } diff --git a/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java b/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java index 5b85b5fc2..cd6136a8e 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ButtonComp.java @@ -11,8 +11,10 @@ import javafx.css.Size; import javafx.css.SizeUnits; import javafx.scene.Node; import javafx.scene.control.Button; +import lombok.Getter; import org.kordamp.ikonli.javafx.FontIcon; +@Getter public class ButtonComp extends Comp> { private final ObservableValue name; @@ -31,10 +33,6 @@ public class ButtonComp extends Comp> { this.listener = listener; } - public ObservableValue getName() { - return name; - } - public Node getGraphic() { return graphic.get(); } @@ -43,10 +41,6 @@ public class ButtonComp extends Comp> { return graphic; } - public Runnable getListener() { - return listener; - } - @Override public CompStructure