mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 00:50:31 +00:00
Cleanup
This commit is contained in:
parent
ad92311a7d
commit
d58abf83b9
56 changed files with 320 additions and 376 deletions
|
@ -2,7 +2,7 @@ package io.xpipe.app.comp.about;
|
|||
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.editor.EditorState;
|
||||
import io.xpipe.app.util.ExternalEditor;
|
||||
import io.xpipe.app.issue.UserReportComp;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
import io.xpipe.extension.I18n;
|
||||
|
@ -30,7 +30,7 @@ public class BrowseDirectoryComp extends SimpleComp {
|
|||
.addComp(
|
||||
"logFile",
|
||||
new ButtonComp(I18n.observable("openCurrentLogFile"), () -> {
|
||||
EditorState.get().openInEditor(AppLogs.get().getSessionLogsDirectory().resolve("xpipe.log").toString());
|
||||
ExternalEditor.get().openInEditor(AppLogs.get().getSessionLogsDirectory().resolve("xpipe.log").toString());
|
||||
}),
|
||||
null)
|
||||
.addComp(
|
||||
|
|
|
@ -2,7 +2,7 @@ package io.xpipe.app.comp.about;
|
|||
|
||||
import io.xpipe.extension.util.XPipeDistributionType;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.grid.AppUpdater;
|
||||
import io.xpipe.app.update.AppUpdater;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.fxcomps.SimpleComp;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.editor.EditorState;
|
||||
import io.xpipe.app.util.ExternalEditor;
|
||||
import io.xpipe.extension.fxcomps.Comp;
|
||||
import io.xpipe.extension.fxcomps.SimpleComp;
|
||||
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
|
||||
|
@ -45,7 +45,7 @@ public class IntegratedTextAreaComp extends SimpleComp {
|
|||
}
|
||||
|
||||
private Region createOpenButton(Region container) {
|
||||
var button = new IconButtonComp("mdal-edit", () -> EditorState.get()
|
||||
var button = new IconButtonComp("mdal-edit", () -> ExternalEditor.get()
|
||||
.startEditing(identifier, fileType, this, value.getValue(), (s) -> {
|
||||
Platform.runLater(() -> value.setValue(s));
|
||||
})).createRegion();
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.comp.source;
|
|||
import io.xpipe.app.comp.base.MultiStepComp;
|
||||
import io.xpipe.app.comp.source.store.DsDbStoreChooserComp;
|
||||
import io.xpipe.app.comp.source.store.DsStreamStoreChoiceComp;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.core.source.DataSource;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.extension.DataSourceProvider;
|
||||
|
@ -42,7 +41,7 @@ public class GuiDsStoreSelectStep extends MultiStepComp.Step<CompStructure<? ext
|
|||
DataSourceProvider.Category category,
|
||||
ObjectProperty<? extends DataSource<?>> baseSource,
|
||||
BooleanProperty loading) {
|
||||
super(Hyperlinks.openLink(Hyperlinks.DOCS_DATA_INPUT));
|
||||
super(null);
|
||||
this.parent = parent;
|
||||
this.provider = provider;
|
||||
this.input = input;
|
||||
|
|
|
@ -33,12 +33,15 @@ public class SourceEntryContextMenu<S extends CompStructure<?>> extends PopupMen
|
|||
AppFont.normal(cm.getStyleableNode());
|
||||
|
||||
for (var actionProvider : entry.getActionProviders()) {
|
||||
var name = actionProvider.getName(entry.getEntry().getSource().asNeeded());
|
||||
var icon = actionProvider.getIcon(entry.getEntry().getSource().asNeeded());
|
||||
var c = actionProvider.getDataSourceCallSite();
|
||||
var name = c.getName(entry.getEntry().getSource().asNeeded());
|
||||
var icon = c.getIcon(entry.getEntry().getSource().asNeeded());
|
||||
var item = new MenuItem(null, new FontIcon(icon));
|
||||
item.setOnAction(event -> {
|
||||
event.consume();
|
||||
try {
|
||||
actionProvider.execute(entry.getEntry().getSource().asNeeded());
|
||||
var action = c.createAction(entry.getEntry().getSource().asNeeded());
|
||||
action.execute();
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
}
|
||||
|
|
|
@ -4,16 +4,17 @@ import io.xpipe.app.comp.source.GuiDsCreatorMultiStep;
|
|||
import io.xpipe.app.comp.storage.StorageFilter;
|
||||
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
|
||||
import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper;
|
||||
import io.xpipe.app.storage.*;
|
||||
import io.xpipe.app.storage.DataSourceEntry;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.StorageElement;
|
||||
import io.xpipe.core.source.DataSource;
|
||||
import io.xpipe.core.store.DataFlow;
|
||||
import io.xpipe.extension.DataSourceActionProvider;
|
||||
import io.xpipe.extension.DataStoreProviders;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import io.xpipe.extension.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.extension.util.ActionProvider;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import lombok.Value;
|
||||
|
||||
import java.time.Instant;
|
||||
|
@ -29,13 +30,10 @@ public class SourceEntryWrapper implements StorageFilter.Filterable {
|
|||
StringProperty information = new SimpleStringProperty();
|
||||
StringProperty storeSummary = new SimpleStringProperty();
|
||||
Property<Instant> lastUsed = new SimpleObjectProperty<>();
|
||||
Property<AccessMode> accessMode = new SimpleObjectProperty<>();
|
||||
Property<DataFlow> dataFlow = new SimpleObjectProperty<>();
|
||||
ObjectProperty<DataSourceEntry.State> state = new SimpleObjectProperty<>();
|
||||
BooleanProperty loading = new SimpleBooleanProperty();
|
||||
|
||||
List<DataSourceActionProvider<?>> actionProviders = new ArrayList<>();
|
||||
ListProperty<ApplicationAccess> accesses = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||
List<ActionProvider> actionProviders = new ArrayList<>();
|
||||
|
||||
public SourceEntryWrapper(DataSourceEntry entry) {
|
||||
this.entry = entry;
|
||||
|
@ -100,16 +98,21 @@ public class SourceEntryWrapper implements StorageFilter.Filterable {
|
|||
loading.setValue(entry.getState() == null || entry.getState() == DataSourceEntry.State.VALIDATING);
|
||||
|
||||
actionProviders.clear();
|
||||
actionProviders.addAll(DataSourceActionProvider.ALL.stream()
|
||||
actionProviders.addAll(ActionProvider.ALL.stream()
|
||||
.filter(p -> {
|
||||
try {
|
||||
if (!entry.getState().isUsable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return p.getApplicableClass()
|
||||
var c = p.getDataSourceCallSite();
|
||||
if (c == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return c.getApplicableClass()
|
||||
.isAssignableFrom(entry.getSource().getClass())
|
||||
&& p.isApplicable(entry.getSource().asNeeded());
|
||||
&& c.isApplicable(entry.getSource().asNeeded());
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
return false;
|
||||
|
|
|
@ -45,9 +45,9 @@ public class SourceStorageEmptyIntroComp extends SimpleComp {
|
|||
documentation.heightProperty().addListener((c, o, n) -> {
|
||||
dfi.iconSizeProperty().set(n.intValue());
|
||||
});
|
||||
var docLink = new Hyperlink(Hyperlinks.DOCS_GETTING_STARTED);
|
||||
var docLink = new Hyperlink(Hyperlinks.DOCUMENTATION);
|
||||
docLink.setOnAction(e -> {
|
||||
Hyperlinks.open(Hyperlinks.DOCS_GETTING_STARTED);
|
||||
Hyperlinks.open(Hyperlinks.DOCUMENTATION);
|
||||
});
|
||||
var docLinkPane = new StackPane(docLink);
|
||||
docLinkPane.setAlignment(Pos.CENTER);
|
||||
|
|
|
@ -51,9 +51,9 @@ public class StoreStorageEmptyIntroComp extends SimpleComp {
|
|||
documentation.heightProperty().addListener((c, o, n) -> {
|
||||
dofi.iconSizeProperty().set(n.intValue());
|
||||
});
|
||||
var docLink = new Hyperlink(Hyperlinks.DOCS_GETTING_STARTED);
|
||||
var docLink = new Hyperlink(Hyperlinks.DOCUMENTATION);
|
||||
docLink.setOnAction(e -> {
|
||||
Hyperlinks.open(Hyperlinks.DOCS_GETTING_STARTED);
|
||||
Hyperlinks.open(Hyperlinks.DOCUMENTATION);
|
||||
});
|
||||
var docLinkPane = new StackPane(docLink);
|
||||
docLinkPane.setAlignment(Pos.CENTER);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import io.xpipe.app.util.ConfigHelper;
|
||||
import io.xpipe.app.util.JsonConfigHelper;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.extension.Cache;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
|
@ -49,7 +49,7 @@ public class AppCache implements Cache {
|
|||
var path = getPath(key);
|
||||
if (Files.exists(path)) {
|
||||
try {
|
||||
var tree = ConfigHelper.readConfig(path);
|
||||
var tree = JsonConfigHelper.readConfig(path);
|
||||
if (tree.isMissingNode()) {
|
||||
return notPresent.get();
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class AppCache implements Cache {
|
|||
try {
|
||||
FileUtils.forceMkdirParent(path.toFile());
|
||||
var tree = JacksonMapper.newMapper().valueToTree(val);
|
||||
ConfigHelper.writeConfig(path, tree);
|
||||
JsonConfigHelper.writeConfig(path, tree);
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable("Could not parse cached data for key " + key, e)
|
||||
.omitted(true)
|
||||
|
|
|
@ -4,11 +4,16 @@ import io.xpipe.app.prefs.AppPrefs;
|
|||
import io.xpipe.app.prefs.SupportedLocale;
|
||||
import io.xpipe.app.util.ModuleHelper;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.Translatable;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import io.xpipe.extension.event.TrackEvent;
|
||||
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment;
|
||||
import io.xpipe.extension.prefs.PrefsChoiceValue;
|
||||
import io.xpipe.extension.util.DynamicOptionsBuilder;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
|
||||
|
@ -89,11 +94,31 @@ public class AppI18n implements I18n {
|
|||
prettyTime = null;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static String getCallerModuleName() {
|
||||
var callers = ModuleHelper.CallingClass.INSTANCE.getCallingClasses();
|
||||
for (Class<?> caller : callers) {
|
||||
if (caller.equals(ModuleHelper.CallingClass.class)
|
||||
|| caller.equals(ModuleHelper.class)
|
||||
|| caller.equals(AppI18n.class)
|
||||
|| caller.equals(I18n.class)
|
||||
|| caller.equals(FancyTooltipAugment.class)
|
||||
|| caller.equals(PrefsChoiceValue.class)
|
||||
|| caller.equals(Translatable.class)
|
||||
|| caller.equals(DynamicOptionsBuilder.class)) {
|
||||
continue;
|
||||
}
|
||||
var split = caller.getModule().getName().split("\\.");
|
||||
return split[split.length - 1];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey(String s) {
|
||||
var key = s;
|
||||
if (!s.contains(".")) {
|
||||
key = ModuleHelper.getCallerModuleName() + "." + s;
|
||||
key = getCallerModuleName() + "." + s;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package io.xpipe.app.core.mode;
|
|||
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
|
||||
import io.xpipe.app.comp.storage.store.StoreViewState;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.editor.EditorState;
|
||||
import io.xpipe.app.grid.AppUpdater;
|
||||
import io.xpipe.app.util.ExternalEditor;
|
||||
import io.xpipe.app.update.AppUpdater;
|
||||
import io.xpipe.app.issue.BasicErrorHandler;
|
||||
import io.xpipe.app.issue.ErrorHandler;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
|
@ -40,7 +40,7 @@ public class BaseMode extends OperationMode {
|
|||
AppCharsetter.init();
|
||||
DataStorage.init();
|
||||
FileWatchManager.init();
|
||||
EditorState.init();
|
||||
ExternalEditor.init();
|
||||
AppSocketServer.init();
|
||||
AppUpdater.init();
|
||||
TrackEvent.info("mode", "Finished base components initialization");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.xpipe.app.core.mode;
|
||||
|
||||
import io.xpipe.app.grid.UpdateChangelogAlert;
|
||||
import io.xpipe.app.update.UpdateChangelogAlert;
|
||||
import io.xpipe.app.core.App;
|
||||
import io.xpipe.app.core.AppGreetings;
|
||||
import io.xpipe.app.issue.ErrorHandler;
|
||||
|
|
|
@ -3,7 +3,7 @@ package io.xpipe.app.core.mode;
|
|||
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
|
||||
import io.xpipe.app.comp.storage.store.StoreViewState;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.grid.UpdateAvailableAlert;
|
||||
import io.xpipe.app.update.UpdateAvailableAlert;
|
||||
import io.xpipe.extension.event.TrackEvent;
|
||||
import io.xpipe.extension.util.ThreadHelper;
|
||||
import javafx.application.Application;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.xpipe.app.exchange.cli;
|
||||
|
||||
import io.xpipe.app.exchange.MessageExchangeImpl;
|
||||
import io.xpipe.app.storage.XPipeInstanceHelper;
|
||||
import io.xpipe.app.update.XPipeInstanceHelper;
|
||||
import io.xpipe.beacon.BeaconHandler;
|
||||
import io.xpipe.beacon.exchange.cli.InstanceExchange;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
|
|
|
@ -3,7 +3,7 @@ package io.xpipe.app.issue;
|
|||
import io.sentry.Sentry;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.grid.AppUpdater;
|
||||
import io.xpipe.app.update.AppUpdater;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import javafx.application.Platform;
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.xpipe.extension.prefs.PrefsChoiceValue;
|
|||
import io.xpipe.extension.prefs.PrefsHandler;
|
||||
import io.xpipe.extension.prefs.PrefsProvider;
|
||||
import io.xpipe.extension.util.XPipeDistributionType;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -26,6 +27,24 @@ import java.util.*;
|
|||
|
||||
public class AppPrefs {
|
||||
|
||||
private static ObservableBooleanValue bindDeveloperTrue(ObservableBooleanValue o) {
|
||||
return Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return AppPrefs.get().developerMode().getValue() || o.get();
|
||||
},
|
||||
o,
|
||||
AppPrefs.get().developerMode());
|
||||
}
|
||||
|
||||
private static ObservableBooleanValue bindDeveloperFalse(ObservableBooleanValue o) {
|
||||
return Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return !AppPrefs.get().developerMode().getValue() || o.get();
|
||||
},
|
||||
o,
|
||||
AppPrefs.get().developerMode());
|
||||
}
|
||||
|
||||
private static final int tooltipDelayMin = 0;
|
||||
private static final int tooltipDelayMax = 1500;
|
||||
private static final int fontSizeMin = 10;
|
||||
|
@ -134,7 +153,7 @@ public class AppPrefs {
|
|||
private final ObjectProperty<Path> effectiveStorageDirectory = STORAGE_DIR_FIXED
|
||||
? new SimpleObjectProperty<>(AppProperties.get().getDataDir().resolve("storage"))
|
||||
: internalStorageDirectory;
|
||||
private final StringField storageDirectoryControl = Fields.ofPath(effectiveStorageDirectory)
|
||||
private final StringField storageDirectoryControl = PrefFields.ofPath(effectiveStorageDirectory)
|
||||
.editable(!STORAGE_DIR_FIXED)
|
||||
.validate(
|
||||
CustomValidators.absolutePath(),
|
||||
|
@ -230,24 +249,24 @@ public class AppPrefs {
|
|||
return effectiveDeveloperMode;
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty developerDisableUpdateVersionCheck() {
|
||||
return developerDisableUpdateVersionCheck;
|
||||
public ObservableBooleanValue developerDisableUpdateVersionCheck() {
|
||||
return bindDeveloperTrue(developerDisableUpdateVersionCheck);
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty developerDisableGuiRestrictions() {
|
||||
return developerDisableGuiRestrictions;
|
||||
public ObservableBooleanValue developerDisableGuiRestrictions() {
|
||||
return bindDeveloperTrue(developerDisableGuiRestrictions);
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty developerDisableConnectorInstallationVersionCheck() {
|
||||
return developerDisableConnectorInstallationVersionCheck;
|
||||
public ObservableBooleanValue developerDisableConnectorInstallationVersionCheck() {
|
||||
return bindDeveloperTrue(developerDisableConnectorInstallationVersionCheck);
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty developerShowHiddenProviders() {
|
||||
return developerShowHiddenProviders;
|
||||
public ObservableBooleanValue developerShowHiddenProviders() {
|
||||
return bindDeveloperTrue(developerShowHiddenProviders);
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty developerShowHiddenEntries() {
|
||||
return developerShowHiddenEntries;
|
||||
public ObservableBooleanValue developerShowHiddenEntries() {
|
||||
return bindDeveloperTrue(developerShowHiddenEntries);
|
||||
}
|
||||
|
||||
private AppPreferencesFx preferencesFx;
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
|||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.util.ConfigHelper;
|
||||
import io.xpipe.app.util.JsonConfigHelper;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import io.xpipe.extension.event.TrackEvent;
|
||||
|
@ -32,7 +32,7 @@ public class JsonStorageHandler implements StorageHandler {
|
|||
|
||||
private JsonNode getContent(String key) {
|
||||
if (content == null) {
|
||||
content = (ObjectNode) ConfigHelper.readConfig(file);
|
||||
content = (ObjectNode) JsonConfigHelper.readConfig(file);
|
||||
}
|
||||
return content.get(key);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class JsonStorageHandler implements StorageHandler {
|
|||
}
|
||||
|
||||
void save() {
|
||||
ConfigHelper.writeConfig(file, content);
|
||||
JsonConfigHelper.writeConfig(file, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,7 +11,7 @@ import javafx.util.StringConverter;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Fields {
|
||||
public class PrefFields {
|
||||
|
||||
public static StringField ofPath(ObjectProperty<Path> fileProperty) {
|
||||
StringProperty stringProperty = new SimpleStringProperty();
|
|
@ -1,6 +0,0 @@
|
|||
package io.xpipe.app.storage;
|
||||
|
||||
public enum AccessMode {
|
||||
READ,
|
||||
WRITE
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package io.xpipe.app.storage;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public record ApplicationAccess(String name, UUID uuid, Instant start, AccessMode mode) {}
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.app.grid;
|
||||
package io.xpipe.app.update;
|
||||
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
|
@ -1,10 +1,10 @@
|
|||
package io.xpipe.app.grid;
|
||||
package io.xpipe.app.update;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.util.TerminalProvider;
|
||||
import io.xpipe.core.impl.FileNames;
|
||||
import io.xpipe.core.impl.LocalProcessControlProvider;
|
||||
import io.xpipe.core.process.CommandProcessControl;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
|
@ -196,8 +196,7 @@ public class AppInstaller {
|
|||
var command = "set -x\n" + "DEBIAN_FRONTEND=noninteractive sudo apt-get remove -qy xpipe\n"
|
||||
+ "DEBIAN_FRONTEND=noninteractive sudo apt-get install -qy \"" + file + "\"\n"
|
||||
+ "xpipe daemon start";
|
||||
var script = ScriptHelper.createLocalExecScript(command);
|
||||
LocalProcessControlProvider.get().openInTerminal("X-Pipe Updater", script);
|
||||
TerminalProvider.open("X-Pipe Updater", command);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,8 +222,7 @@ public class AppInstaller {
|
|||
@Override
|
||||
public void installLocal(String file) throws Exception {
|
||||
var command = "set -x\n" + "sudo rpm -U -v --force \"" + file + "\"\n" + "xpipe daemon start";
|
||||
var script = ScriptHelper.createLocalExecScript(command);
|
||||
LocalProcessControlProvider.get().openInTerminal("X-Pipe Updater", script);
|
||||
TerminalProvider.open("X-Pipe Updater", command);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,8 +248,7 @@ public class AppInstaller {
|
|||
@Override
|
||||
public void installLocal(String file) throws Exception {
|
||||
var command = "set -x\n" + "sudo installer -verboseR -allowUntrusted -pkg \"" + file + "\" -target /\n" + "xpipe daemon start";
|
||||
var script = ScriptHelper.createLocalExecScript(command);
|
||||
LocalProcessControlProvider.get().openInTerminal("X-Pipe Updater", script);
|
||||
TerminalProvider.open("X-Pipe Updater", command);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.app.grid;
|
||||
package io.xpipe.app.update;
|
||||
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.extension.util.XPipeDistributionType;
|
||||
|
@ -6,7 +6,7 @@ import io.xpipe.app.core.AppExtensionManager;
|
|||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.impl.LocalProcessControlProvider;
|
||||
import io.xpipe.core.impl.ProcessControlProvider;
|
||||
import io.xpipe.core.util.XPipeSession;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import io.xpipe.extension.event.TrackEvent;
|
||||
|
@ -112,7 +112,7 @@ public class AppUpdater {
|
|||
if (layer == null) {
|
||||
return;
|
||||
}
|
||||
LocalProcessControlProvider.init(layer);
|
||||
ProcessControlProvider.init(layer);
|
||||
|
||||
INSTANCE = new AppUpdater();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.app.grid;
|
||||
package io.xpipe.app.update;
|
||||
|
||||
import io.xpipe.app.core.AppWindowHelper;
|
||||
import io.xpipe.extension.I18n;
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.app.grid;
|
||||
package io.xpipe.app.update;
|
||||
|
||||
import io.xpipe.app.comp.base.MarkdownComp;
|
||||
import io.xpipe.app.core.AppWindowHelper;
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.app.storage;
|
||||
package io.xpipe.app.update;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.beacon.XPipeInstance;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
|
@ -1,29 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.core.AppWindowHelper;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
import io.xpipe.extension.I18n;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.PasswordField;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class AskpassAlert {
|
||||
|
||||
public static SecretValue query() {
|
||||
AtomicReference<SecretValue> password = new AtomicReference<>();
|
||||
var result = AppWindowHelper.showBlockingAlert(alert -> {
|
||||
alert.setAlertType(Alert.AlertType.CONFIRMATION);
|
||||
alert.setTitle(I18n.get("providePassword"));
|
||||
alert.setHeaderText(I18n.get("queryPasswordDescription"));
|
||||
|
||||
var textField = new PasswordField();
|
||||
textField.textProperty().addListener((c, o, n) -> {
|
||||
password.set(new SecretValue(n));
|
||||
});
|
||||
alert.getDialogPane().setContent(textField);
|
||||
})
|
||||
.filter(buttonType -> buttonType.getButtonData().isDefaultButton());
|
||||
return result.isPresent() ? password.get() : null;
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
|
||||
public class DeveloperHelper {
|
||||
|
||||
public static ObservableBooleanValue bindTrue(ObservableBooleanValue o) {
|
||||
return Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return AppPrefs.get().developerMode().getValue() || o.get();
|
||||
},
|
||||
o,
|
||||
AppPrefs.get().developerMode());
|
||||
}
|
||||
|
||||
public static ObservableBooleanValue bindFalls(ObservableBooleanValue o) {
|
||||
return Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return !AppPrefs.get().developerMode().getValue() || o.get();
|
||||
},
|
||||
o,
|
||||
AppPrefs.get().developerMode());
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.app.editor;
|
||||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.core.FileWatchManager;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
|
@ -22,14 +22,14 @@ import java.util.UUID;
|
|||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EditorState {
|
||||
public class ExternalEditor {
|
||||
|
||||
private static final Path TEMP =
|
||||
FileUtils.getTempDirectory().toPath().resolve("xpipe").resolve("editor");
|
||||
private static EditorState INSTANCE;
|
||||
private static ExternalEditor INSTANCE;
|
||||
private final Set<Entry> openEntries = new CopyOnWriteArraySet<>();
|
||||
|
||||
public static EditorState get() {
|
||||
public static ExternalEditor get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class EditorState {
|
|||
}
|
||||
|
||||
public static void init() {
|
||||
INSTANCE = new EditorState();
|
||||
INSTANCE = new ExternalEditor();
|
||||
try {
|
||||
FileUtils.forceMkdir(TEMP.toFile());
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import com.vladsch.flexmark.util.sequence.Html5Entities;
|
||||
import io.xpipe.modulefs.ModuleFileSystem;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FlexmarkHelper {
|
||||
|
||||
public static void loadHtmlEscapes() {
|
||||
Class<?> c = null;
|
||||
try {
|
||||
c = Html5Entities.class;
|
||||
Html5Entities.entityToString(null);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
var field = c.getDeclaredField("NAMED_CHARACTER_REFERENCES");
|
||||
field.setAccessible(true);
|
||||
field.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
try (var fs = ModuleFileSystem.create("module:/com.vladsch.flexmark_util_html")) {
|
||||
var file = fs.getPath("com/vladsch/flexmark/util/html/entities.properties");
|
||||
try (var in = Files.newInputStream(file)) {
|
||||
var r = readEntities(in);
|
||||
field.set(null, r);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> readEntities(InputStream stream) {
|
||||
Map<String, String> entities = new HashMap<>();
|
||||
Charset charset = StandardCharsets.UTF_8;
|
||||
try {
|
||||
String line;
|
||||
InputStreamReader streamReader = new InputStreamReader(stream, charset);
|
||||
BufferedReader bufferedReader = new BufferedReader(streamReader);
|
||||
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
if (line.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
int equal = line.indexOf("=");
|
||||
String key = line.substring(0, equal);
|
||||
String value = line.substring(equal + 1);
|
||||
entities.put(key, value);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed reading data for HTML named character references", e);
|
||||
}
|
||||
entities.put("NewLine", "\n");
|
||||
return entities;
|
||||
}
|
||||
}
|
|
@ -9,17 +9,12 @@ import java.net.URI;
|
|||
public class Hyperlinks {
|
||||
|
||||
public static final String WEBSITE = "https://xpipe.io";
|
||||
public static final String DOCUMENTATION = "https://docs.xpipe.io";
|
||||
public static final String DOCUMENTATION = "https://xpipe.io/docs";
|
||||
public static final String GITHUB = "https://github.com/xpipe-io";
|
||||
public static final String DISCORD = "https://discord.gg/8y89vS8cRb";
|
||||
public static final String SLACK =
|
||||
"https://join.slack.com/t/x-pipe/shared_invite/zt-1awjq0t5j-5i4UjNJfNe1VN4b_auu6Cg";
|
||||
|
||||
public static final String GUIDE = "https://github.com/crschnick/pdx_unlimiter/wiki/User-Guide";
|
||||
public static final String DOCS_DATA_INPUT = "https://docs.xpipe.io/data-source-creation/data-input";
|
||||
public static final String DOCS_BASE = "https://docs.xpipe.io/";
|
||||
public static final String DOCS_GETTING_STARTED = "https://docs.xpipe.io/en/latest/index.html";
|
||||
public static final String DOCS_PRIVACY = "https://docs.xpipe.io/en/latest/privacy.html";
|
||||
public static final String DOCS_PRIVACY = "https://xpipe.io/docs/privacy";
|
||||
|
||||
public static Runnable openLink(String s) {
|
||||
return () -> open(s);
|
||||
|
|
|
@ -15,13 +15,13 @@ import java.io.StringWriter;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ConfigHelper {
|
||||
public class JsonConfigHelper {
|
||||
|
||||
public static JsonNode readConfig(Path in) {
|
||||
JsonNode node = JsonNodeFactory.instance.objectNode();
|
||||
try {
|
||||
if (Files.exists(in)) {
|
||||
ObjectMapper o = JacksonMapper.newMapper();
|
||||
ObjectMapper o = JacksonMapper.getDefault();
|
||||
node = o.readTree(Files.readAllBytes(in));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -41,7 +41,7 @@ public class ConfigHelper {
|
|||
var writer = new StringWriter();
|
||||
JsonFactory f = new JsonFactory();
|
||||
try (JsonGenerator g = f.createGenerator(writer).setPrettyPrinter(new DefaultPrettyPrinter())) {
|
||||
JacksonMapper.newMapper().writeTree(g, node);
|
||||
JacksonMapper.getDefault().writeTree(g, node);
|
||||
var newContent = writer.toString();
|
||||
Files.writeString(out, newContent);
|
||||
} catch (IOException e) {
|
|
@ -1,11 +1,5 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.Translatable;
|
||||
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment;
|
||||
import io.xpipe.extension.prefs.PrefsChoiceValue;
|
||||
import io.xpipe.extension.util.DynamicOptionsBuilder;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -13,26 +7,6 @@ import java.lang.reflect.Method;
|
|||
|
||||
public class ModuleHelper {
|
||||
|
||||
@SneakyThrows
|
||||
public static String getCallerModuleName() {
|
||||
var callers = CallingClass.INSTANCE.getCallingClasses();
|
||||
for (Class<?> caller : callers) {
|
||||
if (caller.equals(CallingClass.class)
|
||||
|| caller.equals(ModuleHelper.class)
|
||||
|| caller.equals(AppI18n.class)
|
||||
|| caller.equals(I18n.class)
|
||||
|| caller.equals(FancyTooltipAugment.class)
|
||||
|| caller.equals(PrefsChoiceValue.class)
|
||||
|| caller.equals(Translatable.class)
|
||||
|| caller.equals(DynamicOptionsBuilder.class)) {
|
||||
continue;
|
||||
}
|
||||
var split = caller.getModule().getName().split("\\.");
|
||||
return split[split.length - 1];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static boolean isImage() {
|
||||
return ModuleHelper.class
|
||||
.getProtectionDomain()
|
||||
|
|
|
@ -2,8 +2,8 @@ package io.xpipe.app.util;
|
|||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppWindowHelper;
|
||||
import io.xpipe.app.grid.AppDownloads;
|
||||
import io.xpipe.app.grid.AppInstaller;
|
||||
import io.xpipe.app.update.AppDownloads;
|
||||
import io.xpipe.app.update.AppInstaller;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.impl.FileNames;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
|
|
39
app/src/main/java/io/xpipe/app/util/TerminalProvider.java
Normal file
39
app/src/main/java/io/xpipe/app/util/TerminalProvider.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.extension.util.ModuleLayerLoader;
|
||||
import io.xpipe.extension.util.ScriptHelper;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
public abstract class TerminalProvider {
|
||||
|
||||
private static TerminalProvider INSTANCE;
|
||||
|
||||
public static class Loader implements ModuleLayerLoader {
|
||||
|
||||
@Override
|
||||
public void init(ModuleLayer layer) {
|
||||
ServiceLoader.load(layer, TerminalProvider.class).findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresFullDaemon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prioritizeLoading() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void open(String title, String command) throws Exception {
|
||||
if (command.contains("\n")) {
|
||||
command = ScriptHelper.createLocalExecScript(command);
|
||||
}
|
||||
|
||||
INSTANCE.openInTerminal(title, command);
|
||||
}
|
||||
|
||||
protected abstract void openInTerminal(String title, String command) throws Exception;
|
||||
}
|
|
@ -7,7 +7,7 @@ import io.xpipe.app.comp.source.store.NamedStoreChoiceComp;
|
|||
import io.xpipe.app.core.AppImages;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppResources;
|
||||
import io.xpipe.app.grid.AppDownloads;
|
||||
import io.xpipe.app.update.AppDownloads;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.charsetter.Charsetter;
|
||||
|
|
|
@ -27,8 +27,7 @@ open module io.xpipe.app {
|
|||
exports io.xpipe.app.prefs;
|
||||
exports io.xpipe.app.comp.source.store;
|
||||
exports io.xpipe.app.storage;
|
||||
exports io.xpipe.app.editor;
|
||||
exports io.xpipe.app.grid;
|
||||
exports io.xpipe.app.update;
|
||||
exports io.xpipe.app.comp.storage;
|
||||
exports io.xpipe.app.comp.storage.collection;
|
||||
|
||||
|
@ -98,6 +97,7 @@ open module io.xpipe.app {
|
|||
requires jdk.jdwp.agent;
|
||||
|
||||
uses MessageExchangeImpl;
|
||||
uses io.xpipe.app.util.TerminalProvider;
|
||||
|
||||
provides DataStateProvider with
|
||||
DataStateProviderImpl;
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
package io.xpipe.core.impl;
|
||||
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
public abstract class LocalProcessControlProvider {
|
||||
|
||||
private static LocalProcessControlProvider INSTANCE;
|
||||
|
||||
public static LocalProcessControlProvider get() {
|
||||
if (INSTANCE == null) {
|
||||
throw new IllegalStateException("Process control not initialized");
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static void init(ModuleLayer layer) {
|
||||
INSTANCE = layer != null
|
||||
? ServiceLoader.load(layer, LocalProcessControlProvider.class)
|
||||
.findFirst()
|
||||
.orElse(null)
|
||||
: ServiceLoader.load(LocalProcessControlProvider.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static ShellProcessControl create() {
|
||||
if (INSTANCE == null) {
|
||||
throw new IllegalStateException("Not initialized");
|
||||
}
|
||||
|
||||
return INSTANCE.createProcessControl();
|
||||
}
|
||||
|
||||
public abstract ShellProcessControl createProcessControl();
|
||||
|
||||
public abstract void openInTerminal(String title, String command) throws Exception;
|
||||
}
|
|
@ -48,7 +48,7 @@ public class LocalStore extends JacksonizedValue implements FileSystemStore, Mac
|
|||
|
||||
@Override
|
||||
public ShellProcessControl create() {
|
||||
return LocalProcessControlProvider.create();
|
||||
return ProcessControlProvider.createLocal();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package io.xpipe.core.impl;
|
||||
|
||||
import io.xpipe.core.process.CommandProcessControl;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class ProcessControlProvider {
|
||||
|
||||
private static List<ProcessControlProvider> INSTANCES;
|
||||
|
||||
public static void init(ModuleLayer layer) {
|
||||
INSTANCES = ServiceLoader.load(layer, ProcessControlProvider.class)
|
||||
.stream().map(localProcessControlProviderProvider -> localProcessControlProviderProvider.get()).toList();
|
||||
}
|
||||
|
||||
public static ShellProcessControl createLocal() {
|
||||
return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.createLocalProcessControl()).findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
public static ShellProcessControl createSub(
|
||||
ShellProcessControl parent,
|
||||
@NonNull Function<ShellProcessControl, String> commandFunction,
|
||||
BiFunction<ShellProcessControl, String, String> terminalCommand) {
|
||||
return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.sub(parent, commandFunction, terminalCommand)).findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
public static CommandProcessControl createCommand(
|
||||
ShellProcessControl parent,
|
||||
@NonNull Function<ShellProcessControl, String> command,
|
||||
Function<ShellProcessControl, String> terminalCommand) {
|
||||
return INSTANCES.stream().map(localProcessControlProvider -> localProcessControlProvider.command(parent, command, terminalCommand)).findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
public abstract ShellProcessControl sub(
|
||||
ShellProcessControl parent,
|
||||
@NonNull Function<ShellProcessControl, String> commandFunction,
|
||||
BiFunction<ShellProcessControl, String, String> terminalCommand);
|
||||
|
||||
public abstract CommandProcessControl command(
|
||||
ShellProcessControl parent,
|
||||
@NonNull Function<ShellProcessControl, String> command,
|
||||
Function<ShellProcessControl, String> terminalCommand);
|
||||
|
||||
public abstract ShellProcessControl createLocalProcessControl();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import io.xpipe.core.impl.LocalProcessControlProvider;
|
||||
import io.xpipe.core.impl.ProcessControlProvider;
|
||||
import io.xpipe.core.source.WriteMode;
|
||||
import io.xpipe.core.util.CoreJacksonModule;
|
||||
|
||||
|
@ -24,7 +24,7 @@ open module io.xpipe.core {
|
|||
|
||||
uses com.fasterxml.jackson.databind.Module;
|
||||
uses io.xpipe.core.source.WriteMode;
|
||||
uses LocalProcessControlProvider;
|
||||
uses ProcessControlProvider;
|
||||
uses io.xpipe.core.util.ProxyProvider;
|
||||
uses io.xpipe.core.util.ProxyManagerProvider;
|
||||
uses io.xpipe.core.util.DataStateProvider;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.xpipe.ext.base.actions;
|
||||
|
||||
import io.xpipe.app.editor.EditorState;
|
||||
import io.xpipe.app.util.ExternalEditor;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.store.DataFlow;
|
||||
|
@ -33,9 +33,9 @@ public class FileEditAction implements DataStoreActionProvider<FileStore> {
|
|||
@Override
|
||||
public void execute(FileStore store) throws Exception {
|
||||
if (store.getFileSystem().equals(new LocalStore())) {
|
||||
EditorState.get().openInEditor(store.getFile());
|
||||
ExternalEditor.get().openInEditor(store.getFile());
|
||||
} else {
|
||||
EditorState.get()
|
||||
ExternalEditor.get()
|
||||
.startEditing(store.getFileName(), store.getFileExtension(), store, () -> store.openInput(), () -> store.openOutput());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class CommandLineTarget implements DataSourceTarget {
|
|||
|
||||
@Override
|
||||
public String getSetupGuideURL() {
|
||||
return "https://docs.xpipe.io/en/latest/guide/cli/index.html";
|
||||
return "https://xpipe.io/docs/en/latest/guide/cli/index.html";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -118,6 +118,6 @@ public class JavaTarget implements DataSourceTarget {
|
|||
|
||||
@Override
|
||||
public String getSetupGuideURL() {
|
||||
return "https://docs.xpipe.io/en/latest/api/java.html";
|
||||
return "https://xpipe.io/docs/en/latest/api/java.html";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.xpipe.core.charsetter.NewLine;
|
|||
import io.xpipe.core.charsetter.StreamCharset;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import io.xpipe.core.impl.TextSource;
|
||||
import io.xpipe.extension.util.DaemonExtensionTest;
|
||||
import io.xpipe.extension.test.DaemonExtensionTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.xpipe.core.data.node.ValueNode;
|
|||
import io.xpipe.ext.csv.CsvDelimiter;
|
||||
import io.xpipe.ext.csv.CsvHeaderState;
|
||||
import io.xpipe.ext.csv.CsvSource;
|
||||
import io.xpipe.extension.util.DaemonExtensionTest;
|
||||
import io.xpipe.extension.test.DaemonExtensionTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package io.xpipe.extension;
|
||||
|
||||
import io.xpipe.core.source.DataSource;
|
||||
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 DataSourceActionProvider<T extends DataSource<?>> {
|
||||
|
||||
static List<DataSourceActionProvider<?>> ALL = new ArrayList<>();
|
||||
|
||||
public static void init(ModuleLayer layer) {
|
||||
if (ALL.size() == 0) {
|
||||
ALL.addAll(ServiceLoader.load(layer, DataSourceActionProvider.class).stream()
|
||||
.map(p -> (DataSourceActionProvider<?>) p.get())
|
||||
.filter(provider -> {
|
||||
try {
|
||||
return provider.isActive();
|
||||
} catch (Throwable e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.toList());
|
||||
}
|
||||
}
|
||||
|
||||
Class<T> getApplicableClass();
|
||||
|
||||
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 {
|
||||
}
|
||||
}
|
|
@ -31,6 +31,11 @@ public interface DataSourceTarget {
|
|||
public boolean requiresFullDaemon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prioritizeLoading() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<DataSourceTarget> byId(String id) {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package io.xpipe.extension;
|
||||
|
||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||
import io.xpipe.core.impl.LocalProcessControlProvider;
|
||||
import io.xpipe.core.impl.ProcessControlProvider;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.core.util.ProxyFunction;
|
||||
import io.xpipe.extension.event.TrackEvent;
|
||||
import io.xpipe.extension.prefs.PrefsProvider;
|
||||
import io.xpipe.extension.util.ActionProvider;
|
||||
import io.xpipe.extension.util.ModuleLayerLoader;
|
||||
import io.xpipe.extension.util.XPipeDaemon;
|
||||
|
||||
public class XPipeServiceProviders {
|
||||
|
||||
public static void load(ModuleLayer layer) {
|
||||
LocalProcessControlProvider.init(layer);
|
||||
var hasDaemon = XPipeDaemon.getInstanceIfPresent().isPresent();
|
||||
ModuleLayerLoader.loadAll(layer, hasDaemon, true);
|
||||
ProcessControlProvider.init(layer);
|
||||
|
||||
TrackEvent.info("Loading extension providers ...");
|
||||
DataSourceProviders.init(layer);
|
||||
|
@ -34,14 +34,10 @@ public class XPipeServiceProviders {
|
|||
});
|
||||
}
|
||||
|
||||
var hasDaemon = XPipeDaemon.getInstanceIfPresent().isPresent();
|
||||
ModuleLayerLoader.loadAll(layer, hasDaemon);
|
||||
ModuleLayerLoader.loadAll(layer, hasDaemon, false);
|
||||
|
||||
if (hasDaemon) {
|
||||
ActionProvider.init(layer);
|
||||
DataSourceActionProvider.init(layer);
|
||||
ProxyFunction.init(layer);
|
||||
PrefsProvider.init(layer);
|
||||
}
|
||||
|
||||
TrackEvent.info("Finished loading extension providers");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.extension.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.Field;
|
||||
import io.xpipe.extension.util.ModuleLayerLoader;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
@ -11,12 +12,24 @@ public abstract class PrefsProvider {
|
|||
|
||||
private static Set<PrefsProvider> ALL;
|
||||
|
||||
public static void init(ModuleLayer layer) {
|
||||
if (ALL == null) {
|
||||
public static class Loader implements ModuleLayerLoader {
|
||||
|
||||
@Override
|
||||
public void init(ModuleLayer layer) {
|
||||
ALL = ServiceLoader.load(layer, PrefsProvider.class).stream()
|
||||
.map(ServiceLoader.Provider::get)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresFullDaemon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prioritizeLoading() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<PrefsProvider> getAll() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.extension.util;
|
||||
package io.xpipe.extension.test;
|
||||
|
||||
import io.xpipe.api.DataSource;
|
||||
import io.xpipe.beacon.BeaconDaemonController;
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.extension.util;
|
||||
package io.xpipe.extension.test;
|
||||
|
||||
import io.xpipe.core.data.node.DataStructureNode;
|
||||
import io.xpipe.core.impl.FileStore;
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.extension.util;
|
||||
package io.xpipe.extension.test;
|
||||
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.core.util.XPipeSession;
|
|
@ -1,5 +1,6 @@
|
|||
package io.xpipe.extension.util;
|
||||
|
||||
import io.xpipe.core.source.DataSource;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -7,24 +8,37 @@ import javafx.beans.value.ObservableValue;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface ActionProvider {
|
||||
|
||||
static List<ActionProvider> ALL = new ArrayList<>();
|
||||
|
||||
public static void init(ModuleLayer layer) {
|
||||
if (ALL.size() == 0) {
|
||||
public static class Loader implements ModuleLayerLoader {
|
||||
|
||||
@Override
|
||||
public void init(ModuleLayer layer) {
|
||||
ALL.addAll(ServiceLoader.load(layer, ActionProvider.class).stream()
|
||||
.map(p -> (ActionProvider) p.get())
|
||||
.filter(provider -> {
|
||||
try {
|
||||
return provider.isActive();
|
||||
} catch (Throwable e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.toList());
|
||||
.map(actionProviderProvider -> actionProviderProvider.get())
|
||||
.filter(provider -> {
|
||||
try {
|
||||
return provider.isActive();
|
||||
} catch (Throwable e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresFullDaemon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prioritizeLoading() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,10 +53,9 @@ public interface ActionProvider {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
interface LauncherCallSite {
|
||||
|
||||
String getId();
|
||||
String getId();
|
||||
|
||||
Action createAction(List<String> args) throws Exception;
|
||||
}
|
||||
|
@ -55,6 +68,11 @@ public interface ActionProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
default DataSourceCallSite<?> getDataSourceCallSite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static interface DataStoreCallSite<T extends DataStore> {
|
||||
|
||||
Action createAction(T store);
|
||||
|
@ -64,6 +82,7 @@ public interface ActionProvider {
|
|||
default boolean isMajor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isApplicable(T o) throws Exception {
|
||||
return true;
|
||||
}
|
||||
|
@ -76,4 +95,27 @@ public interface ActionProvider {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface DataSourceCallSite<T extends DataSource<?>> {
|
||||
|
||||
Action createAction(T source);
|
||||
|
||||
Class<T> getApplicableClass();
|
||||
|
||||
default boolean isMajor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isApplicable(T o) throws Exception {
|
||||
return true;
|
||||
}
|
||||
|
||||
ObservableValue<String> getName(T source);
|
||||
|
||||
String getIcon(T source);
|
||||
|
||||
default boolean showIfDisabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,18 @@ import java.util.ServiceLoader;
|
|||
|
||||
public interface ModuleLayerLoader {
|
||||
|
||||
public static void loadAll(ModuleLayer layer, boolean hasDaemon) {
|
||||
public static void loadAll(ModuleLayer layer, boolean hasDaemon, boolean prioritization) {
|
||||
ServiceLoader.load(layer, ModuleLayerLoader.class).stream().forEach(moduleLayerLoaderProvider -> {
|
||||
var instance = moduleLayerLoaderProvider.get();
|
||||
try {
|
||||
if (instance.requiresFullDaemon() && !hasDaemon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance.prioritizeLoading() != prioritization) {
|
||||
return;
|
||||
}
|
||||
|
||||
instance.init(layer);
|
||||
} catch (Throwable t) {
|
||||
ErrorEvent.fromThrowable(t).handle();
|
||||
|
@ -23,4 +28,6 @@ public interface ModuleLayerLoader {
|
|||
public void init(ModuleLayer layer);
|
||||
|
||||
boolean requiresFullDaemon();
|
||||
|
||||
boolean prioritizeLoading();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import io.xpipe.core.util.ProxyFunction;
|
|||
import io.xpipe.extension.DataSourceProvider;
|
||||
import io.xpipe.extension.DataStoreActionProvider;
|
||||
import io.xpipe.extension.DataSourceTarget;
|
||||
import io.xpipe.extension.prefs.PrefsProvider;
|
||||
import io.xpipe.extension.util.ActionProvider;
|
||||
import io.xpipe.extension.util.ModuleLayerLoader;
|
||||
import io.xpipe.extension.util.XPipeDaemon;
|
||||
|
@ -51,10 +52,9 @@ open module io.xpipe.extension {
|
|||
uses io.xpipe.extension.DataStoreProvider;
|
||||
uses XPipeDaemon;
|
||||
uses io.xpipe.extension.Cache;
|
||||
uses io.xpipe.extension.DataSourceActionProvider;
|
||||
uses ProxyFunction;
|
||||
uses ActionProvider;
|
||||
uses io.xpipe.extension.util.ModuleLayerLoader;
|
||||
|
||||
provides ModuleLayerLoader with DataSourceTarget.Loader;
|
||||
provides ModuleLayerLoader with DataSourceTarget.Loader, ActionProvider.Loader, PrefsProvider.Loader;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue