Migrate all actions, fix various bugs

This commit is contained in:
crschnick 2023-02-09 21:06:58 +00:00
parent 51bbf8ad67
commit 7be8087b19
19 changed files with 298 additions and 207 deletions

View file

@ -171,13 +171,18 @@ public class StoreEntryComp extends SimpleComp {
var button = new IconButtonComp( var button = new IconButtonComp(
actionProvider.getIcon(entry.getEntry().getStore().asNeeded()), () -> { actionProvider.getIcon(entry.getEntry().getStore().asNeeded()), () -> {
ThreadHelper.runFailableAsync(() -> { ThreadHelper.runFailableAsync(() -> {
var action = actionProvider.createAction(entry.getEntry().getStore().asNeeded()); var action = actionProvider.createAction(
entry.getEntry().getStore().asNeeded());
action.execute(); action.execute();
}); });
}); });
button.apply(new FancyTooltipAugment<>( button.apply(new FancyTooltipAugment<>(
actionProvider.getName(entry.getEntry().getStore().asNeeded()))); actionProvider.getName(entry.getEntry().getStore().asNeeded())));
if (!actionProvider.showIfDisabled()) {
button.hide(Bindings.not(p.getValue()));
} else {
button.disable(Bindings.not(p.getValue())); button.disable(Bindings.not(p.getValue()));
}
list.add(button); list.add(button);
} }
@ -227,7 +232,8 @@ public class StoreEntryComp extends SimpleComp {
var item = new MenuItem(null, new FontIcon(icon)); var item = new MenuItem(null, new FontIcon(icon));
item.setOnAction(event -> { item.setOnAction(event -> {
ThreadHelper.runFailableAsync(() -> { ThreadHelper.runFailableAsync(() -> {
var action = actionProvider.createAction(entry.getEntry().getStore().asNeeded()); var action = actionProvider.createAction(
entry.getEntry().getStore().asNeeded());
action.execute(); action.execute();
}); });
}); });
@ -245,7 +251,8 @@ public class StoreEntryComp extends SimpleComp {
if (AppPrefs.get().developerMode().getValue()) { if (AppPrefs.get().developerMode().getValue()) {
var browse = new MenuItem(I18n.get("browse"), new FontIcon("mdi2f-folder-open-outline")); var browse = new MenuItem(I18n.get("browse"), new FontIcon("mdi2f-folder-open-outline"));
browse.setOnAction(event -> DesktopHelper.browsePath(entry.getEntry().getDirectory())); browse.setOnAction(
event -> DesktopHelper.browsePath(entry.getEntry().getDirectory()));
contextMenu.getItems().add(browse); contextMenu.getItems().add(browse);
} }

View file

@ -11,6 +11,10 @@ public class DataStateProviderImpl extends DataStateProvider {
@Override @Override
public void putState(DataStore store, String key, Object value) { public void putState(DataStore store, String key, Object value) {
if (DataStorage.get() == null) {
return;
}
var entry = DataStorage.get().getEntryByStore(store); var entry = DataStorage.get().getEntryByStore(store);
if (entry.isEmpty()) { if (entry.isEmpty()) {
return; return;
@ -22,6 +26,10 @@ public class DataStateProviderImpl extends DataStateProvider {
@Override @Override
public <T> T getState(DataStore store, String key, Class<T> c, Supplier<T> def) { public <T> T getState(DataStore store, String key, Class<T> c, Supplier<T> def) {
if (DataStorage.get() == null) {
return def.get();
}
var entry = DataStorage.get().getEntryByStore(store); var entry = DataStorage.get().getEntryByStore(store);
if (entry.isEmpty()) { if (entry.isEmpty()) {
return def.get(); return def.get();

View file

@ -74,10 +74,6 @@ public abstract class DataStorage {
} }
public static DataStorage get() { public static DataStorage get() {
if (INSTANCE == null) {
throw new IllegalStateException("Not initialized");
}
return INSTANCE; return INSTANCE;
} }
@ -175,6 +171,10 @@ public abstract class DataStorage {
} }
public Optional<DataSourceCollection> getCollectionForName(String name) { public Optional<DataSourceCollection> getCollectionForName(String name) {
if (name == null) {
return Optional.ofNullable(getInternalCollection());
}
return sourceCollections.stream() return sourceCollections.stream()
.filter(c -> name.equalsIgnoreCase(c.getName())) .filter(c -> name.equalsIgnoreCase(c.getName()))
.findAny(); .findAny();

View file

@ -13,7 +13,7 @@ public abstract class TerminalProvider {
@Override @Override
public void init(ModuleLayer layer) { public void init(ModuleLayer layer) {
ServiceLoader.load(layer, TerminalProvider.class).findFirst().orElseThrow(); INSTANCE = ServiceLoader.load(layer, TerminalProvider.class).findFirst().orElseThrow();
} }
@Override @Override

View file

@ -7,12 +7,14 @@ import io.xpipe.app.exchange.cli.*;
import io.xpipe.app.issue.EventHandlerImpl; import io.xpipe.app.issue.EventHandlerImpl;
import io.xpipe.app.storage.DataStateProviderImpl; import io.xpipe.app.storage.DataStateProviderImpl;
import io.xpipe.app.util.ProxyManagerProviderImpl; import io.xpipe.app.util.ProxyManagerProviderImpl;
import io.xpipe.app.util.TerminalProvider;
import io.xpipe.app.util.XPipeDaemonProvider; import io.xpipe.app.util.XPipeDaemonProvider;
import io.xpipe.core.util.DataStateProvider; import io.xpipe.core.util.DataStateProvider;
import io.xpipe.core.util.ProxyManagerProvider; import io.xpipe.core.util.ProxyManagerProvider;
import io.xpipe.extension.Cache; import io.xpipe.extension.Cache;
import io.xpipe.extension.I18n; import io.xpipe.extension.I18n;
import io.xpipe.extension.event.EventHandler; import io.xpipe.extension.event.EventHandler;
import io.xpipe.extension.util.ModuleLayerLoader;
import io.xpipe.extension.util.XPipeDaemon; import io.xpipe.extension.util.XPipeDaemon;
import org.slf4j.spi.SLF4JServiceProvider; import org.slf4j.spi.SLF4JServiceProvider;
@ -99,6 +101,7 @@ open module io.xpipe.app {
uses MessageExchangeImpl; uses MessageExchangeImpl;
uses io.xpipe.app.util.TerminalProvider; uses io.xpipe.app.util.TerminalProvider;
provides ModuleLayerLoader with TerminalProvider.Loader;
provides DataStateProvider with provides DataStateProvider with
DataStateProviderImpl; DataStateProviderImpl;
provides ProxyManagerProvider with provides ProxyManagerProvider with

View file

@ -41,7 +41,7 @@ public interface OsType {
@Override @Override
public String getTempDirectory(ShellProcessControl pc) throws Exception { public String getTempDirectory(ShellProcessControl pc) throws Exception {
return pc.executeStringSimpleCommand(ShellTypes.CMD, ShellTypes.CMD.getPrintVariableCommand("TEMP")); return pc.executeStringSimpleCommand(pc.getShellType().getPrintEnvironmentVariableCommand("TEMP"));
} }
@Override @Override
@ -52,7 +52,7 @@ public interface OsType {
@Override @Override
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception { public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
try (CommandProcessControl c = try (CommandProcessControl c =
pc.subShell(ShellTypes.CMD).command("systeminfo").start()) { pc.command("systeminfo").start()) {
var text = c.readOrThrow(); var text = c.readOrThrow();
return PropertiesFormatsParser.parse(text, ":"); return PropertiesFormatsParser.parse(text, ":");
} }

View file

@ -1,12 +1,12 @@
package io.xpipe.core.process; package io.xpipe.core.process;
import io.xpipe.core.util.FailableBiFunction;
import io.xpipe.core.util.FailableFunction;
import lombok.NonNull; import lombok.NonNull;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.function.BiFunction;
import java.util.function.Function;
public abstract class ProcessControlProvider { public abstract class ProcessControlProvider {
@ -18,21 +18,22 @@ public abstract class ProcessControlProvider {
} }
public static ShellProcessControl createLocal() { public static ShellProcessControl createLocal() {
return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.createLocalProcessControl()).findFirst().orElseThrow(); return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.createLocalProcessControl()).filter(
Objects::nonNull).findFirst().orElseThrow();
} }
public static ShellProcessControl createSub( public static ShellProcessControl createSub(
ShellProcessControl parent, ShellProcessControl parent,
@NonNull Function<ShellProcessControl, String> commandFunction, @NonNull FailableFunction<ShellProcessControl, String, Exception> commandFunction,
BiFunction<ShellProcessControl, String, String> terminalCommand) { FailableBiFunction<ShellProcessControl, String, String, Exception> terminalCommand) {
return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.sub(parent, commandFunction, terminalCommand)).filter( return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.sub(parent, commandFunction, terminalCommand)).filter(
Objects::nonNull).findFirst().orElseThrow(); Objects::nonNull).findFirst().orElseThrow();
} }
public static CommandProcessControl createCommand( public static CommandProcessControl createCommand(
ShellProcessControl parent, ShellProcessControl parent,
@NonNull Function<ShellProcessControl, String> command, @NonNull FailableFunction<ShellProcessControl, String, Exception> command,
Function<ShellProcessControl, String> terminalCommand) { FailableFunction<ShellProcessControl, String, Exception> terminalCommand) {
return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.command(parent, command, terminalCommand)).filter( return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.command(parent, command, terminalCommand)).filter(
Objects::nonNull).findFirst().orElseThrow(); Objects::nonNull).findFirst().orElseThrow();
} }
@ -44,13 +45,13 @@ public abstract class ProcessControlProvider {
public abstract ShellProcessControl sub( public abstract ShellProcessControl sub(
ShellProcessControl parent, ShellProcessControl parent,
@NonNull Function<ShellProcessControl, String> commandFunction, @NonNull FailableFunction<ShellProcessControl, String, Exception> commandFunction,
BiFunction<ShellProcessControl, String, String> terminalCommand); FailableBiFunction<ShellProcessControl, String, String, Exception> terminalCommand);
public abstract CommandProcessControl command( public abstract CommandProcessControl command(
ShellProcessControl parent, ShellProcessControl parent,
@NonNull Function<ShellProcessControl, String> command, @NonNull FailableFunction<ShellProcessControl, String, Exception> command,
Function<ShellProcessControl, String> terminalCommand); FailableFunction<ShellProcessControl, String, Exception> terminalCommand);
public abstract ShellProcessControl createLocalProcessControl(); public abstract ShellProcessControl createLocalProcessControl();

View file

@ -1,13 +1,13 @@
package io.xpipe.core.process; package io.xpipe.core.process;
import io.xpipe.core.util.FailableBiFunction;
import io.xpipe.core.util.FailableFunction;
import io.xpipe.core.util.SecretValue; import io.xpipe.core.util.SecretValue;
import lombok.NonNull; import lombok.NonNull;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
public interface ShellProcessControl extends ProcessControl { public interface ShellProcessControl extends ProcessControl {
@ -87,18 +87,18 @@ public interface ShellProcessControl extends ProcessControl {
} }
ShellProcessControl subShell( ShellProcessControl subShell(
@NonNull Function<ShellProcessControl, String> command, FailableFunction<ShellProcessControl, String, Exception> command,
BiFunction<ShellProcessControl, String, String> terminalCommand); FailableBiFunction<ShellProcessControl, String, String, Exception> terminalCommand);
void executeLine(String command) throws Exception; void executeLine(String command) throws Exception;
@Override @Override
ShellProcessControl start() throws Exception; ShellProcessControl start() throws Exception;
CommandProcessControl command(Function<ShellProcessControl, String> command); CommandProcessControl command(FailableFunction<ShellProcessControl, String, Exception> command);
CommandProcessControl command( CommandProcessControl command(
Function<ShellProcessControl, String> command, Function<ShellProcessControl, String> terminalCommand); FailableFunction<ShellProcessControl, String, Exception> command, FailableFunction<ShellProcessControl, String, Exception> terminalCommand);
default CommandProcessControl command(String command) { default CommandProcessControl command(String command) {
return command(shellProcessControl -> command); return command(shellProcessControl -> command);

View file

@ -60,11 +60,9 @@ public interface ShellType {
String getEchoCommand(String s, boolean toErrorStream); String getEchoCommand(String s, boolean toErrorStream);
default String getPrintVariableCommand(String name) { String getPrintVariableCommand(String name);
return getPrintVariableCommand("", name);
}
String getPrintVariableCommand(String prefix, String name); String getPrintExitCodeCommand(String prefix);
default String getPrintEnvironmentVariableCommand(String name) { default String getPrintEnvironmentVariableCommand(String name) {
return getPrintVariableCommand(name); return getPrintVariableCommand(name);

View file

@ -0,0 +1,7 @@
package io.xpipe.core.util;
@FunctionalInterface
public interface FailableBiFunction<T1, T2, R, E extends Throwable> {
R apply(T1 var1, T2 var2) throws E;
}

View file

@ -0,0 +1,7 @@
package io.xpipe.core.util;
@FunctionalInterface
public interface FailableFunction<T, R, E extends Throwable> {
R apply(T var1) throws E;
}

View file

@ -2,15 +2,41 @@ package io.xpipe.ext.base.actions;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.core.impl.LocalStore; import io.xpipe.core.impl.LocalStore;
import io.xpipe.extension.DataStoreActionProvider;
import io.xpipe.extension.I18n; import io.xpipe.extension.I18n;
import io.xpipe.extension.util.ActionProvider;
import io.xpipe.extension.util.DesktopHelper; import io.xpipe.extension.util.DesktopHelper;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import lombok.Value;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
public class FileBrowseAction implements DataStoreActionProvider<FileStore> { public class FileBrowseAction implements ActionProvider {
@Value
static class Action implements ActionProvider.Action {
FileStore store;
@Override
public boolean requiresPlatform() {
return false;
}
@Override
public void execute() throws Exception {
DesktopHelper.browseFileInDirectory(Path.of(store.getFile()));
}
}
@Override
public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<FileStore>() {
@Override
public ActionProvider.Action createAction(FileStore store) {
return new Action(store);
}
@Override @Override
public Class<FileStore> getApplicableClass() { public Class<FileStore> getApplicableClass() {
@ -31,9 +57,6 @@ public class FileBrowseAction implements DataStoreActionProvider<FileStore> {
public String getIcon(FileStore store) { public String getIcon(FileStore store) {
return "mdi2f-folder-open-outline"; return "mdi2f-folder-open-outline";
} }
};
@Override
public void execute(FileStore store) throws Exception {
DesktopHelper.browseFileInDirectory(Path.of(store.getFile()));
} }
} }

View file

@ -4,11 +4,42 @@ import io.xpipe.app.util.ExternalEditor;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.core.impl.LocalStore; import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataFlow;
import io.xpipe.extension.DataStoreActionProvider;
import io.xpipe.extension.I18n; import io.xpipe.extension.I18n;
import io.xpipe.extension.util.ActionProvider;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import lombok.Value;
public class FileEditAction implements DataStoreActionProvider<FileStore> { public class FileEditAction implements ActionProvider {
@Value
static class Action implements ActionProvider.Action {
FileStore store;
@Override
public boolean requiresPlatform() {
return false;
}
@Override
public void execute() throws Exception {
if (store.getFileSystem().equals(new LocalStore())) {
ExternalEditor.get().openInEditor(store.getFile());
} else {
ExternalEditor.get()
.startEditing(store.getFileName(), store.getFileExtension(), store, () -> store.openInput(), () -> store.openOutput());
}
}
}
@Override
public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<FileStore>() {
@Override
public ActionProvider.Action createAction(FileStore store) {
return new Action(store);
}
@Override @Override
public Class<FileStore> getApplicableClass() { public Class<FileStore> getApplicableClass() {
@ -29,14 +60,6 @@ public class FileEditAction implements DataStoreActionProvider<FileStore> {
public String getIcon(FileStore store) { public String getIcon(FileStore store) {
return "mdal-edit"; return "mdal-edit";
} }
};
@Override
public void execute(FileStore store) throws Exception {
if (store.getFileSystem().equals(new LocalStore())) {
ExternalEditor.get().openInEditor(store.getFile());
} else {
ExternalEditor.get()
.startEditing(store.getFileName(), store.getFileExtension(), store, () -> store.openInput(), () -> store.openOutput());
}
} }
} }

View file

@ -3,22 +3,57 @@ package io.xpipe.ext.base.actions;
import io.xpipe.app.core.AppActionLinkDetector; import io.xpipe.app.core.AppActionLinkDetector;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.core.util.SecretValue; import io.xpipe.core.util.SecretValue;
import io.xpipe.extension.DataStoreActionProvider;
import io.xpipe.extension.DataStoreProviders; import io.xpipe.extension.DataStoreProviders;
import io.xpipe.extension.I18n; import io.xpipe.extension.I18n;
import io.xpipe.extension.util.ActionProvider;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import lombok.Value;
import java.awt.*; import java.awt.*;
import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
public class ShareStoreAction implements DataStoreActionProvider<DataStore> { public class ShareStoreAction implements ActionProvider {
@Value
static class Action implements ActionProvider.Action {
DataStore store;
@Override
public boolean requiresPlatform() {
return false;
}
public static String create(DataStore store) {
return "xpipe://add/store/" + SecretValue.encrypt(store.toString()).getEncryptedValue();
}
@Override
public void execute() throws Exception {
var string = create(store);
var selection = new StringSelection(string);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
AppActionLinkDetector.setLastDetectedAction(string);
clipboard.setContents(selection, selection);
}
}
@Override
public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<DataStore>() {
@Override @Override
public boolean showIfDisabled() { public boolean showIfDisabled() {
return false; return false;
} }
@Override
public ActionProvider.Action createAction(DataStore store) {
return new Action(store);
}
@Override @Override
public Class<DataStore> getApplicableClass() { public Class<DataStore> getApplicableClass() {
return DataStore.class; return DataStore.class;
@ -38,17 +73,6 @@ public class ShareStoreAction implements DataStoreActionProvider<DataStore> {
public String getIcon(DataStore store) { public String getIcon(DataStore store) {
return "mdi2c-clipboard-list-outline"; return "mdi2c-clipboard-list-outline";
} }
};
public static String create(DataStore store) {
return "xpipe://add/store/" + SecretValue.encrypt(store.toString()).getEncryptedValue();
}
@Override
public void execute(DataStore store) throws Exception {
var string = create(store);
var selection = new StringSelection(string);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
AppActionLinkDetector.setLastDetectedAction(string);
clipboard.setContents(selection, selection);
} }
} }

View file

@ -1,41 +1,33 @@
package io.xpipe.ext.base.actions; package io.xpipe.ext.base.actions;
import io.xpipe.core.store.StreamDataStore; import io.xpipe.core.store.StreamDataStore;
import io.xpipe.extension.DataStoreActionProvider;
import io.xpipe.extension.I18n; import io.xpipe.extension.I18n;
import io.xpipe.extension.event.ErrorEvent; import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.util.ActionProvider;
import io.xpipe.extension.util.DesktopHelper; import io.xpipe.extension.util.DesktopHelper;
import io.xpipe.extension.util.ThreadHelper; import io.xpipe.extension.util.ThreadHelper;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import lombok.Value;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.Files; import java.nio.file.Files;
public class StreamExportAction implements DataStoreActionProvider<StreamDataStore> { public class StreamExportAction implements ActionProvider {
@Value
static class Action implements ActionProvider.Action {
StreamDataStore store;
@Override @Override
public Class<StreamDataStore> getApplicableClass() { public boolean requiresPlatform() {
return StreamDataStore.class; return false;
} }
@Override @Override
public boolean isApplicable(StreamDataStore o) throws Exception { public void execute() throws Exception {
return o.getFlow() != null && o.getFlow().hasInput();
}
@Override
public ObservableValue<String> getName(StreamDataStore store) {
return I18n.observable("base.exportStream");
}
@Override
public String getIcon(StreamDataStore store) {
return "mdi2f-file-export-outline";
}
@Override
public void execute(StreamDataStore store) throws Exception {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(I18n.get("browseFileTitle")); fileChooser.setTitle(I18n.get("browseFileTitle"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), ".")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "."));
@ -56,3 +48,37 @@ public class StreamExportAction implements DataStoreActionProvider<StreamDataSto
}); });
} }
} }
@Override
public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<StreamDataStore>() {
@Override
public Action createAction(StreamDataStore store) {
return new Action(store);
}
@Override
public boolean isApplicable(StreamDataStore o) throws Exception {
return o.getFlow() != null && o.getFlow().hasInput();
}
@Override
public Class<StreamDataStore> getApplicableClass() {
return StreamDataStore.class;
}
@Override
public ObservableValue<String> getName(StreamDataStore store) {
return I18n.observable("base.exportStream");
}
@Override
public String getIcon(StreamDataStore store) {
return "mdi2f-file-export-outline";
}
};
}
}

View file

@ -2,7 +2,6 @@ import io.xpipe.ext.base.*;
import io.xpipe.ext.base.actions.*; import io.xpipe.ext.base.actions.*;
import io.xpipe.ext.base.apps.*; import io.xpipe.ext.base.apps.*;
import io.xpipe.extension.DataSourceProvider; import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataStoreActionProvider;
import io.xpipe.extension.DataStoreProvider; import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.DataSourceTarget; import io.xpipe.extension.DataSourceTarget;
import io.xpipe.extension.util.ActionProvider; import io.xpipe.extension.util.ActionProvider;
@ -22,8 +21,7 @@ open module io.xpipe.ext.base {
requires static net.synedra.validatorfx; requires static net.synedra.validatorfx;
requires static io.xpipe.app; requires static io.xpipe.app;
provides ActionProvider with AddStoreAction; provides ActionProvider with AddStoreAction,
provides DataStoreActionProvider with
StreamExportAction, StreamExportAction,
ShareStoreAction, ShareStoreAction,
FileBrowseAction, FileBrowseAction,

View file

@ -1,59 +0,0 @@
package io.xpipe.extension;
import io.xpipe.core.store.DataStore;
import io.xpipe.extension.event.ErrorEvent;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.Region;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
public interface DataStoreActionProvider<T extends DataStore> {
static List<DataStoreActionProvider<?>> ALL = new ArrayList<>();
public static void init(ModuleLayer layer) {
if (ALL.size() == 0) {
ALL.addAll(ServiceLoader.load(layer, DataStoreActionProvider.class).stream()
.map(p -> (DataStoreActionProvider<?>) p.get())
.filter(provider -> {
try {
return provider.isActive();
} catch (Throwable e) {
ErrorEvent.fromThrowable(e).handle();
return false;
}
})
.toList());
}
}
Class<T> getApplicableClass();
default boolean isMajor() {
return false;
}
default boolean isActive() throws Exception {
return true;
}
default boolean isApplicable(T o) throws Exception {
return true;
}
default void applyToRegion(T store, Region region) {
}
ObservableValue<String> getName(T store);
String getIcon(T store);
default void execute(T store) throws Exception {
}
default boolean showIfDisabled() {
return true;
}
}

View file

@ -9,6 +9,7 @@ import io.xpipe.core.util.SecretValue;
import io.xpipe.extension.event.TrackEvent; import io.xpipe.extension.event.TrackEvent;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@ -91,6 +92,18 @@ public class ScriptHelper {
} "$@" } "$@"
"""; """;
public static String unquote(String input) {
if (input.startsWith("\"") && input.endsWith("\"")) {
return input.substring(1, input.length() - 1);
}
if (input.startsWith("'") && input.endsWith("'")) {
return input.substring(1, input.length() - 1);
}
return input;
}
public static String constructOpenWithInitScriptCommand( public static String constructOpenWithInitScriptCommand(
ShellProcessControl processControl, List<String> init, String toExecuteInShell) { ShellProcessControl processControl, List<String> init, String toExecuteInShell) {
ShellType t = processControl.getShellType(); ShellType t = processControl.getShellType();
@ -98,6 +111,20 @@ public class ScriptHelper {
return t.getNormalOpenCommand(); return t.getNormalOpenCommand();
} }
if (init.size() == 0) {
var cmd = unquote(toExecuteInShell);
// Check for special case of the command to be executed just being another shell script
if (cmd.endsWith(".sh") || cmd.endsWith(".bat")) {
return t.executeCommandWithShell(cmd);
}
// Check for special case of the command being a shell command
if (Arrays.stream(ShellTypes.getAllShellTypes()).anyMatch(shellType -> cmd.equals(shellType.getNormalOpenCommand()))) {
return cmd;
}
}
String nl = t.getNewLine().getNewLineString(); String nl = t.getNewLine().getNewLineString();
var content = String.join(nl, init) + nl; var content = String.join(nl, init) + nl;

View file

@ -1,6 +1,5 @@
import io.xpipe.core.util.ProxyFunction; import io.xpipe.core.util.ProxyFunction;
import io.xpipe.extension.DataSourceProvider; import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataStoreActionProvider;
import io.xpipe.extension.DataSourceTarget; import io.xpipe.extension.DataSourceTarget;
import io.xpipe.extension.prefs.PrefsProvider; import io.xpipe.extension.prefs.PrefsProvider;
import io.xpipe.extension.util.ActionProvider; import io.xpipe.extension.util.ActionProvider;
@ -45,7 +44,6 @@ open module io.xpipe.extension {
uses DataSourceProvider; uses DataSourceProvider;
uses DataSourceTarget; uses DataSourceTarget;
uses DataStoreActionProvider;
uses io.xpipe.extension.I18n; uses io.xpipe.extension.I18n;
uses io.xpipe.extension.event.EventHandler; uses io.xpipe.extension.event.EventHandler;
uses io.xpipe.extension.prefs.PrefsProvider; uses io.xpipe.extension.prefs.PrefsProvider;