mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-09-16 01:08:00 +12:00
Cleanup
This commit is contained in:
parent
8b4a59e8f0
commit
84d0a70ec8
61 changed files with 324 additions and 382 deletions
|
@ -2,7 +2,7 @@ package io.xpipe.app.comp.about;
|
||||||
|
|
||||||
import io.xpipe.app.comp.base.ButtonComp;
|
import io.xpipe.app.comp.base.ButtonComp;
|
||||||
import io.xpipe.app.core.AppLogs;
|
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.app.issue.UserReportComp;
|
||||||
import io.xpipe.core.util.XPipeInstallation;
|
import io.xpipe.core.util.XPipeInstallation;
|
||||||
import io.xpipe.extension.I18n;
|
import io.xpipe.extension.I18n;
|
||||||
|
@ -30,7 +30,7 @@ public class BrowseDirectoryComp extends SimpleComp {
|
||||||
.addComp(
|
.addComp(
|
||||||
"logFile",
|
"logFile",
|
||||||
new ButtonComp(I18n.observable("openCurrentLogFile"), () -> {
|
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)
|
null)
|
||||||
.addComp(
|
.addComp(
|
||||||
|
|
|
@ -2,7 +2,7 @@ package io.xpipe.app.comp.about;
|
||||||
|
|
||||||
import io.xpipe.extension.util.XPipeDistributionType;
|
import io.xpipe.extension.util.XPipeDistributionType;
|
||||||
import io.xpipe.app.core.AppI18n;
|
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.app.util.Hyperlinks;
|
||||||
import io.xpipe.extension.I18n;
|
import io.xpipe.extension.I18n;
|
||||||
import io.xpipe.extension.fxcomps.SimpleComp;
|
import io.xpipe.extension.fxcomps.SimpleComp;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.app.comp.base;
|
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.Comp;
|
||||||
import io.xpipe.extension.fxcomps.SimpleComp;
|
import io.xpipe.extension.fxcomps.SimpleComp;
|
||||||
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
|
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
|
||||||
|
@ -45,7 +45,7 @@ public class IntegratedTextAreaComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Region createOpenButton(Region container) {
|
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) -> {
|
.startEditing(identifier, fileType, this, value.getValue(), (s) -> {
|
||||||
Platform.runLater(() -> value.setValue(s));
|
Platform.runLater(() -> value.setValue(s));
|
||||||
})).createRegion();
|
})).createRegion();
|
||||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.comp.source;
|
||||||
import io.xpipe.app.comp.base.MultiStepComp;
|
import io.xpipe.app.comp.base.MultiStepComp;
|
||||||
import io.xpipe.app.comp.source.store.DsDbStoreChooserComp;
|
import io.xpipe.app.comp.source.store.DsDbStoreChooserComp;
|
||||||
import io.xpipe.app.comp.source.store.DsStreamStoreChoiceComp;
|
import io.xpipe.app.comp.source.store.DsStreamStoreChoiceComp;
|
||||||
import io.xpipe.app.util.Hyperlinks;
|
|
||||||
import io.xpipe.core.source.DataSource;
|
import io.xpipe.core.source.DataSource;
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
import io.xpipe.extension.DataSourceProvider;
|
import io.xpipe.extension.DataSourceProvider;
|
||||||
|
@ -42,7 +41,7 @@ public class GuiDsStoreSelectStep extends MultiStepComp.Step<CompStructure<? ext
|
||||||
DataSourceProvider.Category category,
|
DataSourceProvider.Category category,
|
||||||
ObjectProperty<? extends DataSource<?>> baseSource,
|
ObjectProperty<? extends DataSource<?>> baseSource,
|
||||||
BooleanProperty loading) {
|
BooleanProperty loading) {
|
||||||
super(Hyperlinks.openLink(Hyperlinks.DOCS_DATA_INPUT));
|
super(null);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.input = input;
|
this.input = input;
|
||||||
|
|
|
@ -33,12 +33,15 @@ public class SourceEntryContextMenu<S extends CompStructure<?>> extends PopupMen
|
||||||
AppFont.normal(cm.getStyleableNode());
|
AppFont.normal(cm.getStyleableNode());
|
||||||
|
|
||||||
for (var actionProvider : entry.getActionProviders()) {
|
for (var actionProvider : entry.getActionProviders()) {
|
||||||
var name = actionProvider.getName(entry.getEntry().getSource().asNeeded());
|
var c = actionProvider.getDataSourceCallSite();
|
||||||
var icon = actionProvider.getIcon(entry.getEntry().getSource().asNeeded());
|
var name = c.getName(entry.getEntry().getSource().asNeeded());
|
||||||
|
var icon = c.getIcon(entry.getEntry().getSource().asNeeded());
|
||||||
var item = new MenuItem(null, new FontIcon(icon));
|
var item = new MenuItem(null, new FontIcon(icon));
|
||||||
item.setOnAction(event -> {
|
item.setOnAction(event -> {
|
||||||
|
event.consume();
|
||||||
try {
|
try {
|
||||||
actionProvider.execute(entry.getEntry().getSource().asNeeded());
|
var action = c.createAction(entry.getEntry().getSource().asNeeded());
|
||||||
|
action.execute();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable(e).handle();
|
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.StorageFilter;
|
||||||
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
|
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
|
||||||
import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper;
|
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.source.DataSource;
|
||||||
import io.xpipe.core.store.DataFlow;
|
import io.xpipe.core.store.DataFlow;
|
||||||
import io.xpipe.extension.DataSourceActionProvider;
|
|
||||||
import io.xpipe.extension.DataStoreProviders;
|
import io.xpipe.extension.DataStoreProviders;
|
||||||
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.fxcomps.util.PlatformThread;
|
import io.xpipe.extension.fxcomps.util.PlatformThread;
|
||||||
|
import io.xpipe.extension.util.ActionProvider;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -29,13 +30,10 @@ public class SourceEntryWrapper implements StorageFilter.Filterable {
|
||||||
StringProperty information = new SimpleStringProperty();
|
StringProperty information = new SimpleStringProperty();
|
||||||
StringProperty storeSummary = new SimpleStringProperty();
|
StringProperty storeSummary = new SimpleStringProperty();
|
||||||
Property<Instant> lastUsed = new SimpleObjectProperty<>();
|
Property<Instant> lastUsed = new SimpleObjectProperty<>();
|
||||||
Property<AccessMode> accessMode = new SimpleObjectProperty<>();
|
|
||||||
Property<DataFlow> dataFlow = new SimpleObjectProperty<>();
|
Property<DataFlow> dataFlow = new SimpleObjectProperty<>();
|
||||||
ObjectProperty<DataSourceEntry.State> state = new SimpleObjectProperty<>();
|
ObjectProperty<DataSourceEntry.State> state = new SimpleObjectProperty<>();
|
||||||
BooleanProperty loading = new SimpleBooleanProperty();
|
BooleanProperty loading = new SimpleBooleanProperty();
|
||||||
|
List<ActionProvider> actionProviders = new ArrayList<>();
|
||||||
List<DataSourceActionProvider<?>> actionProviders = new ArrayList<>();
|
|
||||||
ListProperty<ApplicationAccess> accesses = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
||||||
|
|
||||||
public SourceEntryWrapper(DataSourceEntry entry) {
|
public SourceEntryWrapper(DataSourceEntry entry) {
|
||||||
this.entry = entry;
|
this.entry = entry;
|
||||||
|
@ -100,16 +98,21 @@ public class SourceEntryWrapper implements StorageFilter.Filterable {
|
||||||
loading.setValue(entry.getState() == null || entry.getState() == DataSourceEntry.State.VALIDATING);
|
loading.setValue(entry.getState() == null || entry.getState() == DataSourceEntry.State.VALIDATING);
|
||||||
|
|
||||||
actionProviders.clear();
|
actionProviders.clear();
|
||||||
actionProviders.addAll(DataSourceActionProvider.ALL.stream()
|
actionProviders.addAll(ActionProvider.ALL.stream()
|
||||||
.filter(p -> {
|
.filter(p -> {
|
||||||
try {
|
try {
|
||||||
if (!entry.getState().isUsable()) {
|
if (!entry.getState().isUsable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.getApplicableClass()
|
var c = p.getDataSourceCallSite();
|
||||||
|
if (c == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.getApplicableClass()
|
||||||
.isAssignableFrom(entry.getSource().getClass())
|
.isAssignableFrom(entry.getSource().getClass())
|
||||||
&& p.isApplicable(entry.getSource().asNeeded());
|
&& c.isApplicable(entry.getSource().asNeeded());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable(e).handle();
|
ErrorEvent.fromThrowable(e).handle();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -45,9 +45,9 @@ public class SourceStorageEmptyIntroComp extends SimpleComp {
|
||||||
documentation.heightProperty().addListener((c, o, n) -> {
|
documentation.heightProperty().addListener((c, o, n) -> {
|
||||||
dfi.iconSizeProperty().set(n.intValue());
|
dfi.iconSizeProperty().set(n.intValue());
|
||||||
});
|
});
|
||||||
var docLink = new Hyperlink(Hyperlinks.DOCS_GETTING_STARTED);
|
var docLink = new Hyperlink(Hyperlinks.DOCUMENTATION);
|
||||||
docLink.setOnAction(e -> {
|
docLink.setOnAction(e -> {
|
||||||
Hyperlinks.open(Hyperlinks.DOCS_GETTING_STARTED);
|
Hyperlinks.open(Hyperlinks.DOCUMENTATION);
|
||||||
});
|
});
|
||||||
var docLinkPane = new StackPane(docLink);
|
var docLinkPane = new StackPane(docLink);
|
||||||
docLinkPane.setAlignment(Pos.CENTER);
|
docLinkPane.setAlignment(Pos.CENTER);
|
||||||
|
|
|
@ -51,9 +51,9 @@ public class StoreStorageEmptyIntroComp extends SimpleComp {
|
||||||
documentation.heightProperty().addListener((c, o, n) -> {
|
documentation.heightProperty().addListener((c, o, n) -> {
|
||||||
dofi.iconSizeProperty().set(n.intValue());
|
dofi.iconSizeProperty().set(n.intValue());
|
||||||
});
|
});
|
||||||
var docLink = new Hyperlink(Hyperlinks.DOCS_GETTING_STARTED);
|
var docLink = new Hyperlink(Hyperlinks.DOCUMENTATION);
|
||||||
docLink.setOnAction(e -> {
|
docLink.setOnAction(e -> {
|
||||||
Hyperlinks.open(Hyperlinks.DOCS_GETTING_STARTED);
|
Hyperlinks.open(Hyperlinks.DOCUMENTATION);
|
||||||
});
|
});
|
||||||
var docLinkPane = new StackPane(docLink);
|
var docLinkPane = new StackPane(docLink);
|
||||||
docLinkPane.setAlignment(Pos.CENTER);
|
docLinkPane.setAlignment(Pos.CENTER);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.app.core;
|
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.core.util.JacksonMapper;
|
||||||
import io.xpipe.extension.Cache;
|
import io.xpipe.extension.Cache;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
|
@ -49,7 +49,7 @@ public class AppCache implements Cache {
|
||||||
var path = getPath(key);
|
var path = getPath(key);
|
||||||
if (Files.exists(path)) {
|
if (Files.exists(path)) {
|
||||||
try {
|
try {
|
||||||
var tree = ConfigHelper.readConfig(path);
|
var tree = JsonConfigHelper.readConfig(path);
|
||||||
if (tree.isMissingNode()) {
|
if (tree.isMissingNode()) {
|
||||||
return notPresent.get();
|
return notPresent.get();
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ public class AppCache implements Cache {
|
||||||
try {
|
try {
|
||||||
FileUtils.forceMkdirParent(path.toFile());
|
FileUtils.forceMkdirParent(path.toFile());
|
||||||
var tree = JacksonMapper.newMapper().valueToTree(val);
|
var tree = JacksonMapper.newMapper().valueToTree(val);
|
||||||
ConfigHelper.writeConfig(path, tree);
|
JsonConfigHelper.writeConfig(path, tree);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable("Could not parse cached data for key " + key, e)
|
ErrorEvent.fromThrowable("Could not parse cached data for key " + key, e)
|
||||||
.omitted(true)
|
.omitted(true)
|
||||||
|
|
|
@ -4,11 +4,16 @@ import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.prefs.SupportedLocale;
|
import io.xpipe.app.prefs.SupportedLocale;
|
||||||
import io.xpipe.app.util.ModuleHelper;
|
import io.xpipe.app.util.ModuleHelper;
|
||||||
import io.xpipe.extension.I18n;
|
import io.xpipe.extension.I18n;
|
||||||
|
import io.xpipe.extension.Translatable;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
import io.xpipe.extension.event.TrackEvent;
|
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.Bindings;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.ocpsoft.prettytime.PrettyTime;
|
import org.ocpsoft.prettytime.PrettyTime;
|
||||||
|
|
||||||
|
@ -89,11 +94,31 @@ public class AppI18n implements I18n {
|
||||||
prettyTime = null;
|
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
|
@Override
|
||||||
public String getKey(String s) {
|
public String getKey(String s) {
|
||||||
var key = s;
|
var key = s;
|
||||||
if (!s.contains(".")) {
|
if (!s.contains(".")) {
|
||||||
key = ModuleHelper.getCallerModuleName() + "." + s;
|
key = getCallerModuleName() + "." + s;
|
||||||
}
|
}
|
||||||
return key;
|
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.collection.SourceCollectionViewState;
|
||||||
import io.xpipe.app.comp.storage.store.StoreViewState;
|
import io.xpipe.app.comp.storage.store.StoreViewState;
|
||||||
import io.xpipe.app.core.*;
|
import io.xpipe.app.core.*;
|
||||||
import io.xpipe.app.editor.EditorState;
|
import io.xpipe.app.util.ExternalEditor;
|
||||||
import io.xpipe.app.grid.AppUpdater;
|
import io.xpipe.app.update.AppUpdater;
|
||||||
import io.xpipe.app.issue.BasicErrorHandler;
|
import io.xpipe.app.issue.BasicErrorHandler;
|
||||||
import io.xpipe.app.issue.ErrorHandler;
|
import io.xpipe.app.issue.ErrorHandler;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
|
@ -40,7 +40,7 @@ public class BaseMode extends OperationMode {
|
||||||
AppCharsetter.init();
|
AppCharsetter.init();
|
||||||
DataStorage.init();
|
DataStorage.init();
|
||||||
FileWatchManager.init();
|
FileWatchManager.init();
|
||||||
EditorState.init();
|
ExternalEditor.init();
|
||||||
AppSocketServer.init();
|
AppSocketServer.init();
|
||||||
AppUpdater.init();
|
AppUpdater.init();
|
||||||
TrackEvent.info("mode", "Finished base components initialization");
|
TrackEvent.info("mode", "Finished base components initialization");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.app.core.mode;
|
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.App;
|
||||||
import io.xpipe.app.core.AppGreetings;
|
import io.xpipe.app.core.AppGreetings;
|
||||||
import io.xpipe.app.issue.ErrorHandler;
|
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.collection.SourceCollectionViewState;
|
||||||
import io.xpipe.app.comp.storage.store.StoreViewState;
|
import io.xpipe.app.comp.storage.store.StoreViewState;
|
||||||
import io.xpipe.app.core.*;
|
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.event.TrackEvent;
|
||||||
import io.xpipe.extension.util.ThreadHelper;
|
import io.xpipe.extension.util.ThreadHelper;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.xpipe.app.exchange.cli;
|
package io.xpipe.app.exchange.cli;
|
||||||
|
|
||||||
import io.xpipe.app.exchange.MessageExchangeImpl;
|
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.BeaconHandler;
|
||||||
import io.xpipe.beacon.exchange.cli.InstanceExchange;
|
import io.xpipe.beacon.exchange.cli.InstanceExchange;
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.core.impl.LocalStore;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package io.xpipe.app.issue;
|
||||||
import io.sentry.Sentry;
|
import io.sentry.Sentry;
|
||||||
import io.xpipe.app.core.*;
|
import io.xpipe.app.core.*;
|
||||||
import io.xpipe.app.core.mode.OperationMode;
|
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.I18n;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
import javafx.application.Platform;
|
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.PrefsHandler;
|
||||||
import io.xpipe.extension.prefs.PrefsProvider;
|
import io.xpipe.extension.prefs.PrefsProvider;
|
||||||
import io.xpipe.extension.util.XPipeDistributionType;
|
import io.xpipe.extension.util.XPipeDistributionType;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.beans.value.ObservableBooleanValue;
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
@ -26,6 +27,24 @@ import java.util.*;
|
||||||
|
|
||||||
public class AppPrefs {
|
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 tooltipDelayMin = 0;
|
||||||
private static final int tooltipDelayMax = 1500;
|
private static final int tooltipDelayMax = 1500;
|
||||||
private static final int fontSizeMin = 10;
|
private static final int fontSizeMin = 10;
|
||||||
|
@ -134,7 +153,7 @@ public class AppPrefs {
|
||||||
private final ObjectProperty<Path> effectiveStorageDirectory = STORAGE_DIR_FIXED
|
private final ObjectProperty<Path> effectiveStorageDirectory = STORAGE_DIR_FIXED
|
||||||
? new SimpleObjectProperty<>(AppProperties.get().getDataDir().resolve("storage"))
|
? new SimpleObjectProperty<>(AppProperties.get().getDataDir().resolve("storage"))
|
||||||
: internalStorageDirectory;
|
: internalStorageDirectory;
|
||||||
private final StringField storageDirectoryControl = Fields.ofPath(effectiveStorageDirectory)
|
private final StringField storageDirectoryControl = PrefFields.ofPath(effectiveStorageDirectory)
|
||||||
.editable(!STORAGE_DIR_FIXED)
|
.editable(!STORAGE_DIR_FIXED)
|
||||||
.validate(
|
.validate(
|
||||||
CustomValidators.absolutePath(),
|
CustomValidators.absolutePath(),
|
||||||
|
@ -230,24 +249,24 @@ public class AppPrefs {
|
||||||
return effectiveDeveloperMode;
|
return effectiveDeveloperMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty developerDisableUpdateVersionCheck() {
|
public ObservableBooleanValue developerDisableUpdateVersionCheck() {
|
||||||
return developerDisableUpdateVersionCheck;
|
return bindDeveloperTrue(developerDisableUpdateVersionCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty developerDisableGuiRestrictions() {
|
public ObservableBooleanValue developerDisableGuiRestrictions() {
|
||||||
return developerDisableGuiRestrictions;
|
return bindDeveloperTrue(developerDisableGuiRestrictions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty developerDisableConnectorInstallationVersionCheck() {
|
public ObservableBooleanValue developerDisableConnectorInstallationVersionCheck() {
|
||||||
return developerDisableConnectorInstallationVersionCheck;
|
return bindDeveloperTrue(developerDisableConnectorInstallationVersionCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty developerShowHiddenProviders() {
|
public ObservableBooleanValue developerShowHiddenProviders() {
|
||||||
return developerShowHiddenProviders;
|
return bindDeveloperTrue(developerShowHiddenProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty developerShowHiddenEntries() {
|
public ObservableBooleanValue developerShowHiddenEntries() {
|
||||||
return developerShowHiddenEntries;
|
return bindDeveloperTrue(developerShowHiddenEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AppPreferencesFx preferencesFx;
|
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.node.TextNode;
|
||||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||||
import io.xpipe.app.core.AppProperties;
|
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.core.util.JacksonMapper;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
import io.xpipe.extension.event.TrackEvent;
|
import io.xpipe.extension.event.TrackEvent;
|
||||||
|
@ -32,7 +32,7 @@ public class JsonStorageHandler implements StorageHandler {
|
||||||
|
|
||||||
private JsonNode getContent(String key) {
|
private JsonNode getContent(String key) {
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
content = (ObjectNode) ConfigHelper.readConfig(file);
|
content = (ObjectNode) JsonConfigHelper.readConfig(file);
|
||||||
}
|
}
|
||||||
return content.get(key);
|
return content.get(key);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class JsonStorageHandler implements StorageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
void save() {
|
void save() {
|
||||||
ConfigHelper.writeConfig(file, content);
|
JsonConfigHelper.writeConfig(file, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,7 +11,7 @@ import javafx.util.StringConverter;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Fields {
|
public class PrefFields {
|
||||||
|
|
||||||
public static StringField ofPath(ObjectProperty<Path> fileProperty) {
|
public static StringField ofPath(ObjectProperty<Path> fileProperty) {
|
||||||
StringProperty stringProperty = new SimpleStringProperty();
|
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.app.prefs.AppPrefs;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
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.JsonSubTypes;
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import io.xpipe.app.util.TerminalProvider;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.impl.LocalProcessControlProvider;
|
|
||||||
import io.xpipe.core.process.CommandProcessControl;
|
import io.xpipe.core.process.CommandProcessControl;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellProcessControl;
|
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"
|
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"
|
+ "DEBIAN_FRONTEND=noninteractive sudo apt-get install -qy \"" + file + "\"\n"
|
||||||
+ "xpipe daemon start";
|
+ "xpipe daemon start";
|
||||||
var script = ScriptHelper.createLocalExecScript(command);
|
TerminalProvider.open("X-Pipe Updater", command);
|
||||||
LocalProcessControlProvider.get().openInTerminal("X-Pipe Updater", script);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +222,7 @@ public class AppInstaller {
|
||||||
@Override
|
@Override
|
||||||
public void installLocal(String file) throws Exception {
|
public void installLocal(String file) throws Exception {
|
||||||
var command = "set -x\n" + "sudo rpm -U -v --force \"" + file + "\"\n" + "xpipe daemon start";
|
var command = "set -x\n" + "sudo rpm -U -v --force \"" + file + "\"\n" + "xpipe daemon start";
|
||||||
var script = ScriptHelper.createLocalExecScript(command);
|
TerminalProvider.open("X-Pipe Updater", command);
|
||||||
LocalProcessControlProvider.get().openInTerminal("X-Pipe Updater", script);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +248,7 @@ public class AppInstaller {
|
||||||
@Override
|
@Override
|
||||||
public void installLocal(String file) throws Exception {
|
public void installLocal(String file) throws Exception {
|
||||||
var command = "set -x\n" + "sudo installer -verboseR -allowUntrusted -pkg \"" + file + "\" -target /\n" + "xpipe daemon start";
|
var command = "set -x\n" + "sudo installer -verboseR -allowUntrusted -pkg \"" + file + "\" -target /\n" + "xpipe daemon start";
|
||||||
var script = ScriptHelper.createLocalExecScript(command);
|
TerminalProvider.open("X-Pipe Updater", command);
|
||||||
LocalProcessControlProvider.get().openInTerminal("X-Pipe Updater", script);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package io.xpipe.app.grid;
|
package io.xpipe.app.update;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppCache;
|
import io.xpipe.app.core.AppCache;
|
||||||
import io.xpipe.extension.util.XPipeDistributionType;
|
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.AppProperties;
|
||||||
import io.xpipe.app.core.mode.OperationMode;
|
import io.xpipe.app.core.mode.OperationMode;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
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.core.util.XPipeSession;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
import io.xpipe.extension.event.TrackEvent;
|
import io.xpipe.extension.event.TrackEvent;
|
||||||
|
@ -112,7 +112,7 @@ public class AppUpdater {
|
||||||
if (layer == null) {
|
if (layer == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LocalProcessControlProvider.init(layer);
|
ProcessControlProvider.init(layer);
|
||||||
|
|
||||||
INSTANCE = new AppUpdater();
|
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.app.core.AppWindowHelper;
|
||||||
import io.xpipe.extension.I18n;
|
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.comp.base.MarkdownComp;
|
||||||
import io.xpipe.app.core.AppWindowHelper;
|
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.core.AppProperties;
|
||||||
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.beacon.XPipeInstance;
|
import io.xpipe.beacon.XPipeInstance;
|
||||||
import io.xpipe.core.store.ShellStore;
|
import io.xpipe.core.store.ShellStore;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
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.core.FileWatchManager;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
|
@ -22,14 +22,14 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class EditorState {
|
public class ExternalEditor {
|
||||||
|
|
||||||
private static final Path TEMP =
|
private static final Path TEMP =
|
||||||
FileUtils.getTempDirectory().toPath().resolve("xpipe").resolve("editor");
|
FileUtils.getTempDirectory().toPath().resolve("xpipe").resolve("editor");
|
||||||
private static EditorState INSTANCE;
|
private static ExternalEditor INSTANCE;
|
||||||
private final Set<Entry> openEntries = new CopyOnWriteArraySet<>();
|
private final Set<Entry> openEntries = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
public static EditorState get() {
|
public static ExternalEditor get() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class EditorState {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
INSTANCE = new EditorState();
|
INSTANCE = new ExternalEditor();
|
||||||
try {
|
try {
|
||||||
FileUtils.forceMkdir(TEMP.toFile());
|
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 class Hyperlinks {
|
||||||
|
|
||||||
public static final String WEBSITE = "https://xpipe.io";
|
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 GITHUB = "https://github.com/xpipe-io";
|
||||||
public static final String DISCORD = "https://discord.gg/8y89vS8cRb";
|
public static final String DISCORD = "https://discord.gg/8y89vS8cRb";
|
||||||
public static final String SLACK =
|
public static final String SLACK =
|
||||||
"https://join.slack.com/t/x-pipe/shared_invite/zt-1awjq0t5j-5i4UjNJfNe1VN4b_auu6Cg";
|
"https://join.slack.com/t/x-pipe/shared_invite/zt-1awjq0t5j-5i4UjNJfNe1VN4b_auu6Cg";
|
||||||
|
public static final String DOCS_PRIVACY = "https://xpipe.io/docs/privacy";
|
||||||
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 Runnable openLink(String s) {
|
public static Runnable openLink(String s) {
|
||||||
return () -> open(s);
|
return () -> open(s);
|
||||||
|
|
|
@ -15,13 +15,13 @@ import java.io.StringWriter;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public class ConfigHelper {
|
public class JsonConfigHelper {
|
||||||
|
|
||||||
public static JsonNode readConfig(Path in) {
|
public static JsonNode readConfig(Path in) {
|
||||||
JsonNode node = JsonNodeFactory.instance.objectNode();
|
JsonNode node = JsonNodeFactory.instance.objectNode();
|
||||||
try {
|
try {
|
||||||
if (Files.exists(in)) {
|
if (Files.exists(in)) {
|
||||||
ObjectMapper o = JacksonMapper.newMapper();
|
ObjectMapper o = JacksonMapper.getDefault();
|
||||||
node = o.readTree(Files.readAllBytes(in));
|
node = o.readTree(Files.readAllBytes(in));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -41,7 +41,7 @@ public class ConfigHelper {
|
||||||
var writer = new StringWriter();
|
var writer = new StringWriter();
|
||||||
JsonFactory f = new JsonFactory();
|
JsonFactory f = new JsonFactory();
|
||||||
try (JsonGenerator g = f.createGenerator(writer).setPrettyPrinter(new DefaultPrettyPrinter())) {
|
try (JsonGenerator g = f.createGenerator(writer).setPrettyPrinter(new DefaultPrettyPrinter())) {
|
||||||
JacksonMapper.newMapper().writeTree(g, node);
|
JacksonMapper.getDefault().writeTree(g, node);
|
||||||
var newContent = writer.toString();
|
var newContent = writer.toString();
|
||||||
Files.writeString(out, newContent);
|
Files.writeString(out, newContent);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
|
@ -1,11 +1,5 @@
|
||||||
package io.xpipe.app.util;
|
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 lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
@ -13,26 +7,6 @@ import java.lang.reflect.Method;
|
||||||
|
|
||||||
public class ModuleHelper {
|
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() {
|
public static boolean isImage() {
|
||||||
return ModuleHelper.class
|
return ModuleHelper.class
|
||||||
.getProtectionDomain()
|
.getProtectionDomain()
|
||||||
|
|
|
@ -2,8 +2,8 @@ package io.xpipe.app.util;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppProperties;
|
import io.xpipe.app.core.AppProperties;
|
||||||
import io.xpipe.app.core.AppWindowHelper;
|
import io.xpipe.app.core.AppWindowHelper;
|
||||||
import io.xpipe.app.grid.AppDownloads;
|
import io.xpipe.app.update.AppDownloads;
|
||||||
import io.xpipe.app.grid.AppInstaller;
|
import io.xpipe.app.update.AppInstaller;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.process.ShellProcessControl;
|
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.AppImages;
|
||||||
import io.xpipe.app.core.AppProperties;
|
import io.xpipe.app.core.AppProperties;
|
||||||
import io.xpipe.app.core.AppResources;
|
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.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreEntry;
|
import io.xpipe.app.storage.DataStoreEntry;
|
||||||
import io.xpipe.core.charsetter.Charsetter;
|
import io.xpipe.core.charsetter.Charsetter;
|
||||||
|
|
|
@ -27,8 +27,7 @@ open module io.xpipe.app {
|
||||||
exports io.xpipe.app.prefs;
|
exports io.xpipe.app.prefs;
|
||||||
exports io.xpipe.app.comp.source.store;
|
exports io.xpipe.app.comp.source.store;
|
||||||
exports io.xpipe.app.storage;
|
exports io.xpipe.app.storage;
|
||||||
exports io.xpipe.app.editor;
|
exports io.xpipe.app.update;
|
||||||
exports io.xpipe.app.grid;
|
|
||||||
exports io.xpipe.app.comp.storage;
|
exports io.xpipe.app.comp.storage;
|
||||||
exports io.xpipe.app.comp.storage.collection;
|
exports io.xpipe.app.comp.storage.collection;
|
||||||
|
|
||||||
|
@ -98,6 +97,7 @@ open module io.xpipe.app {
|
||||||
requires jdk.jdwp.agent;
|
requires jdk.jdwp.agent;
|
||||||
|
|
||||||
uses MessageExchangeImpl;
|
uses MessageExchangeImpl;
|
||||||
|
uses io.xpipe.app.util.TerminalProvider;
|
||||||
|
|
||||||
provides DataStateProvider with
|
provides DataStateProvider with
|
||||||
DataStateProviderImpl;
|
DataStateProviderImpl;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.cli;
|
||||||
import io.xpipe.beacon.exchange.MessageExchanges;
|
import io.xpipe.beacon.exchange.MessageExchanges;
|
||||||
import io.xpipe.cli.util.CliProperties;
|
import io.xpipe.cli.util.CliProperties;
|
||||||
import io.xpipe.cli.util.PrettyTimeHelper;
|
import io.xpipe.cli.util.PrettyTimeHelper;
|
||||||
import io.xpipe.core.impl.LocalProcessControlProvider;
|
|
||||||
import io.xpipe.core.util.JacksonMapper;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
|
|
||||||
public class BuildTimeInitialization {
|
public class BuildTimeInitialization {
|
||||||
|
@ -13,7 +12,6 @@ public class BuildTimeInitialization {
|
||||||
CliProperties.init();
|
CliProperties.init();
|
||||||
JacksonMapper.initClassBased();
|
JacksonMapper.initClassBased();
|
||||||
MessageExchanges.loadAll();
|
MessageExchanges.loadAll();
|
||||||
LocalProcessControlProvider.init(null);
|
|
||||||
PrettyTimeHelper.init();
|
PrettyTimeHelper.init();
|
||||||
// System.out.println("Ending build time initialization");
|
// System.out.println("Ending build time initialization");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.cli.test;
|
package io.xpipe.cli.test;
|
||||||
|
|
||||||
import io.xpipe.extension.util.DaemonExtensionTest;
|
import io.xpipe.extension.test.DaemonExtensionTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.cli.test;
|
package io.xpipe.cli.test;
|
||||||
|
|
||||||
import io.xpipe.extension.util.DaemonExtensionTest;
|
import io.xpipe.extension.test.DaemonExtensionTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.cli.test;
|
package io.xpipe.cli.test;
|
||||||
|
|
||||||
import io.xpipe.extension.util.DaemonExtensionTest;
|
import io.xpipe.extension.test.DaemonExtensionTest;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.cli.test;
|
package io.xpipe.cli.test;
|
||||||
|
|
||||||
import io.xpipe.extension.util.ExtensionTest;
|
import io.xpipe.extension.test.ExtensionTest;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
|
@ -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
|
@Override
|
||||||
public ShellProcessControl create() {
|
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.source.WriteMode;
|
||||||
import io.xpipe.core.util.CoreJacksonModule;
|
import io.xpipe.core.util.CoreJacksonModule;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ open module io.xpipe.core {
|
||||||
|
|
||||||
uses com.fasterxml.jackson.databind.Module;
|
uses com.fasterxml.jackson.databind.Module;
|
||||||
uses io.xpipe.core.source.WriteMode;
|
uses io.xpipe.core.source.WriteMode;
|
||||||
uses LocalProcessControlProvider;
|
uses ProcessControlProvider;
|
||||||
uses io.xpipe.core.util.ProxyProvider;
|
uses io.xpipe.core.util.ProxyProvider;
|
||||||
uses io.xpipe.core.util.ProxyManagerProvider;
|
uses io.xpipe.core.util.ProxyManagerProvider;
|
||||||
uses io.xpipe.core.util.DataStateProvider;
|
uses io.xpipe.core.util.DataStateProvider;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.ext.base.actions;
|
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.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;
|
||||||
|
@ -33,9 +33,9 @@ public class FileEditAction implements DataStoreActionProvider<FileStore> {
|
||||||
@Override
|
@Override
|
||||||
public void execute(FileStore store) throws Exception {
|
public void execute(FileStore store) throws Exception {
|
||||||
if (store.getFileSystem().equals(new LocalStore())) {
|
if (store.getFileSystem().equals(new LocalStore())) {
|
||||||
EditorState.get().openInEditor(store.getFile());
|
ExternalEditor.get().openInEditor(store.getFile());
|
||||||
} else {
|
} else {
|
||||||
EditorState.get()
|
ExternalEditor.get()
|
||||||
.startEditing(store.getFileName(), store.getFileExtension(), store, () -> store.openInput(), () -> store.openOutput());
|
.startEditing(store.getFileName(), store.getFileExtension(), store, () -> store.openInput(), () -> store.openOutput());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class CommandLineTarget implements DataSourceTarget {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSetupGuideURL() {
|
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
|
@Override
|
||||||
|
|
|
@ -118,6 +118,6 @@ public class JavaTarget implements DataSourceTarget {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSetupGuideURL() {
|
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.charsetter.StreamCharset;
|
||||||
import io.xpipe.core.impl.FileStore;
|
import io.xpipe.core.impl.FileStore;
|
||||||
import io.xpipe.core.impl.TextSource;
|
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.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
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.CsvDelimiter;
|
||||||
import io.xpipe.ext.csv.CsvHeaderState;
|
import io.xpipe.ext.csv.CsvHeaderState;
|
||||||
import io.xpipe.ext.csv.CsvSource;
|
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.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
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() {
|
public boolean requiresFullDaemon() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean prioritizeLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<DataSourceTarget> byId(String id) {
|
public static Optional<DataSourceTarget> byId(String id) {
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
package io.xpipe.extension;
|
package io.xpipe.extension;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
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.JacksonMapper;
|
||||||
import io.xpipe.core.util.ProxyFunction;
|
import io.xpipe.core.util.ProxyFunction;
|
||||||
import io.xpipe.extension.event.TrackEvent;
|
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.ModuleLayerLoader;
|
||||||
import io.xpipe.extension.util.XPipeDaemon;
|
import io.xpipe.extension.util.XPipeDaemon;
|
||||||
|
|
||||||
public class XPipeServiceProviders {
|
public class XPipeServiceProviders {
|
||||||
|
|
||||||
public static void load(ModuleLayer layer) {
|
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 ...");
|
TrackEvent.info("Loading extension providers ...");
|
||||||
DataSourceProviders.init(layer);
|
DataSourceProviders.init(layer);
|
||||||
|
@ -34,14 +34,10 @@ public class XPipeServiceProviders {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasDaemon = XPipeDaemon.getInstanceIfPresent().isPresent();
|
ModuleLayerLoader.loadAll(layer, hasDaemon, false);
|
||||||
ModuleLayerLoader.loadAll(layer, hasDaemon);
|
|
||||||
|
|
||||||
if (hasDaemon) {
|
if (hasDaemon) {
|
||||||
ActionProvider.init(layer);
|
|
||||||
DataSourceActionProvider.init(layer);
|
|
||||||
ProxyFunction.init(layer);
|
ProxyFunction.init(layer);
|
||||||
PrefsProvider.init(layer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackEvent.info("Finished loading extension providers");
|
TrackEvent.info("Finished loading extension providers");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.xpipe.extension.prefs;
|
package io.xpipe.extension.prefs;
|
||||||
|
|
||||||
import com.dlsc.formsfx.model.structure.Field;
|
import com.dlsc.formsfx.model.structure.Field;
|
||||||
|
import io.xpipe.extension.util.ModuleLayerLoader;
|
||||||
import javafx.beans.value.ObservableBooleanValue;
|
import javafx.beans.value.ObservableBooleanValue;
|
||||||
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
@ -11,12 +12,24 @@ public abstract class PrefsProvider {
|
||||||
|
|
||||||
private static Set<PrefsProvider> ALL;
|
private static Set<PrefsProvider> ALL;
|
||||||
|
|
||||||
public static void init(ModuleLayer layer) {
|
public static class Loader implements ModuleLayerLoader {
|
||||||
if (ALL == null) {
|
|
||||||
|
@Override
|
||||||
|
public void init(ModuleLayer layer) {
|
||||||
ALL = ServiceLoader.load(layer, PrefsProvider.class).stream()
|
ALL = ServiceLoader.load(layer, PrefsProvider.class).stream()
|
||||||
.map(ServiceLoader.Provider::get)
|
.map(ServiceLoader.Provider::get)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresFullDaemon() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean prioritizeLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<PrefsProvider> getAll() {
|
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.api.DataSource;
|
||||||
import io.xpipe.beacon.BeaconDaemonController;
|
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.data.node.DataStructureNode;
|
||||||
import io.xpipe.core.impl.FileStore;
|
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.JacksonMapper;
|
||||||
import io.xpipe.core.util.XPipeSession;
|
import io.xpipe.core.util.XPipeSession;
|
|
@ -1,5 +1,6 @@
|
||||||
package io.xpipe.extension.util;
|
package io.xpipe.extension.util;
|
||||||
|
|
||||||
|
import io.xpipe.core.source.DataSource;
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
import io.xpipe.extension.event.ErrorEvent;
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
@ -7,24 +8,37 @@ import javafx.beans.value.ObservableValue;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public interface ActionProvider {
|
public interface ActionProvider {
|
||||||
|
|
||||||
static List<ActionProvider> ALL = new ArrayList<>();
|
static List<ActionProvider> ALL = new ArrayList<>();
|
||||||
|
|
||||||
public static void init(ModuleLayer layer) {
|
public static class Loader implements ModuleLayerLoader {
|
||||||
if (ALL.size() == 0) {
|
|
||||||
|
@Override
|
||||||
|
public void init(ModuleLayer layer) {
|
||||||
ALL.addAll(ServiceLoader.load(layer, ActionProvider.class).stream()
|
ALL.addAll(ServiceLoader.load(layer, ActionProvider.class).stream()
|
||||||
.map(p -> (ActionProvider) p.get())
|
.map(actionProviderProvider -> actionProviderProvider.get())
|
||||||
.filter(provider -> {
|
.filter(provider -> {
|
||||||
try {
|
try {
|
||||||
return provider.isActive();
|
return provider.isActive();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
ErrorEvent.fromThrowable(e).handle();
|
ErrorEvent.fromThrowable(e).handle();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.toList());
|
.collect(Collectors.toSet()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresFullDaemon() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean prioritizeLoading() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +53,9 @@ public interface ActionProvider {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface LauncherCallSite {
|
interface LauncherCallSite {
|
||||||
|
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
Action createAction(List<String> args) throws Exception;
|
Action createAction(List<String> args) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +68,11 @@ public interface ActionProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default DataSourceCallSite<?> getDataSourceCallSite() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface DataStoreCallSite<T extends DataStore> {
|
public static interface DataStoreCallSite<T extends DataStore> {
|
||||||
|
|
||||||
Action createAction(T store);
|
Action createAction(T store);
|
||||||
|
@ -64,6 +82,7 @@ public interface ActionProvider {
|
||||||
default boolean isMajor() {
|
default boolean isMajor() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isApplicable(T o) throws Exception {
|
default boolean isApplicable(T o) throws Exception {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -76,4 +95,27 @@ public interface ActionProvider {
|
||||||
return true;
|
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 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 -> {
|
ServiceLoader.load(layer, ModuleLayerLoader.class).stream().forEach(moduleLayerLoaderProvider -> {
|
||||||
var instance = moduleLayerLoaderProvider.get();
|
var instance = moduleLayerLoaderProvider.get();
|
||||||
try {
|
try {
|
||||||
if (instance.requiresFullDaemon() && !hasDaemon) {
|
if (instance.requiresFullDaemon() && !hasDaemon) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance.prioritizeLoading() != prioritization) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
instance.init(layer);
|
instance.init(layer);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ErrorEvent.fromThrowable(t).handle();
|
ErrorEvent.fromThrowable(t).handle();
|
||||||
|
@ -23,4 +28,6 @@ public interface ModuleLayerLoader {
|
||||||
public void init(ModuleLayer layer);
|
public void init(ModuleLayer layer);
|
||||||
|
|
||||||
boolean requiresFullDaemon();
|
boolean requiresFullDaemon();
|
||||||
|
|
||||||
|
boolean prioritizeLoading();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ 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.DataStoreActionProvider;
|
||||||
import io.xpipe.extension.DataSourceTarget;
|
import io.xpipe.extension.DataSourceTarget;
|
||||||
|
import io.xpipe.extension.prefs.PrefsProvider;
|
||||||
import io.xpipe.extension.util.ActionProvider;
|
import io.xpipe.extension.util.ActionProvider;
|
||||||
import io.xpipe.extension.util.ModuleLayerLoader;
|
import io.xpipe.extension.util.ModuleLayerLoader;
|
||||||
import io.xpipe.extension.util.XPipeDaemon;
|
import io.xpipe.extension.util.XPipeDaemon;
|
||||||
|
@ -51,10 +52,9 @@ open module io.xpipe.extension {
|
||||||
uses io.xpipe.extension.DataStoreProvider;
|
uses io.xpipe.extension.DataStoreProvider;
|
||||||
uses XPipeDaemon;
|
uses XPipeDaemon;
|
||||||
uses io.xpipe.extension.Cache;
|
uses io.xpipe.extension.Cache;
|
||||||
uses io.xpipe.extension.DataSourceActionProvider;
|
|
||||||
uses ProxyFunction;
|
uses ProxyFunction;
|
||||||
uses ActionProvider;
|
uses ActionProvider;
|
||||||
uses io.xpipe.extension.util.ModuleLayerLoader;
|
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