mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 00:50:31 +00:00
Remove leftover merge files
This commit is contained in:
parent
3e7fbe89ac
commit
d2d0df9789
89 changed files with 0 additions and 5460 deletions
|
@ -1,29 +0,0 @@
|
|||
package io.xpipe.api.test;
|
||||
|
||||
import io.xpipe.api.DataTableAccumulator;
|
||||
import io.xpipe.core.data.node.TupleNode;
|
||||
import io.xpipe.core.data.node.ValueNode;
|
||||
import io.xpipe.core.data.type.TupleType;
|
||||
import io.xpipe.core.data.type.ValueType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DataTableAccumulatorTest extends ApiTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
var type = TupleType.of(List.of("col1", "col2"), List.of(ValueType.of(), ValueType.of()));
|
||||
var acc = DataTableAccumulator.create(type);
|
||||
|
||||
var val = type.convert(TupleNode.of(List.of(ValueNode.of("val1"), ValueNode.of("val2"))))
|
||||
.orElseThrow();
|
||||
acc.add(val);
|
||||
var table = acc.finish(":test");
|
||||
|
||||
// Assertions.assertEquals(table.getInfo().getDataType(), TupleType.tableType(List.of("col1", "col2")));
|
||||
// Assertions.assertEquals(table.getInfo().getRowCountIfPresent(), OptionalInt.empty());
|
||||
// var read = table.read(1).at(0);
|
||||
// Assertions.assertEquals(val, read);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package io.xpipe.api.test;
|
||||
|
||||
import io.xpipe.api.DataSource;
|
||||
import io.xpipe.core.store.DataStoreId;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DataTableTest extends ApiTest {
|
||||
|
||||
@BeforeAll
|
||||
public static void setupStorage() throws Exception {
|
||||
DataSource.create(
|
||||
DataStoreId.fromString(":usernames"), "csv", DataTableTest.class.getResource("username.csv"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet() {
|
||||
var table = DataSource.getById(":usernames").asTable();
|
||||
var r = table.read(2);
|
||||
var a = 0;
|
||||
}
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-data-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-ast-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-builder-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-sequence-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-misc-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-dependency-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-collection-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-format-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-html-0.64.0.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flexmark-util-visitor-0.64.0.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark {
|
||||
exports com.vladsch.flexmark.html;
|
||||
exports com.vladsch.flexmark.html.renderer;
|
||||
exports com.vladsch.flexmark.parser;
|
||||
exports com.vladsch.flexmark.parser.core;
|
||||
|
||||
requires com.vladsch.flexmark_util_data;
|
||||
requires com.vladsch.flexmark_util_ast;
|
||||
requires com.vladsch.flexmark_util_builder;
|
||||
requires com.vladsch.flexmark_util_sequence;
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
requires com.vladsch.flexmark_util_dependency;
|
||||
requires com.vladsch.flexmark_util_collection;
|
||||
requires com.vladsch.flexmark_util_format;
|
||||
requires com.vladsch.flexmark_util_html;
|
||||
requires com.vladsch.flexmark_util_visitor;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-data:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_data {
|
||||
exports com.vladsch.flexmark.util.data;
|
||||
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-ast:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_ast {
|
||||
exports com.vladsch.flexmark.util.ast;
|
||||
|
||||
requires com.vladsch.flexmark_util_data;
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
requires com.vladsch.flexmark_util_collection;
|
||||
requires com.vladsch.flexmark_util_sequence;
|
||||
requires com.vladsch.flexmark_util_visitor;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-builder:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_builder {
|
||||
exports com.vladsch.flexmark.util.builder;
|
||||
|
||||
requires com.vladsch.flexmark_util_data;
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-sequence:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_sequence {
|
||||
exports com.vladsch.flexmark.util.sequence;
|
||||
exports com.vladsch.flexmark.util.sequence.mappers;
|
||||
exports com.vladsch.flexmark.util.sequence.builder;
|
||||
|
||||
opens com.vladsch.flexmark.util.sequence;
|
||||
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
requires com.vladsch.flexmark_util_data;
|
||||
requires com.vladsch.flexmark_util_collection;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-misc:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_misc {
|
||||
exports com.vladsch.flexmark.util.misc;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-dependency:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_dependency {
|
||||
exports com.vladsch.flexmark.util.dependency;
|
||||
|
||||
requires com.vladsch.flexmark_util_collection;
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-collection:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_collection {
|
||||
exports com.vladsch.flexmark.util.collection;
|
||||
exports com.vladsch.flexmark.util.collection.iteration;
|
||||
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-format:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_format {
|
||||
exports com.vladsch.flexmark.util.format;
|
||||
|
||||
requires com.vladsch.flexmark_util_data;
|
||||
requires com.vladsch.flexmark_util_sequence;
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
requires com.vladsch.flexmark_util_ast;
|
||||
requires com.vladsch.flexmark_util_collection;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-html:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_html {
|
||||
exports com.vladsch.flexmark.util.html;
|
||||
|
||||
opens com.vladsch.flexmark.util.html;
|
||||
|
||||
requires com.vladsch.flexmark_util_misc;
|
||||
requires com.vladsch.flexmark_util_sequence;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'com.vladsch.flexmark:flexmark-util-visitor:0.64.0'
|
||||
moduleInfoSource = '''
|
||||
module com.vladsch.flexmark_util_visitor {
|
||||
exports com.vladsch.flexmark.util.visitor;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/github-api-1.301.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact 'org.kohsuke:github-api:1.301'
|
||||
moduleInfoSource = '''
|
||||
module org.kohsuke.github {
|
||||
exports org.kohsuke.github;
|
||||
exports org.kohsuke.github.function;
|
||||
exports org.kohsuke.github.authorization;
|
||||
exports org.kohsuke.github.extras;
|
||||
exports org.kohsuke.github.connector;
|
||||
|
||||
requires java.logging;
|
||||
requires org.apache.commons.io;
|
||||
requires org.apache.commons.lang3;
|
||||
requires com.fasterxml.jackson.databind;
|
||||
|
||||
opens org.kohsuke.github;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/richtextfx-0.10.6.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/flowless-0.6.6.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/undofx-2.1.1.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/wellbehavedfx-0.3.3.jar")
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/reactfx-2.0-M5.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact group: 'org.fxmisc.flowless', name: 'flowless', version: '0.6.6'
|
||||
moduleInfoSource = '''
|
||||
module org.fxmisc.flowless {
|
||||
exports org.fxmisc.flowless;
|
||||
requires static javafx.base;
|
||||
requires static javafx.controls;
|
||||
requires org.reactfx;
|
||||
requires org.fxmisc.wellbehavedfx;
|
||||
}
|
||||
'''
|
||||
}
|
||||
|
||||
module {
|
||||
artifact group: 'org.fxmisc.undo', name: 'undofx', version: '2.1.1'
|
||||
moduleInfoSource = '''
|
||||
module org.fxmisc.undofx {
|
||||
exports org.fxmisc.undo;
|
||||
requires static javafx.base;
|
||||
requires static javafx.controls;
|
||||
requires org.reactfx;
|
||||
requires org.fxmisc.wellbehavedfx;
|
||||
}
|
||||
'''
|
||||
}
|
||||
|
||||
module {
|
||||
artifact group: 'org.fxmisc.wellbehaved', name: 'wellbehavedfx', version: '0.3.3'
|
||||
moduleInfoSource = '''
|
||||
module org.fxmisc.wellbehavedfx {
|
||||
exports org.fxmisc.wellbehaved.event;
|
||||
exports org.fxmisc.wellbehaved.event.template;
|
||||
|
||||
requires static javafx.base;
|
||||
requires static javafx.controls;
|
||||
requires org.reactfx;
|
||||
}
|
||||
'''
|
||||
}
|
||||
|
||||
module {
|
||||
artifact group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.10.6'
|
||||
moduleInfoSource = '''
|
||||
module org.fxmisc.richtext {
|
||||
exports org.fxmisc.richtext;
|
||||
exports org.fxmisc.richtext.model;
|
||||
exports org.fxmisc.richtext.event;
|
||||
|
||||
requires org.fxmisc.flowless;
|
||||
requires org.fxmisc.undofx;
|
||||
requires org.fxmisc.wellbehavedfx;
|
||||
requires static javafx.base;
|
||||
requires static javafx.controls;
|
||||
requires org.reactfx;
|
||||
}
|
||||
'''
|
||||
}
|
||||
|
||||
module {
|
||||
artifact group: 'org.reactfx', name: 'reactfx', version: '2.0-M5'
|
||||
moduleInfoSource = '''
|
||||
module org.reactfx {
|
||||
exports org.reactfx;
|
||||
exports org.reactfx.collection;
|
||||
exports org.reactfx.value;
|
||||
exports org.reactfx.util;
|
||||
|
||||
requires static javafx.base;
|
||||
requires static javafx.controls;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/sentry-6.29.0.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact 'io.sentry:sentry:6.29.0'
|
||||
moduleInfoSource = '''
|
||||
module io.sentry {
|
||||
exports io.sentry;
|
||||
opens io.sentry;
|
||||
|
||||
exports io.sentry.protocol;
|
||||
opens io.sentry.protocol;
|
||||
|
||||
exports io.sentry.config;
|
||||
opens io.sentry.config;
|
||||
|
||||
exports io.sentry.transport;
|
||||
opens io.sentry.transport;
|
||||
|
||||
exports io.sentry.util;
|
||||
opens io.sentry.util;
|
||||
|
||||
exports io.sentry.cache;
|
||||
opens io.sentry.cache;
|
||||
|
||||
exports io.sentry.exception;
|
||||
opens io.sentry.exception;
|
||||
|
||||
exports io.sentry.hints;
|
||||
opens io.sentry.hints;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
package io.xpipe.app.browser;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreSection;
|
||||
import io.xpipe.app.comp.store.StoreSectionMiniComp;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.FilterComp;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.DataStoreCategoryChoiceComp;
|
||||
import io.xpipe.app.util.FixedHierarchyStore;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
final class BrowserBookmarkList extends SimpleComp {
|
||||
|
||||
public static final Timer DROP_TIMER = new Timer("dnd", true);
|
||||
private static final PseudoClass SELECTED = PseudoClass.getPseudoClass("selected");
|
||||
private final BrowserModel model;
|
||||
private Point2D lastOver = new Point2D(-1, -1);
|
||||
private TimerTask activeTask;
|
||||
|
||||
BrowserBookmarkList(BrowserModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var filterText = new SimpleStringProperty();
|
||||
var open = PlatformThread.sync(model.getSelected());
|
||||
Predicate<StoreEntryWrapper> applicable = storeEntryWrapper -> {
|
||||
return (storeEntryWrapper.getEntry().getStore() instanceof ShellStore ||
|
||||
storeEntryWrapper.getEntry().getStore() instanceof FixedHierarchyStore) && storeEntryWrapper.getEntry().getValidity().isUsable();
|
||||
};
|
||||
var selectedCategory = new SimpleObjectProperty<>(StoreViewState.get().getActiveCategory().getValue());
|
||||
var section = StoreSectionMiniComp.createList(
|
||||
StoreSection.createTopLevel(StoreViewState.get().getAllEntries(), storeEntryWrapper -> true, filterText, selectedCategory), (s, comp) -> {
|
||||
BooleanProperty busy = new SimpleBooleanProperty(false);
|
||||
comp.disable(Bindings.createBooleanBinding(() -> {
|
||||
return busy.get() || !applicable.test(s.getWrapper());
|
||||
}, busy));
|
||||
comp.apply(struc -> {
|
||||
open.addListener((observable, oldValue, newValue) -> {
|
||||
struc.get().pseudoClassStateChanged(SELECTED,
|
||||
newValue != null && newValue.getEntry().get().equals(s.getWrapper().getEntry()));
|
||||
});
|
||||
struc.get().setOnAction(event -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
var entry = s.getWrapper().getEntry();
|
||||
if (!entry.getValidity().isUsable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.getStore() instanceof ShellStore fileSystem) {
|
||||
model.openFileSystemAsync(entry.ref(), null, busy);
|
||||
} else if (entry.getStore() instanceof FixedHierarchyStore) {
|
||||
BooleanScope.execute(busy, () -> {
|
||||
s.getWrapper().refreshChildren();
|
||||
});
|
||||
}
|
||||
});
|
||||
event.consume();
|
||||
});
|
||||
});
|
||||
});
|
||||
var category = new DataStoreCategoryChoiceComp(StoreViewState.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory(),
|
||||
selectedCategory).styleClass(Styles.LEFT_PILL);
|
||||
var filter = new FilterComp(filterText).styleClass(Styles.RIGHT_PILL).hgrow().apply(struc -> {});
|
||||
|
||||
var top = new HorizontalComp(List.of(category, filter.hgrow())).styleClass("categories").apply(struc -> {
|
||||
AppFont.medium(struc.get());
|
||||
struc.get().setFillHeight(true);
|
||||
}).createRegion();
|
||||
var r = section.vgrow().createRegion();
|
||||
var content = new VBox(top, r);
|
||||
content.setFillWidth(true);
|
||||
|
||||
content.getStyleClass().add("bookmark-list");
|
||||
return content;
|
||||
}
|
||||
|
||||
private void handleHoverTimer(DataStore store, DragEvent event) {
|
||||
if (lastOver.getX() == event.getX() && lastOver.getY() == event.getY()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastOver = (new Point2D(event.getX(), event.getY()));
|
||||
activeTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (activeTask != this) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Platform.runLater(() -> model.openExistingFileSystemIfPresent(store.asNeeded()));
|
||||
}
|
||||
};
|
||||
DROP_TIMER.schedule(activeTask, 500);
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppResources;
|
||||
import io.xpipe.app.ext.DownloadModuleInstall;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InstallExtensionComp extends SimpleComp {
|
||||
|
||||
DownloadModuleInstall install;
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var builder = new OptionsBuilder();
|
||||
builder.addTitle("installRequired");
|
||||
var header = new LabelComp(AppI18n.observable("extensionInstallDescription"))
|
||||
.apply(struc -> struc.get().setWrapText(true));
|
||||
builder.addComp(header);
|
||||
|
||||
if (install.getVendorURL() != null) {
|
||||
var vendorLink = Comp.of(() -> {
|
||||
var hl = new Hyperlink(install.getVendorURL());
|
||||
hl.setOnAction(e -> Hyperlinks.open(install.getVendorURL()));
|
||||
return hl;
|
||||
});
|
||||
builder.addComp(vendorLink);
|
||||
}
|
||||
|
||||
if (install.getLicenseFile() != null) {
|
||||
builder.addTitle("license");
|
||||
|
||||
var changeNotice = new LabelComp(AppI18n.observable("extensionInstallLicenseNote"))
|
||||
.apply(struc -> struc.get().setWrapText(true));
|
||||
builder.addComp(changeNotice);
|
||||
|
||||
var license = Comp.of(() -> {
|
||||
var text = new TextArea();
|
||||
text.setEditable(false);
|
||||
AppResources.with(install.getModule(), install.getLicenseFile(), file -> {
|
||||
var s = Files.readString(file);
|
||||
text.setText(s);
|
||||
});
|
||||
text.setWrapText(true);
|
||||
VBox.setVgrow(text, Priority.ALWAYS);
|
||||
AppFont.verySmall(text);
|
||||
return text;
|
||||
});
|
||||
builder.addComp(license);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -1,285 +0,0 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import atlantafx.base.controls.Spacer;
|
||||
import atlantafx.base.theme.Styles;
|
||||
import com.jfoenix.controls.JFXTabPane;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.ReadOnlyProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.layout.*;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MultiStepComp extends Comp<CompStructure<VBox>> {
|
||||
private static final PseudoClass COMPLETED = PseudoClass.getPseudoClass("completed");
|
||||
private static final PseudoClass CURRENT = PseudoClass.getPseudoClass("current");
|
||||
private static final PseudoClass NEXT = PseudoClass.getPseudoClass("next");
|
||||
private final Property<Boolean> completed = new SimpleBooleanProperty();
|
||||
private final Property<Step<?>> currentStep = new SimpleObjectProperty<>();
|
||||
@Getter
|
||||
private List<Entry> entries;
|
||||
@Getter
|
||||
private int currentIndex = 0;
|
||||
|
||||
private Step<?> getValue() {
|
||||
return currentStep.getValue();
|
||||
}
|
||||
|
||||
private void set(Step<?> step) {
|
||||
currentStep.setValue(step);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
if (isFinished()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getValue().canContinue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLastPage()) {
|
||||
getValue().onContinue();
|
||||
finish();
|
||||
currentIndex++;
|
||||
completed.setValue(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int index = Math.min(getCurrentIndex() + 1, entries.size() - 1);
|
||||
if (currentIndex == index) {
|
||||
return;
|
||||
}
|
||||
|
||||
getValue().onContinue();
|
||||
entries.get(index).step().onInit();
|
||||
currentIndex = index;
|
||||
set(entries.get(index).step());
|
||||
});
|
||||
}
|
||||
|
||||
public void previous() {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
int index = Math.max(currentIndex - 1, 0);
|
||||
if (currentIndex == index) {
|
||||
return;
|
||||
}
|
||||
|
||||
getValue().onBack();
|
||||
currentIndex = index;
|
||||
set(entries.get(index).step());
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isCompleted(Entry e) {
|
||||
return entries.indexOf(e) < currentIndex;
|
||||
}
|
||||
|
||||
public boolean isNext(Entry e) {
|
||||
return entries.indexOf(e) > currentIndex;
|
||||
}
|
||||
|
||||
public boolean isCurrent(Entry e) {
|
||||
return entries.indexOf(e) == currentIndex;
|
||||
}
|
||||
|
||||
public boolean isFirstPage() {
|
||||
return currentIndex == 0;
|
||||
}
|
||||
|
||||
public boolean isLastPage() {
|
||||
return currentIndex == entries.size() - 1;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return currentIndex == entries.size();
|
||||
}
|
||||
|
||||
protected Region createStepOverview(Region content) {
|
||||
if (entries.size() == 1) {
|
||||
return new Region();
|
||||
}
|
||||
|
||||
HBox box = new HBox();
|
||||
box.setFillHeight(true);
|
||||
box.getStyleClass().add("top");
|
||||
box.setAlignment(Pos.CENTER);
|
||||
|
||||
var comp = this;
|
||||
int number = 1;
|
||||
for (var entry : comp.getEntries()) {
|
||||
VBox element = new VBox();
|
||||
element.setFillWidth(true);
|
||||
element.setAlignment(Pos.CENTER);
|
||||
var label = new Label();
|
||||
label.textProperty().bind(entry.name);
|
||||
label.getStyleClass().add("name");
|
||||
element.getChildren().add(label);
|
||||
element.getStyleClass().add("entry");
|
||||
|
||||
var line = new Region();
|
||||
boolean first = number == 1;
|
||||
boolean last = number == comp.getEntries().size();
|
||||
line.prefWidthProperty()
|
||||
.bind(Bindings.createDoubleBinding(
|
||||
() -> element.getWidth() / ((first || last) ? 2 : 1), element.widthProperty()));
|
||||
line.setMinWidth(0);
|
||||
line.getStyleClass().add("line");
|
||||
var lineBox = new HBox(line);
|
||||
lineBox.setFillHeight(true);
|
||||
if (first) {
|
||||
lineBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
} else if (last) {
|
||||
lineBox.setAlignment(Pos.CENTER_LEFT);
|
||||
} else {
|
||||
lineBox.setAlignment(Pos.CENTER);
|
||||
}
|
||||
|
||||
var circle = new Region();
|
||||
circle.getStyleClass().add("circle");
|
||||
var numberLabel = new Label("" + number);
|
||||
numberLabel.getStyleClass().add("number");
|
||||
var stack = new StackPane();
|
||||
stack.getChildren().add(lineBox);
|
||||
stack.getChildren().add(circle);
|
||||
stack.getChildren().add(numberLabel);
|
||||
stack.setAlignment(Pos.CENTER);
|
||||
element.getChildren().add(stack);
|
||||
|
||||
Runnable updatePseudoClasses = () -> {
|
||||
element.pseudoClassStateChanged(CURRENT, comp.isCurrent(entry));
|
||||
element.pseudoClassStateChanged(NEXT, comp.isNext(entry));
|
||||
element.pseudoClassStateChanged(COMPLETED, comp.isCompleted(entry));
|
||||
};
|
||||
updatePseudoClasses.run();
|
||||
comp.currentStep.addListener((c, o, n) -> {
|
||||
updatePseudoClasses.run();
|
||||
});
|
||||
|
||||
box.getChildren().add(element);
|
||||
|
||||
element.prefWidthProperty()
|
||||
.bind(Bindings.createDoubleBinding(
|
||||
() -> content.getWidth() / comp.getEntries().size(), content.widthProperty()));
|
||||
|
||||
number++;
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
protected Region createStepNavigation() {
|
||||
MultiStepComp comp = this;
|
||||
|
||||
HBox buttons = new HBox();
|
||||
buttons.setFillHeight(true);
|
||||
buttons.getChildren().add(new Region());
|
||||
buttons.getChildren().add(new Spacer());
|
||||
buttons.getStyleClass().add("buttons");
|
||||
buttons.setSpacing(5);
|
||||
|
||||
SimpleChangeListener.apply(currentStep, val -> {
|
||||
buttons.getChildren().set(0, val.bottom() != null ? val.bottom().createRegion() : new Region());
|
||||
});
|
||||
|
||||
buttons.setAlignment(Pos.CENTER_RIGHT);
|
||||
var nextText = Bindings.createStringBinding(
|
||||
() -> isLastPage() ? AppI18n.get("finishStep") : AppI18n.get("nextStep"), currentStep);
|
||||
var nextButton = new ButtonComp(nextText, null, comp::next)
|
||||
.styleClass(Styles.ACCENT)
|
||||
.styleClass("next");
|
||||
|
||||
var previousButton = new ButtonComp(AppI18n.observable("previousStep"), null, comp::previous)
|
||||
.styleClass("next")
|
||||
.apply(struc -> struc.get()
|
||||
.disableProperty()
|
||||
.bind(Bindings.createBooleanBinding(this::isFirstPage, currentStep)));
|
||||
|
||||
previousButton.apply(
|
||||
s -> s.get().visibleProperty().bind(Bindings.createBooleanBinding(() -> !isFirstPage(), currentStep)));
|
||||
|
||||
buttons.getChildren().add(previousButton.createRegion());
|
||||
buttons.getChildren().add(nextButton.createRegion());
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<VBox> createBase() {
|
||||
this.entries = setup();
|
||||
this.set(entries.get(currentIndex).step);
|
||||
|
||||
VBox content = new VBox();
|
||||
var comp = this;
|
||||
Region box = createStepOverview(content);
|
||||
|
||||
var compContent = new JFXTabPane();
|
||||
compContent.getStyleClass().add("content");
|
||||
for (var ignored : comp.getEntries()) {
|
||||
compContent.getTabs().add(new Tab(null, null));
|
||||
}
|
||||
var entryR = comp.getValue().createRegion();
|
||||
entryR.getStyleClass().add("step");
|
||||
compContent.getTabs().set(currentIndex, new Tab(null, entryR));
|
||||
compContent.getSelectionModel().select(currentIndex);
|
||||
|
||||
content.getChildren().addAll(box, compContent, createStepNavigation());
|
||||
content.getStyleClass().add("multi-step-comp");
|
||||
content.setFillWidth(true);
|
||||
VBox.setVgrow(compContent, Priority.ALWAYS);
|
||||
currentStep.addListener((c, o, n) -> {
|
||||
var nextTab = compContent
|
||||
.getTabs()
|
||||
.get(entries.stream().map(e -> e.step).toList().indexOf(n));
|
||||
if (nextTab.getContent() == null) {
|
||||
var createdRegion = n.createRegion();
|
||||
createdRegion.getStyleClass().add("step");
|
||||
nextTab.setContent(createdRegion);
|
||||
}
|
||||
compContent.getSelectionModel().select(comp.getCurrentIndex());
|
||||
});
|
||||
return new SimpleCompStructure<>(content);
|
||||
}
|
||||
|
||||
protected abstract List<Entry> setup();
|
||||
|
||||
protected abstract void finish();
|
||||
|
||||
public ReadOnlyProperty<Boolean> completedProperty() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public abstract static class Step<S extends CompStructure<?>> extends Comp<S> {
|
||||
|
||||
public Comp<?> bottom() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onInit() {}
|
||||
|
||||
public void onBack() {}
|
||||
|
||||
public void onContinue() {}
|
||||
|
||||
public boolean canContinue() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public record Entry(ObservableValue<String> name, Step<?> step) {}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import atlantafx.base.controls.ToggleSwitch;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
public class NamedToggleComp extends SimpleComp {
|
||||
|
||||
private final BooleanProperty selected;
|
||||
private final ObservableValue<String> name;
|
||||
|
||||
public NamedToggleComp(BooleanProperty selected, ObservableValue<String> name) {
|
||||
this.selected = selected;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var s = new ToggleSwitch();
|
||||
s.setSelected(selected.getValue());
|
||||
s.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
selected.set(newValue);
|
||||
});
|
||||
selected.addListener((observable, oldValue, newValue) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
s.setSelected(newValue);
|
||||
});
|
||||
});
|
||||
if (name != null) {
|
||||
s.textProperty().bind(PlatformThread.sync(name));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
package io.xpipe.app.comp.store;
|
||||
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.ext.DataStoreProviders;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.JfxHelper;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.Region;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
@AllArgsConstructor
|
||||
public class DataStoreProviderChoiceComp extends Comp<CompStructure<ComboBox<DataStoreProvider>>> {
|
||||
|
||||
Predicate<DataStoreProvider> filter;
|
||||
Property<DataStoreProvider> provider;
|
||||
boolean staticDisplay;
|
||||
|
||||
private List<DataStoreProvider> getProviders() {
|
||||
return DataStoreProviders.getAll().stream().filter(filter).toList();
|
||||
}
|
||||
|
||||
private Region createGraphic(DataStoreProvider provider) {
|
||||
if (provider == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var graphic = provider.getDisplayIconFileName(null);
|
||||
return JfxHelper.createNamedEntry(provider.getDisplayName(), provider.getDisplayDescription(), graphic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<ComboBox<DataStoreProvider>> createBase() {
|
||||
Supplier<ListCell<DataStoreProvider>> cellFactory = () -> new ListCell<>() {
|
||||
@Override
|
||||
protected void updateItem(DataStoreProvider item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setGraphic(createGraphic(item));
|
||||
setAccessibleText(item != null ? item.getDisplayName() : null);
|
||||
setAccessibleHelp(item != null ? item.getDisplayDescription() : null);
|
||||
}
|
||||
};
|
||||
var cb = new ComboBox<DataStoreProvider>();
|
||||
cb.setCellFactory(param -> {
|
||||
return cellFactory.get();
|
||||
});
|
||||
cb.setButtonCell(cellFactory.get());
|
||||
var l = getProviders().stream()
|
||||
.filter(p -> AppPrefs.get().developerShowHiddenProviders().get() || p.getCreationCategory() != null || staticDisplay)
|
||||
.toList();
|
||||
l.forEach(dataStoreProvider -> cb.getItems().add(dataStoreProvider));
|
||||
if (provider.getValue() == null) {
|
||||
provider.setValue(l.getFirst());
|
||||
}
|
||||
cb.setValue(provider.getValue());
|
||||
provider.bind(cb.valueProperty());
|
||||
cb.getStyleClass().add("choice-comp");
|
||||
cb.setAccessibleText("Choose connection type");
|
||||
cb.setOnKeyPressed(event -> {
|
||||
if (!event.getCode().equals(KeyCode.ENTER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cb.show();
|
||||
event.consume();
|
||||
});
|
||||
return new SimpleCompStructure<>(cb);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.charsetter.Charsetter;
|
||||
import io.xpipe.core.charsetter.CharsetterContext;
|
||||
import io.xpipe.core.charsetter.StreamCharset;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class AppCharsets {
|
||||
|
||||
private static final List<String> observedCharsets = new ArrayList<>();
|
||||
|
||||
public static void init() {
|
||||
var system = System.getProperty("file.encoding");
|
||||
var systemLocale = Locale.getDefault();
|
||||
var appLocale = AppPrefs.get().language.getValue().getLocale();
|
||||
var used = AppCache.get("observedCharsets", List.class, () -> new ArrayList<String>());
|
||||
var ctx = new CharsetterContext(system, systemLocale, appLocale, used);
|
||||
Charsetter.init(ctx);
|
||||
}
|
||||
|
||||
public static void observe(StreamCharset c) {
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var used = AppCache.get("observedCharsets", List.class, () -> new ArrayList<String>());
|
||||
used.add(c.getCharset().name());
|
||||
AppCache.update("observedCharsets", used);
|
||||
|
||||
init();
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import io.xpipe.core.charsetter.Charsetter;
|
||||
import io.xpipe.core.charsetter.StreamCharset;
|
||||
import io.xpipe.core.util.FailableConsumer;
|
||||
import io.xpipe.core.util.FailableSupplier;
|
||||
import org.apache.commons.io.ByteOrderMark;
|
||||
import org.apache.commons.io.input.BOMInputStream;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class AppCharsetter extends Charsetter {
|
||||
|
||||
private static final int MAX_BYTES = 8192;
|
||||
|
||||
public static void init() {
|
||||
Charsetter.INSTANCE = new AppCharsetter();
|
||||
}
|
||||
|
||||
public Result read(FailableSupplier<InputStream> in, FailableConsumer<InputStreamReader, Exception> con)
|
||||
throws Exception {
|
||||
checkInit();
|
||||
|
||||
try (var is = in.get();
|
||||
var bin = new BOMInputStream(is)) {
|
||||
ByteOrderMark bom = bin.getBOM();
|
||||
String charsetName = bom == null ? null : bom.getCharsetName();
|
||||
var charset = charsetName != null
|
||||
? StreamCharset.get(Charset.forName(charsetName), bom.getCharsetName() != null)
|
||||
: null;
|
||||
|
||||
bin.mark(MAX_BYTES);
|
||||
var bytes = bin.readNBytes(MAX_BYTES);
|
||||
bin.reset();
|
||||
if (charset == null) {
|
||||
charset = StreamCharset.get(inferCharset(bytes), false);
|
||||
}
|
||||
var nl = inferNewLine(bytes);
|
||||
|
||||
if (con != null) {
|
||||
con.accept(new InputStreamReader(bin, charset.getCharset()));
|
||||
}
|
||||
return new Result(charset, nl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package io.xpipe.app.ext;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class DownloadModuleInstall extends ModuleInstall {
|
||||
|
||||
private final String licenseFile;
|
||||
private final String vendorURL;
|
||||
|
||||
@Getter
|
||||
private final List<String> assets;
|
||||
|
||||
public DownloadModuleInstall(String id, String module, String licenseFile, String vendorURL, List<String> assets) {
|
||||
super(id, module);
|
||||
this.licenseFile = licenseFile;
|
||||
this.vendorURL = vendorURL;
|
||||
this.assets = assets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLicenseFile() {
|
||||
return licenseFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVendorURL() {
|
||||
return vendorURL;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package io.xpipe.app.ext;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Getter
|
||||
public abstract class ModuleInstall {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String module;
|
||||
|
||||
protected ModuleInstall(String id, String module) {
|
||||
this.id = id;
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public abstract String getLicenseFile();
|
||||
|
||||
public abstract String getVendorURL();
|
||||
|
||||
public abstract void installInternal(Path directory) throws Exception;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package io.xpipe.app.fxcomps.impl;
|
||||
|
||||
import com.jfoenix.controls.JFXTabPane;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import lombok.Getter;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class TabPaneComp extends Comp<CompStructure<JFXTabPane>> {
|
||||
|
||||
private final Property<Entry> selected;
|
||||
private final List<Entry> entries;
|
||||
|
||||
public TabPaneComp(Property<Entry> selected, List<Entry> entries) {
|
||||
this.selected = selected;
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<JFXTabPane> createBase() {
|
||||
JFXTabPane tabPane = new JFXTabPane();
|
||||
tabPane.getStyleClass().add("tab-pane-comp");
|
||||
|
||||
for (var e : entries) {
|
||||
Tab tab = new Tab();
|
||||
var ll = new Label(null);
|
||||
if (e.graphic != null) {
|
||||
ll.setGraphic(new FontIcon(e.graphic()));
|
||||
}
|
||||
ll.textProperty().bind(e.name());
|
||||
ll.getStyleClass().add("name");
|
||||
ll.setAlignment(Pos.CENTER);
|
||||
tab.setGraphic(ll);
|
||||
var content = e.comp().createRegion();
|
||||
tab.setContent(content);
|
||||
tabPane.getTabs().add(tab);
|
||||
content.prefWidthProperty().bind(tabPane.widthProperty());
|
||||
}
|
||||
|
||||
tabPane.getSelectionModel().select(entries.indexOf(selected.getValue()));
|
||||
tabPane.getSelectionModel().selectedIndexProperty().addListener((c, o, n) -> {
|
||||
selected.setValue(entries.get(n.intValue()));
|
||||
});
|
||||
selected.addListener((c, o, n) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
tabPane.getSelectionModel().select(entries.indexOf(n));
|
||||
});
|
||||
});
|
||||
|
||||
return new SimpleCompStructure<>(tabPane);
|
||||
}
|
||||
|
||||
public record Entry(ObservableValue<String> name, String graphic, Comp<?> comp) {}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import io.xpipe.app.comp.base.TileButtonComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AboutComp extends Comp<CompStructure<?>> {
|
||||
|
||||
private Comp<?> createLinks() {
|
||||
return new OptionsBuilder()
|
||||
.addComp(
|
||||
new TileButtonComp("discord", "discordDescription", "mdi2d-discord", e -> {
|
||||
Hyperlinks.open(Hyperlinks.DISCORD);
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.addComp(
|
||||
new TileButtonComp("slack", "slackDescription", "mdi2s-slack", e -> {
|
||||
Hyperlinks.open(Hyperlinks.SLACK);
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.addComp(
|
||||
new TileButtonComp("securityPolicy", "securityPolicyDescription", "mdrmz-security", e -> {
|
||||
Hyperlinks.open(Hyperlinks.SECURITY);
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.addComp(
|
||||
new TileButtonComp("privacy", "privacyDescription", "mdomz-privacy_tip", e -> {
|
||||
Hyperlinks.open(Hyperlinks.PRIVACY);
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.addComp(
|
||||
new TileButtonComp("thirdParty", "thirdPartyDescription", "mdi2o-open-source-initiative", e -> {
|
||||
AppWindowHelper.sideWindow(
|
||||
AppI18n.get("openSourceNotices"),
|
||||
stage -> Comp.of(() -> createThirdPartyDeps()),
|
||||
true,
|
||||
null)
|
||||
.show();
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.addComp(
|
||||
new TileButtonComp("eula", "eulaDescription", "mdi2c-card-text-outline", e -> {
|
||||
Hyperlinks.open(Hyperlinks.EULA);
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.buildComp();
|
||||
}
|
||||
|
||||
private Region createThirdPartyDeps() {
|
||||
var list = new ThirdPartyDependencyListComp().createRegion();
|
||||
list.getStyleClass().add("open-source-notices");
|
||||
var sp = new ScrollPane(list);
|
||||
sp.setFitToWidth(true);
|
||||
sp.setPrefWidth(600);
|
||||
sp.setPrefHeight(500);
|
||||
return sp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<?> createBase() {
|
||||
var props = new PropertiesComp().padding(new Insets(0, 0, 0, 15));
|
||||
var update = new UpdateCheckComp().grow(true, false);
|
||||
var box = new VerticalComp(List.of(props, Comp.separator(), update, Comp.separator(), createLinks()))
|
||||
.apply(s -> s.get().setFillWidth(true))
|
||||
.apply(struc -> struc.get().setSpacing(15))
|
||||
.styleClass("information")
|
||||
.styleClass("about-tab")
|
||||
.apply(struc -> struc.get().setPrefWidth(600));
|
||||
return box.createStructure();
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.Form;
|
||||
import com.dlsc.formsfx.model.util.TranslationService;
|
||||
import com.dlsc.preferencesfx.PreferencesFxEvent;
|
||||
import com.dlsc.preferencesfx.history.History;
|
||||
import com.dlsc.preferencesfx.model.Category;
|
||||
import com.dlsc.preferencesfx.model.PreferencesFxModel;
|
||||
import com.dlsc.preferencesfx.util.SearchHandler;
|
||||
import com.dlsc.preferencesfx.util.StorageHandler;
|
||||
import com.dlsc.preferencesfx.view.*;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.event.EventType;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class AppPreferencesFx {
|
||||
|
||||
private final PreferencesFxModel preferencesFxModel;
|
||||
|
||||
private NavigationView navigationView;
|
||||
private NavigationPresenter navigationPresenter;
|
||||
|
||||
private UndoRedoBox undoRedoBox;
|
||||
|
||||
private BreadCrumbView breadCrumbView;
|
||||
private BreadCrumbPresenter breadCrumbPresenter;
|
||||
|
||||
private CategoryController categoryController;
|
||||
|
||||
private PreferencesFxView preferencesFxView;
|
||||
private PreferencesFxPresenter preferencesFxPresenter;
|
||||
|
||||
private AppPreferencesFx(StorageHandler storageHandler, Category... categories) {
|
||||
preferencesFxModel = new PreferencesFxModel(storageHandler, new SearchHandler(), new History(), categories);
|
||||
|
||||
configure();
|
||||
}
|
||||
|
||||
public static AppPreferencesFx of(Category... categories) {
|
||||
return new AppPreferencesFx(new JsonStorageHandler(), categories);
|
||||
}
|
||||
|
||||
private void configure() {
|
||||
preferencesFxModel.setSaveSettings(true);
|
||||
preferencesFxModel.setHistoryDebugState(true);
|
||||
preferencesFxModel.setInstantPersistent(true);
|
||||
preferencesFxModel.setButtonsVisible(false);
|
||||
}
|
||||
|
||||
public void loadSettings() {
|
||||
// setting values are only loaded if they are present already
|
||||
preferencesFxModel.loadSettingValues();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void setupControls() {
|
||||
undoRedoBox = new UndoRedoBox(preferencesFxModel.getHistory());
|
||||
|
||||
breadCrumbView = new BreadCrumbView(preferencesFxModel, undoRedoBox) {
|
||||
@Override
|
||||
public void initializeParts() {}
|
||||
|
||||
@Override
|
||||
public void layoutParts() {}
|
||||
};
|
||||
breadCrumbPresenter = new BreadCrumbPresenter(preferencesFxModel, breadCrumbView);
|
||||
|
||||
categoryController = new CategoryController();
|
||||
categoryController.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
||||
categoryController.setFitToWidth(true);
|
||||
initializeCategoryViews();
|
||||
|
||||
// display initial category
|
||||
categoryController.setView(preferencesFxModel.getDisplayedCategory());
|
||||
|
||||
navigationView = new NavigationView(preferencesFxModel);
|
||||
var searchField = navigationView.getClass().getDeclaredField("searchFld");
|
||||
searchField.setAccessible(true);
|
||||
Node search = (Node) searchField.get(navigationView);
|
||||
search.setManaged(false);
|
||||
search.setVisible(false);
|
||||
navigationPresenter = new NavigationPresenter(preferencesFxModel, navigationView);
|
||||
|
||||
preferencesFxView =
|
||||
new PreferencesFxView(preferencesFxModel, navigationView, breadCrumbView, categoryController);
|
||||
preferencesFxPresenter = new PreferencesFxPresenter(preferencesFxModel, preferencesFxView) {
|
||||
@Override
|
||||
public void setupEventHandlers() {
|
||||
// Ignore window close
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ObjectProperty<TranslationService> translationServiceProperty() {
|
||||
return preferencesFxModel.translationServiceProperty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the CategoryController by creating CategoryView / CategoryPresenter pairs from all
|
||||
* Categories and loading them into the CategoryController.
|
||||
*/
|
||||
private void initializeCategoryViews() {
|
||||
preferencesFxModel.getFlatCategoriesLst().forEach(category -> {
|
||||
var categoryView = new CustomCategoryView(preferencesFxModel, category);
|
||||
CategoryPresenter categoryPresenter =
|
||||
new CategoryPresenter(preferencesFxModel, category, categoryView, breadCrumbPresenter) {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void initializeViewParts() {
|
||||
var formMethod = CategoryPresenter.class.getDeclaredMethod("createForm");
|
||||
formMethod.setAccessible(true);
|
||||
|
||||
var formField = CategoryPresenter.class.getDeclaredField("form");
|
||||
formField.setAccessible(true);
|
||||
formField.set(this, formMethod.invoke(this));
|
||||
categoryView.initializeFormRenderer((Form) formField.get(this));
|
||||
|
||||
this.addI18nListener();
|
||||
this.addInstantPersistenceListener();
|
||||
}
|
||||
};
|
||||
categoryController.addView(category, categoryView, categoryPresenter);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method to manually save the changed settings when showing the preferences by using
|
||||
* {@link #getView()}.
|
||||
*/
|
||||
public void saveSettings() {
|
||||
preferencesFxModel.saveSettings();
|
||||
((JsonStorageHandler) preferencesFxModel.getStorageHandler()).save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method to undo all changes made in the settings when showing the preferences by using
|
||||
* {@link #getView()}.
|
||||
*/
|
||||
public void discardChanges() {
|
||||
preferencesFxModel.discardChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event handler with the model. The handler is called when the model receives an
|
||||
* {@code Event} of the specified type during the bubbling phase of event delivery.
|
||||
*
|
||||
* @param eventType the type of the events to receive by the handler
|
||||
* @param eventHandler the handler to register
|
||||
* @return PreferencesFx to allow for chaining.
|
||||
* @throws NullPointerException if either event type or handler are {@code null}.
|
||||
*/
|
||||
public AppPreferencesFx addEventHandler(
|
||||
EventType<PreferencesFxEvent> eventType, EventHandler<? super PreferencesFxEvent> eventHandler) {
|
||||
preferencesFxModel.addEventHandler(eventType, eventHandler);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PreferencesFxView, so that it can be used as a Node.
|
||||
*
|
||||
* @return a PreferencesFxView, so that it can be used as a Node.
|
||||
*/
|
||||
public PreferencesFxView getView() {
|
||||
return preferencesFxView;
|
||||
}
|
||||
|
||||
public List<Category> getCategories() {
|
||||
return preferencesFxModel.getCategories();
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.Form;
|
||||
import com.dlsc.preferencesfx.model.Category;
|
||||
import com.dlsc.preferencesfx.model.PreferencesFxModel;
|
||||
import com.dlsc.preferencesfx.view.CategoryView;
|
||||
|
||||
public class CustomCategoryView extends CategoryView {
|
||||
|
||||
public CustomCategoryView(PreferencesFxModel model, Category categoryModel) {
|
||||
super(model, categoryModel);
|
||||
}
|
||||
|
||||
public void initializeFormRenderer(Form form) {
|
||||
getChildren().clear();
|
||||
var preferencesFormRenderer = new CustomFormRenderer(form);
|
||||
getChildren().add(preferencesFormRenderer);
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.Element;
|
||||
import com.dlsc.formsfx.model.structure.Field;
|
||||
import com.dlsc.formsfx.model.structure.Form;
|
||||
import com.dlsc.preferencesfx.formsfx.view.controls.SimpleControl;
|
||||
import com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxFormRenderer;
|
||||
import com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxGroup;
|
||||
import com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxGroupRenderer;
|
||||
import com.dlsc.preferencesfx.util.PreferencesFxUtils;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CustomFormRenderer extends PreferencesFxFormRenderer {
|
||||
|
||||
public static final double SPACING = 8.0;
|
||||
|
||||
public CustomFormRenderer(Form form) {
|
||||
super(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeParts() {
|
||||
groups = form.getGroups().stream()
|
||||
.map(group -> new PreferencesFxGroupRenderer((PreferencesFxGroup) group, this) {
|
||||
|
||||
@Override
|
||||
public void initializeParts() {
|
||||
super.initializeParts();
|
||||
grid.getStyleClass().add("grid");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public void layoutParts() {
|
||||
StringBuilder styleClass = new StringBuilder("group");
|
||||
|
||||
// if there are no rows yet, getRowCount returns -1, in this case the next row is 0
|
||||
int nextRow = PreferencesFxUtils.getRowCount(grid) + 1;
|
||||
|
||||
List<Element> elements = preferencesGroup.getElements().stream()
|
||||
.map(Element.class::cast)
|
||||
.toList();
|
||||
|
||||
// Only when the preferencesGroup has a title
|
||||
if (preferencesGroup.getTitle() != null && elements.size() > 0) {
|
||||
titleLabel.setPrefWidth(USE_COMPUTED_SIZE);
|
||||
grid.add(titleLabel, 0, nextRow++);
|
||||
titleLabel.getStyleClass().add("group-title");
|
||||
AppFont.setSize(titleLabel, 2);
|
||||
// Set margin for all but first group titles to visually separate groups
|
||||
if (nextRow > 1) {
|
||||
GridPane.setMargin(titleLabel, new Insets(SPACING * 5, 0, SPACING, 0));
|
||||
} else {
|
||||
GridPane.setMargin(titleLabel, new Insets(SPACING, 0, SPACING, 0));
|
||||
}
|
||||
}
|
||||
|
||||
styleClass.append("-setting");
|
||||
|
||||
int rowAmount = nextRow;
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
// add to GridPane
|
||||
Element element = elements.get(i);
|
||||
var offset = preferencesGroup.getTitle() != null ? 15 : 0;
|
||||
if (element instanceof Field f) {
|
||||
SimpleControl c = (SimpleControl) f.getRenderer();
|
||||
c.setField(f);
|
||||
AppFont.header(c.getFieldLabel());
|
||||
c.getFieldLabel().textProperty().unbind();
|
||||
c.getFieldLabel().textProperty().bind(Bindings.createStringBinding(() -> {
|
||||
return f.labelProperty().get() + (AppPrefs.get().getProRequiredSettings().contains(f) ? " (Pro)" : "");
|
||||
}, f.labelProperty()));
|
||||
grid.add(c.getFieldLabel(), 0, i + rowAmount);
|
||||
|
||||
var canFocus = BindingsHelper.persist(
|
||||
c.getNode().disabledProperty().not());
|
||||
|
||||
var descriptionLabel = new Label();
|
||||
descriptionLabel.setMaxWidth(600);
|
||||
AppFont.medium(descriptionLabel);
|
||||
descriptionLabel.setWrapText(true);
|
||||
descriptionLabel
|
||||
.disableProperty()
|
||||
.bind(c.getFieldLabel().disabledProperty());
|
||||
descriptionLabel
|
||||
.opacityProperty()
|
||||
.bind(c.getFieldLabel()
|
||||
.opacityProperty()
|
||||
.multiply(0.65));
|
||||
descriptionLabel
|
||||
.managedProperty()
|
||||
.bind(c.getFieldLabel().managedProperty());
|
||||
descriptionLabel
|
||||
.visibleProperty()
|
||||
.bind(c.getFieldLabel().visibleProperty());
|
||||
|
||||
var descriptionKey = f.getLabel() != null ? f.getLabel() + "Description" : null;
|
||||
if (AppI18n.getInstance().containsKey(descriptionKey)) {
|
||||
rowAmount++;
|
||||
descriptionLabel.textProperty().bind(AppI18n.observable(descriptionKey));
|
||||
descriptionLabel.focusTraversableProperty().bind(canFocus);
|
||||
grid.add(descriptionLabel, 0, i + rowAmount);
|
||||
}
|
||||
|
||||
rowAmount++;
|
||||
|
||||
var node = c.getNode();
|
||||
((Region) node).setMaxWidth(250);
|
||||
((Region) node).setMinWidth(250);
|
||||
AppFont.medium(c.getNode());
|
||||
c.getFieldLabel().focusTraversableProperty().bind(canFocus);
|
||||
grid.add(node, 0, i + rowAmount);
|
||||
|
||||
if (i == elements.size() - 1) {
|
||||
// additional styling for the last setting
|
||||
styleClass.append("-last");
|
||||
}
|
||||
|
||||
GridPane.setMargin(descriptionLabel, new Insets(SPACING, 0, 0, offset));
|
||||
GridPane.setMargin(node, new Insets(SPACING, 0, 0, offset));
|
||||
|
||||
if (!((i == 0) && (nextRow > 0))) {
|
||||
GridPane.setMargin(c.getFieldLabel(), new Insets(SPACING * 6, 0, 0, offset));
|
||||
} else {
|
||||
GridPane.setMargin(c.getFieldLabel(), new Insets(SPACING, 0, 0, offset));
|
||||
}
|
||||
|
||||
c.getFieldLabel().getStyleClass().add(styleClass + "-label");
|
||||
node.getStyleClass().add(styleClass + "-node");
|
||||
}
|
||||
|
||||
if (element instanceof LazyNodeElement<?> nodeElement) {
|
||||
var node = nodeElement.getNode();
|
||||
if (node instanceof Region r) {
|
||||
r.setMaxWidth(600);
|
||||
}
|
||||
grid.add(node, 0, i + rowAmount);
|
||||
GridPane.setMargin(node, new Insets(SPACING, 0, 0, offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import atlantafx.base.controls.ToggleSwitch;
|
||||
import com.dlsc.formsfx.model.structure.BooleanField;
|
||||
import com.dlsc.preferencesfx.formsfx.view.controls.SimpleControl;
|
||||
import com.dlsc.preferencesfx.formsfx.view.controls.ToggleControl;
|
||||
import com.dlsc.preferencesfx.util.VisibilityProperty;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
/**
|
||||
* Displays a control for boolean values with a toggle from ControlsFX.
|
||||
*
|
||||
* @author François Martin
|
||||
* @author Marco Sanfratello
|
||||
*/
|
||||
public class CustomToggleControl extends SimpleControl<BooleanField, ToggleSwitch> {
|
||||
|
||||
/**
|
||||
* Constructs a ToggleControl of {@link ToggleControl} type, with visibility condition.
|
||||
*
|
||||
* @param visibilityProperty property for control visibility of this element
|
||||
*
|
||||
* @return the constructed ToggleControl
|
||||
*/
|
||||
public static ToggleControl of(VisibilityProperty visibilityProperty) {
|
||||
ToggleControl toggleControl = new ToggleControl();
|
||||
|
||||
toggleControl.setVisibilityProperty(visibilityProperty);
|
||||
|
||||
return toggleControl;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void initializeParts() {
|
||||
super.initializeParts();
|
||||
fieldLabel = new Label(field.labelProperty().getValue());
|
||||
node = new atlantafx.base.controls.ToggleSwitch();
|
||||
node.getStyleClass().add("toggle-control");
|
||||
node.setSelected(field.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void layoutParts() {}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setupBindings() {
|
||||
super.setupBindings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setupValueChangedListeners() {
|
||||
super.setupValueChangedListeners();
|
||||
field.userInputProperty().addListener((observable, oldValue, newValue) -> {
|
||||
node.setSelected(Boolean.parseBoolean(field.getUserInput()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setupEventHandlers() {
|
||||
node.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
field.userInputProperty().setValue(String.valueOf(newValue));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.validators.CustomValidator;
|
||||
import com.dlsc.formsfx.model.validators.Validator;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class CustomValidators {
|
||||
|
||||
public static Validator<String> absolutePath() {
|
||||
return CustomValidator.forPredicate(
|
||||
(String s) -> {
|
||||
try {
|
||||
var p = Path.of(s);
|
||||
return p.isAbsolute();
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
AppI18n.get("notAnAbsolutePath"));
|
||||
}
|
||||
|
||||
public static Validator<String> directory() {
|
||||
return CustomValidator.forPredicate(
|
||||
(String s) -> {
|
||||
var p = Path.of(s);
|
||||
return Files.exists(p) && Files.isDirectory(p);
|
||||
},
|
||||
AppI18n.get("notADirectory"));
|
||||
}
|
||||
}
|
|
@ -1,195 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.preferencesfx.util.StorageHandler;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.NullNode;
|
||||
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.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.util.JsonConfigHelper;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static io.xpipe.app.ext.PrefsChoiceValue.getAll;
|
||||
import static io.xpipe.app.ext.PrefsChoiceValue.getSupported;
|
||||
|
||||
public class JsonStorageHandler implements StorageHandler {
|
||||
|
||||
private final Path file =
|
||||
AppProperties.get().getDataDir().resolve("settings").resolve("preferences.json");
|
||||
private ObjectNode content;
|
||||
|
||||
private String getSaveId(String bc) {
|
||||
return bc.split("#")[bc.split("#").length - 1];
|
||||
}
|
||||
|
||||
private JsonNode getContent(String key) {
|
||||
if (content == null) {
|
||||
content = JsonConfigHelper.readConfigObject(file);
|
||||
}
|
||||
return content.get(key);
|
||||
}
|
||||
|
||||
private void setContent(String key, JsonNode value) {
|
||||
content.set(key, value);
|
||||
}
|
||||
|
||||
void save() {
|
||||
JsonConfigHelper.writeConfig(file, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveObject(String breadcrumb, Object object) {
|
||||
var id = getSaveId(breadcrumb);
|
||||
var tree = object instanceof PrefsChoiceValue prefsChoiceValue
|
||||
? new TextNode(prefsChoiceValue.getId())
|
||||
: (object != null ? JacksonMapper.getDefault().valueToTree(object) : NullNode.getInstance());
|
||||
setContent(id, tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object loadObject(String breadcrumb, Object defaultObject) {
|
||||
Class<Object> c = (Class<Object>) AppPrefs.get().getSettingType(breadcrumb);
|
||||
return loadObject(breadcrumb, c, defaultObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T loadObject(String breadcrumb, Class<T> type, T defaultObject) {
|
||||
var id = getSaveId(breadcrumb);
|
||||
var tree = getContent(id);
|
||||
if (tree == null) {
|
||||
TrackEvent.debug("Preferences value not found for key: " + breadcrumb);
|
||||
return defaultObject;
|
||||
}
|
||||
|
||||
var all = getAll(type);
|
||||
if (all != null) {
|
||||
Class<PrefsChoiceValue> cast = (Class<PrefsChoiceValue>) type;
|
||||
var in = tree.asText();
|
||||
var found = all.stream()
|
||||
.filter(t -> ((PrefsChoiceValue) t).getId().equalsIgnoreCase(in))
|
||||
.findAny();
|
||||
if (found.isEmpty()) {
|
||||
TrackEvent.withWarn("Invalid prefs value found")
|
||||
.tag("key", id)
|
||||
.tag("value", in)
|
||||
.handle();
|
||||
return defaultObject;
|
||||
}
|
||||
|
||||
var supported = getSupported(cast);
|
||||
if (!supported.contains(found.get())) {
|
||||
TrackEvent.withWarn("Unsupported prefs value found")
|
||||
.tag("key", id)
|
||||
.tag("value", in)
|
||||
.handle();
|
||||
return defaultObject;
|
||||
}
|
||||
|
||||
TrackEvent.debug("Loading preferences value for key " + breadcrumb + " from value " + found.get());
|
||||
return found.get();
|
||||
}
|
||||
|
||||
try {
|
||||
TrackEvent.debug("Loading preferences value for key " + breadcrumb + " from value " + tree);
|
||||
return JacksonMapper.getDefault().treeToValue(tree, type);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).omit().handle();
|
||||
return defaultObject;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ObservableList<?> loadObservableList(String breadcrumb, ObservableList defaultObservableList) {
|
||||
return loadObservableList(breadcrumb, defaultObservableList.get(0).getClass(), defaultObservableList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObservableList<T> loadObservableList(
|
||||
String breadcrumb, Class<T> type, ObservableList<T> defaultObservableList) {
|
||||
var id = getSaveId(breadcrumb);
|
||||
var tree = getContent(id);
|
||||
if (tree == null) {
|
||||
return defaultObservableList;
|
||||
}
|
||||
|
||||
try {
|
||||
CollectionType javaType =
|
||||
JacksonMapper.newMapper().getTypeFactory().constructCollectionType(List.class, type);
|
||||
return JacksonMapper.newMapper().treeToValue(tree, javaType);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).omit().handle();
|
||||
return defaultObservableList;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearPreferences() {
|
||||
return FileUtils.deleteQuietly(file.toFile());
|
||||
}
|
||||
|
||||
// ======
|
||||
// UNUSED
|
||||
// ======
|
||||
|
||||
@Override
|
||||
public void saveSelectedCategory(String breadcrumb) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String loadSelectedCategory() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDividerPosition(double dividerPosition) {}
|
||||
|
||||
@Override
|
||||
public double loadDividerPosition() {
|
||||
return 0.27;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveWindowWidth(double windowWidth) {}
|
||||
|
||||
@Override
|
||||
public double loadWindowWidth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveWindowHeight(double windowHeight) {}
|
||||
|
||||
@Override
|
||||
public double loadWindowHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveWindowPosX(double windowPosX) {}
|
||||
|
||||
@Override
|
||||
public double loadWindowPosX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveWindowPosY(double windowPosY) {}
|
||||
|
||||
@Override
|
||||
public double loadWindowPosY() {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.Element;
|
||||
import javafx.scene.Node;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class LazyNodeElement<N extends Node> extends Element<LazyNodeElement<N>> {
|
||||
|
||||
protected Supplier<N> node;
|
||||
|
||||
public static <T extends Node> LazyNodeElement<T> of(Supplier<T> node) {
|
||||
return new LazyNodeElement<>(node);
|
||||
}
|
||||
|
||||
protected LazyNodeElement(Supplier<N> node) {
|
||||
if (node == null) {
|
||||
throw new NullPointerException("Node argument must not be null");
|
||||
}
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public N getNode() {
|
||||
return node.get();
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import com.dlsc.preferencesfx.model.Category;
|
||||
import com.dlsc.preferencesfx.model.Group;
|
||||
import com.dlsc.preferencesfx.model.Setting;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
||||
import io.xpipe.app.util.TerminalHelper;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.process.CommandControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.LocalStore;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import lombok.SneakyThrows;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PasswordCategory extends AppPrefsCategory {
|
||||
|
||||
public PasswordCategory(AppPrefs prefs) {
|
||||
super(prefs);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public Category create() {
|
||||
var testPasswordManagerValue = new SimpleStringProperty();
|
||||
Runnable test = () -> {
|
||||
prefs.save();
|
||||
var cmd = prefs.passwordManagerString(testPasswordManagerValue.get());
|
||||
if (cmd == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
TerminalHelper.open(
|
||||
"Password test",
|
||||
new LocalStore()
|
||||
.control()
|
||||
.command(cmd
|
||||
+ "\n"
|
||||
+ ShellDialects.getPlatformDefault()
|
||||
.getEchoCommand("Is this your password?", false))
|
||||
.terminalExitMode(CommandControl.TerminalExitMode.KEEP_OPEN));
|
||||
});
|
||||
};
|
||||
|
||||
var testPasswordManager = lazyNode(
|
||||
"passwordManagerCommandTest",
|
||||
new HorizontalComp(List.of(
|
||||
new TextFieldComp(testPasswordManagerValue)
|
||||
.apply(struc -> struc.get().setPromptText("Test password key"))
|
||||
.styleClass(Styles.LEFT_PILL)
|
||||
.grow(false, true),
|
||||
new ButtonComp(null, new FontIcon("mdi2p-play"), test)
|
||||
.styleClass(Styles.RIGHT_PILL)
|
||||
.grow(false, true)))
|
||||
.padding(new Insets(15, 0, 0, 0))
|
||||
.apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT))
|
||||
.apply(struc -> struc.get().setFillHeight(true)),
|
||||
null);
|
||||
return Category.of(
|
||||
"passwordManager",
|
||||
Group.of(
|
||||
Setting.of("passwordManagerCommand", prefs.passwordManagerCommand),
|
||||
testPasswordManager));
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.StringField;
|
||||
import com.dlsc.preferencesfx.formsfx.view.controls.SimpleChooserControl;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class PrefFields {
|
||||
|
||||
public static StringField ofPath(ObjectProperty<Path> fileProperty) {
|
||||
StringProperty stringProperty = new SimpleStringProperty(fileProperty.getValue().toString());
|
||||
|
||||
// Prevent garbage collection of this due to how preferencesfx handles properties via bindings
|
||||
BindingsHelper.linkPersistently(fileProperty, stringProperty);
|
||||
|
||||
stringProperty.addListener((observable, oldValue, newValue) -> {
|
||||
fileProperty.setValue(newValue != null ? Path.of(newValue) : null);
|
||||
});
|
||||
|
||||
fileProperty.addListener((observable, oldValue, newValue) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
stringProperty.setValue(newValue != null ? newValue.toString() : "");
|
||||
});
|
||||
});
|
||||
|
||||
return StringField.ofStringType(stringProperty)
|
||||
.render(() -> {
|
||||
var c = new SimpleChooserControl(
|
||||
AppI18n.get("browse"), fileProperty.getValue().toFile(), true);
|
||||
c.setMinWidth(600);
|
||||
c.setPrefWidth(600);
|
||||
return c;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.controlsfx.control.MasterDetailPane;
|
||||
|
||||
public class PrefsComp extends SimpleComp {
|
||||
|
||||
private final AppLayoutModel layout;
|
||||
|
||||
public PrefsComp(AppLayoutModel layout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
return createButtonOverlay();
|
||||
}
|
||||
|
||||
private Region createButtonOverlay() {
|
||||
var pfx = AppPrefs.get().createControls().getView();
|
||||
pfx.getStyleClass().add("prefs");
|
||||
MasterDetailPane p = (MasterDetailPane) pfx.getCenter();
|
||||
p.dividerPositionProperty().setValue(0.27);
|
||||
|
||||
var stack = new StackPane(pfx);
|
||||
stack.setPickOnBounds(false);
|
||||
AppFont.medium(stack);
|
||||
|
||||
return stack;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||
import io.xpipe.app.util.JfxHelper;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
public class PropertiesComp extends SimpleComp {
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var title = Comp.of(() -> {
|
||||
return JfxHelper.createNamedEntry(AppI18n.get("xPipeClient"), "Version " + AppProperties.get().getVersion() + " ("
|
||||
+ AppProperties.get().getArch() + ")", "logo/logo_48x48.png");
|
||||
});
|
||||
|
||||
var section = new OptionsBuilder()
|
||||
.addComp(title, null)
|
||||
.addComp(Comp.vspacer(10))
|
||||
.name("build")
|
||||
.addComp(
|
||||
new LabelComp(AppProperties.get().getBuild()),
|
||||
null)
|
||||
.name("runtimeVersion")
|
||||
.addComp(
|
||||
new LabelComp(System.getProperty("java.vm.version")),
|
||||
null)
|
||||
.name("virtualMachine")
|
||||
.addComp(
|
||||
new LabelComp(System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name")),
|
||||
null)
|
||||
.buildComp();
|
||||
return section.styleClass("properties-comp").createRegion();
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.util.ResourceBundleService;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class QuietResourceBundleService extends ResourceBundleService {
|
||||
|
||||
public QuietResourceBundleService() {
|
||||
super(new ResourceBundle() {
|
||||
@Override
|
||||
protected Object handleGetObject(@NonNull String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Enumeration<String> getKeys() {
|
||||
return Collections.emptyEnumeration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translate(String key) {
|
||||
return AppI18n.get(key);
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.dlsc.formsfx.model.structure.SingleSelectionField;
|
||||
import com.dlsc.preferencesfx.formsfx.view.controls.SimpleControl;
|
||||
import io.xpipe.app.util.Translatable;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.StackPane;
|
||||
|
||||
public class TranslatableComboBoxControl<V extends Translatable>
|
||||
extends SimpleControl<SingleSelectionField<V>, StackPane> {
|
||||
|
||||
private ComboBox<V> comboBox;
|
||||
private Label readOnlyLabel;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void initializeParts() {
|
||||
super.initializeParts();
|
||||
|
||||
fieldLabel = new Label(field.labelProperty().getValue());
|
||||
readOnlyLabel = new Label();
|
||||
|
||||
node = new StackPane();
|
||||
node.getStyleClass().add("simple-select-control");
|
||||
|
||||
comboBox = new ComboBox<V>(field.getItems());
|
||||
comboBox.setConverter(Translatable.stringConverter());
|
||||
|
||||
comboBox.getSelectionModel().select(field.getItems().indexOf(field.getSelection()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void layoutParts() {
|
||||
readOnlyLabel.getStyleClass().add("read-only-label");
|
||||
|
||||
comboBox.setMaxWidth(Double.MAX_VALUE);
|
||||
comboBox.setVisibleRowCount(10);
|
||||
|
||||
node.setAlignment(Pos.CENTER_LEFT);
|
||||
node.getChildren().addAll(comboBox, readOnlyLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setupBindings() {
|
||||
super.setupBindings();
|
||||
|
||||
comboBox.visibleProperty().bind(field.editableProperty());
|
||||
readOnlyLabel.visibleProperty().bind(field.editableProperty().not());
|
||||
readOnlyLabel.textProperty().bind(Translatable.asTranslatedString(comboBox.valueProperty()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setupValueChangedListeners() {
|
||||
super.setupValueChangedListeners();
|
||||
|
||||
field.itemsProperty().addListener((observable, oldValue, newValue) -> comboBox.setItems(field.getItems()));
|
||||
|
||||
field.selectionProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (field.getSelection() != null) {
|
||||
comboBox.getSelectionModel().select(field.getItems().indexOf(field.getSelection()));
|
||||
} else {
|
||||
comboBox.getSelectionModel().clearSelection();
|
||||
}
|
||||
});
|
||||
|
||||
field.errorMessagesProperty().addListener((observable, oldValue, newValue) -> toggleTooltip(comboBox));
|
||||
field.tooltipProperty().addListener((observable, oldValue, newValue) -> toggleTooltip(comboBox));
|
||||
comboBox.focusedProperty().addListener((observable, oldValue, newValue) -> toggleTooltip(comboBox));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setupEventHandlers() {
|
||||
comboBox.valueProperty()
|
||||
.addListener((observable, oldValue, newValue) ->
|
||||
field.select(comboBox.getSelectionModel().getSelectedIndex()));
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import io.xpipe.app.comp.base.TileButtonComp;
|
||||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.UserReportComp;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.LocalStore;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TroubleshootComp extends Comp<CompStructure<?>> {
|
||||
|
||||
private Comp<?> createActions() {
|
||||
OptionsBuilder b = new OptionsBuilder()
|
||||
.addTitle("troubleshootingOptions")
|
||||
.spacer(13)
|
||||
.addComp(
|
||||
new TileButtonComp("reportIssue", "reportIssueDescription", "mdal-bug_report", e -> {
|
||||
var event = ErrorEvent.fromMessage("User Report");
|
||||
if (AppLogs.get().isWriteToFile()) {
|
||||
event.attachment(AppLogs.get().getSessionLogsDirectory());
|
||||
}
|
||||
UserReportComp.show(event.build());
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.separator()
|
||||
// .addComp(
|
||||
// new TileButtonComp("restart", "restartDescription", "mdmz-refresh", e -> {
|
||||
// OperationMode.executeAfterShutdown(() -> {
|
||||
// try (var sc = ShellStore.createLocal()
|
||||
// .control()
|
||||
// .start()) {
|
||||
// var script = FileNames.join(
|
||||
// XPipeInstallation.getCurrentInstallationBasePath()
|
||||
// .toString(),
|
||||
//
|
||||
// XPipeInstallation.getDaemonExecutablePath(sc.getOsType()));
|
||||
// sc.executeSimpleCommand(
|
||||
// ScriptHelper.createDetachCommand(sc, "\"" + script
|
||||
// + "\""));
|
||||
// }
|
||||
// });
|
||||
// e.consume();
|
||||
// })
|
||||
// .grow(true, false),
|
||||
// null)
|
||||
// .separator()
|
||||
.addComp(
|
||||
new TileButtonComp("launchDebugMode", "launchDebugModeDescription", "mdmz-refresh", e -> {
|
||||
OperationMode.executeAfterShutdown(() -> {
|
||||
try (var sc = new LocalStore()
|
||||
.control()
|
||||
.start()) {
|
||||
var script = FileNames.join(
|
||||
XPipeInstallation.getCurrentInstallationBasePath()
|
||||
.toString(),
|
||||
XPipeInstallation.getDaemonDebugScriptPath(sc.getOsType()));
|
||||
if (sc.getOsType().equals(OsType.WINDOWS)) {
|
||||
sc.executeSimpleCommand(
|
||||
ApplicationHelper.createDetachCommand(sc, "\"" + script + "\""));
|
||||
} else {
|
||||
TerminalHelper.open("XPipe Debug", LocalShell.getShell().command("\"" + script + "\""));
|
||||
}
|
||||
}
|
||||
});
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.separator();
|
||||
|
||||
if (AppLogs.get().isWriteToFile()) {
|
||||
b.addComp(
|
||||
new TileButtonComp(
|
||||
"openCurrentLogFile",
|
||||
"openCurrentLogFileDescription",
|
||||
"mdmz-text_snippet",
|
||||
e -> {
|
||||
FileOpener.openInTextEditor(AppLogs.get()
|
||||
.getSessionLogsDirectory()
|
||||
.resolve("xpipe.log")
|
||||
.toString());
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.separator();
|
||||
}
|
||||
|
||||
b.addComp(
|
||||
new TileButtonComp(
|
||||
"openInstallationDirectory",
|
||||
"openInstallationDirectoryDescription",
|
||||
"mdomz-snippet_folder",
|
||||
e -> {
|
||||
DesktopHelper.browsePath(
|
||||
XPipeInstallation.getCurrentInstallationBasePath());
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null)
|
||||
.separator()
|
||||
.addComp(
|
||||
new TileButtonComp("clearCaches", "clearCachesDescription", "mdi2t-trash-can-outline", e -> {
|
||||
ClearCacheAlert.show();
|
||||
e.consume();
|
||||
})
|
||||
.grow(true, false),
|
||||
null);
|
||||
return b.buildComp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<?> createBase() {
|
||||
var box = new VerticalComp(List.of(createActions()))
|
||||
.apply(s -> s.get().setFillWidth(true))
|
||||
.apply(struc -> struc.get().setSpacing(15))
|
||||
.styleClass("troubleshoot-tab")
|
||||
.apply(struc -> struc.get().setPrefWidth(600));
|
||||
return box.createStructure();
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package io.xpipe.app.test;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.ext.XPipeServiceProviders;
|
||||
import io.xpipe.app.util.XPipeSession;
|
||||
import io.xpipe.beacon.BeaconDaemonController;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.core.util.XPipeDaemonMode;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class DaemonExtensionTest extends ExtensionTest {
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
AppProperties.init();
|
||||
JacksonMapper.initModularized(ModuleLayer.boot());
|
||||
XPipeServiceProviders.load(ModuleLayer.boot());
|
||||
XPipeSession.init(UUID.randomUUID());
|
||||
BeaconDaemonController.start(XPipeDaemonMode.TRAY);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
BeaconDaemonController.stop();
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.util.AesSecretValue;
|
||||
import io.xpipe.core.util.DefaultSecretValue;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Random;
|
||||
|
||||
@JsonTypeName("locked")
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class LockedSecretValue extends AesSecretValue {
|
||||
|
||||
public LockedSecretValue(char[] secret) {
|
||||
super(secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretValue inPlace() {
|
||||
return new DefaultSecretValue(getSecret());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<locked secret>";
|
||||
}
|
||||
|
||||
protected SecretKey getAESKey(int keysize) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
var chars = AppPrefs.get().getLockPassword().getValue() != null
|
||||
? AppPrefs.get().getLockPassword().getValue().getSecret()
|
||||
: new char[0];
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
var salt = new byte[16];
|
||||
new Random(keysize).nextBytes(salt);
|
||||
KeySpec spec = new PBEKeySpec(chars, salt, 8192, keysize);
|
||||
return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.util.DefaultSecretValue;
|
||||
import io.xpipe.core.util.EncryptedSecretValue;
|
||||
|
||||
public class SecretHelper {
|
||||
|
||||
public static EncryptedSecretValue encryptInPlace(char[] c) {
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DefaultSecretValue(c);
|
||||
}
|
||||
|
||||
public static EncryptedSecretValue encryptInPlace(String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return encryptInPlace(s.toCharArray());
|
||||
}
|
||||
|
||||
public static EncryptedSecretValue encrypt(char[] c) {
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (AppPrefs.get() != null && AppPrefs.get().getLockPassword().getValue() != null) {
|
||||
return new LockedSecretValue(c);
|
||||
}
|
||||
|
||||
return new DefaultSecretValue(c);
|
||||
}
|
||||
|
||||
public static EncryptedSecretValue encrypt(String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return encrypt(s.toCharArray());
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Bounds;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.ScrollBar;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.ScrollEvent;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class SmoothScroll {
|
||||
|
||||
private static ScrollBar getScrollbarComponent(Node no, Orientation orientation) {
|
||||
Node n = no.lookup(".scroll-bar");
|
||||
if (n instanceof final ScrollBar bar) {
|
||||
if (bar.getOrientation().equals(orientation)) {
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void smoothScrollingListView(Node n, double speed) {
|
||||
smoothScrollingListView(n, speed, Orientation.VERTICAL, bounds -> bounds.getHeight());
|
||||
}
|
||||
|
||||
public static void smoothHScrollingListView(ListView<?> listView, double speed) {
|
||||
smoothScrollingListView(listView, speed, Orientation.HORIZONTAL, bounds -> bounds.getHeight());
|
||||
}
|
||||
|
||||
private static void smoothScrollingListView(
|
||||
Node n, double speed, Orientation orientation, Function<Bounds, Double> sizeFunc) {
|
||||
((TableView<?>) n).skinProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
ScrollBar scrollBar = getScrollbarComponent(n, orientation);
|
||||
if (scrollBar == null) {
|
||||
return;
|
||||
}
|
||||
scrollBar.setUnitIncrement(1);
|
||||
final double[] frictions = {
|
||||
0.99, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.04, 0.01, 0.008, 0.008, 0.008, 0.008, 0.0006, 0.0005,
|
||||
0.00003, 0.00001
|
||||
};
|
||||
final double[] pushes = {speed};
|
||||
final double[] derivatives = new double[frictions.length];
|
||||
final double[] lastVPos = {0};
|
||||
Timeline timeline = new Timeline();
|
||||
final EventHandler<MouseEvent> dragHandler = event -> timeline.stop();
|
||||
final EventHandler<ScrollEvent> scrollHandler = event -> {
|
||||
scrollBar.valueProperty().set(lastVPos[0]);
|
||||
if (event.getEventType() == ScrollEvent.SCROLL) {
|
||||
double direction = event.getDeltaY() > 0 ? -1 : 1;
|
||||
for (int i = 0; i < pushes.length; i++) {
|
||||
derivatives[i] += direction * pushes[i];
|
||||
}
|
||||
if (timeline.getStatus() == Animation.Status.STOPPED) {
|
||||
timeline.play();
|
||||
}
|
||||
}
|
||||
event.consume();
|
||||
};
|
||||
if (scrollBar.getParent() != null) {
|
||||
scrollBar.getParent().addEventHandler(MouseEvent.DRAG_DETECTED, dragHandler);
|
||||
scrollBar.getParent().addEventHandler(ScrollEvent.ANY, scrollHandler);
|
||||
}
|
||||
scrollBar.parentProperty().addListener((o, oldVal, newVal) -> {
|
||||
if (oldVal != null) {
|
||||
oldVal.removeEventHandler(MouseEvent.DRAG_DETECTED, dragHandler);
|
||||
oldVal.removeEventHandler(ScrollEvent.ANY, scrollHandler);
|
||||
}
|
||||
if (newVal != null) {
|
||||
newVal.addEventHandler(MouseEvent.DRAG_DETECTED, dragHandler);
|
||||
newVal.addEventHandler(ScrollEvent.ANY, scrollHandler);
|
||||
}
|
||||
});
|
||||
|
||||
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(3), (event) -> {
|
||||
for (int i = 0; i < derivatives.length; i++) {
|
||||
derivatives[i] *= frictions[i];
|
||||
}
|
||||
for (int i = 1; i < derivatives.length; i++) {
|
||||
derivatives[i] += derivatives[i - 1];
|
||||
}
|
||||
double dy = derivatives[derivatives.length - 1];
|
||||
double size = sizeFunc.apply(scrollBar.getLayoutBounds());
|
||||
scrollBar.valueProperty().set(Math.min(Math.max(scrollBar.getValue() + dy / size, 0), 1));
|
||||
lastVPos[0] = scrollBar.getValue();
|
||||
if (Math.abs(dy) < 1) {
|
||||
if (Math.abs(dy) < 0.001) {
|
||||
timeline.stop();
|
||||
}
|
||||
}
|
||||
}));
|
||||
timeline.setCycleCount(Animation.INDEFINITE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.ExternalTerminalType;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.process.ProcessControl;
|
||||
import io.xpipe.core.process.TerminalInitScriptConfig;
|
||||
|
||||
public class TerminalHelper {
|
||||
|
||||
public static void open(String title, ProcessControl cc) throws Exception {
|
||||
open(null, title, cc);
|
||||
}
|
||||
|
||||
public static void open(DataStoreEntry entry, String title, ProcessControl cc) throws Exception {
|
||||
var type = AppPrefs.get().terminalType().getValue();
|
||||
if (type == null) {
|
||||
throw ErrorEvent.unreportable(new IllegalStateException(AppI18n.get("noTerminalSet")));
|
||||
}
|
||||
|
||||
var color = entry != null ? DataStorage.get().getRootForEntry(entry).getColor() : null;
|
||||
var prefix = entry != null && color != null && type.supportsColoredTitle()
|
||||
? color.getEmoji() + " "
|
||||
: "";
|
||||
var cleanTitle = (title != null ? title : entry != null ? entry.getName() : "?");
|
||||
var adjustedTitle = prefix + cleanTitle;
|
||||
var file = ScriptHelper.createLocalExecScript(cc.prepareTerminalOpen(new TerminalInitScriptConfig(adjustedTitle, type.shouldClear(), color != null)));
|
||||
var config = new ExternalTerminalType.LaunchConfiguration(entry != null ? color : null, adjustedTitle, cleanTitle, file);
|
||||
try {
|
||||
type.launch(config);
|
||||
} catch (Exception ex) {
|
||||
throw ErrorEvent.unreportable(ex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
storeForLaterUse=Store for later use
|
||||
localMachine=Local
|
||||
localFile=Local File
|
||||
network=Network
|
||||
recentFiles=Recent files
|
||||
newDataSource=New data source
|
||||
newDataStore=New data store
|
||||
selectInput=Select Input
|
||||
configure=Configure
|
||||
retrieve=Retrieve
|
||||
internet=Internet
|
||||
table=Table
|
||||
update=Update
|
||||
selectStreamStore=Select Stream Store
|
||||
openStreamStoreWizard=Open Stream Store Wizard
|
||||
updateDataSource=Update Data Source
|
||||
structure=Structure
|
||||
text=Text
|
||||
raw=Raw
|
||||
collection=Collection
|
||||
anyFile=Any file
|
||||
anyStream=Any Stream Type
|
||||
noMatchingStoreFound=No suitable saved store was found
|
||||
addStore=Add Store
|
||||
anyStreamDescription=Or choose specific type
|
||||
restart=Restart XPipe
|
||||
restartDescription=A restart can often be a quick fix
|
||||
reportIssue=Report Issue
|
||||
reportIssueDescription=Open the integrated issue reporter
|
||||
usefulActions=Useful actions
|
||||
stored=Saved
|
||||
troubleshootingOptions=Troubleshooting options
|
||||
troubleshoot=Troubleshoot
|
||||
other=Other
|
||||
remote=Remote File
|
||||
addShellStore=Add Shell ...
|
||||
addShellTitle=Add Shell Connection
|
||||
savedConnections=Saved Connections
|
||||
none=None
|
||||
save=Save
|
||||
clean=Clean
|
||||
refresh=Refresh
|
||||
moveTo=Move to ...
|
||||
remove=Remove
|
||||
addDatabase=Database ...
|
||||
addCluster=Cluster ...
|
||||
browseInternalStorage=Browse internal storage
|
||||
addTunnel=Tunnel ...
|
||||
addScript=Script ...
|
||||
addHost=Remote Host ...
|
||||
addShell=Shell Environment ...
|
||||
addCommand=Custom Command ...
|
||||
addAutomatically=Search Automatically ...
|
||||
addOther=Add Other ...
|
||||
addStreamTitle=Add Stream Store
|
||||
addConnection=Add Connection
|
||||
addConnections=New
|
||||
selectType=Select Type
|
||||
selectTypeDescription=Select connection type
|
||||
selectDatabaseType=Database Type
|
||||
selectDatabaseTypeDescription=Select Type of the Database
|
||||
selectShellType=Shell Type
|
||||
selectShellTypeDescription=Select the Type of the Shell Connection
|
||||
selectStreamType=Stream Type
|
||||
selectStreamTypeDescription=Select type of the stream
|
||||
name=Name
|
||||
configuration=Configuration
|
||||
dragAndDropFilesHere=Or just drag and drop a file here
|
||||
confirmDsCreationAbortTitle=Confirm abort
|
||||
confirmDsCreationAbortHeader=Do you want to abort the data source creation?
|
||||
confirmDsCreationAbortContent=Any data source creation progress will be lost.
|
||||
confirmInvalidStoreTitle=Confirm invalid data store
|
||||
confirmInvalidStoreHeader=Do you want to add this data store anyway?
|
||||
confirmInvalidStoreContent=You can use this store even if it could not be validated.
|
|
@ -1,21 +0,0 @@
|
|||
introTitle=Data sources
|
||||
introDescription=Pipe, manage, and store many different types of data.
|
||||
introCollection=Data source collections allow you to store and\norganize all your data sources for later use.
|
||||
introPipe=Pipe data from any origin to any destination\nacross formats while maintaining compatibility.
|
||||
introDocumentation=In case you prefer a more structured approach to\nfamiliarizing yourself with XPipe, check out the documentation:
|
||||
introEntry=Once you have done that, you can add a new data source to it.\nThere are different types of data sources to choose from:
|
||||
introTableDataSource=Tabular data sources, for example a database table, an excel sheet, or a csv file.
|
||||
dataSourceIntroTitle=Categories of Data Sources
|
||||
dataSourceIntroDescription=The next step is to add a data sources to this collection (See above). XPipe\ndifferentiates between several categories of data sources for different purposes.
|
||||
dataSourceIntroTable=Tabular data sources contain data represented by some kind of table.\nExamples are database tables, Excel sheets, or .csv files.
|
||||
dataSourceIntroStructure=Structure data sources contain some form of object structure.\nExamples are .json files, .xml files, or certain types of NoSQL databases.
|
||||
dataSourceIntroText=Text data sources contain readable text that can\ncome in a variety of different encodings and simple formats.
|
||||
dataSourceIntroBinary=Binary data sources contain binary data. They\ncan be used when the data should be handled and preserved byte by byte.
|
||||
dataSourceIntroCollection=Collection data sources contain multiple sub data sources. \nExamples are zip files or file system directories.
|
||||
storeIntroTitle=Connection Hub
|
||||
storeIntroDescription=Here you can manage all your local and remote shell connections in one place
|
||||
storeStreamDescription=Stream connections produce raw byte data\nthat can be used to construct data sources from.
|
||||
storeMachineDescription=To start off, here you can quickly detect available\nconnections automatically and choose which ones to add.
|
||||
detectConnections=Search for connections
|
||||
storeDatabaseDescription=Database connections allow you to connect to\na database server and interact with its contained data.
|
||||
storeDocumentation=In case you prefer a more structured approach to\nfamiliarizing yourself with XPipe, check out the documentation:
|
|
@ -1,2 +0,0 @@
|
|||
appearance=Aussehen
|
||||
uiOptions=UI Optionen
|
|
@ -1,35 +0,0 @@
|
|||
# Interface
|
||||
addCollection=Add collection
|
||||
newCollection=New collection
|
||||
delete=Delete
|
||||
rename=Rename
|
||||
properties=Properties
|
||||
usedDate=Used $DATE$
|
||||
cols=$COLS$ columns
|
||||
rowsCols=$ROWS$ rows / $COLS$ columns
|
||||
lines=$LINES$ lines
|
||||
objects=$OBJECTS$ objects
|
||||
bytes=$BYTES$ bytes
|
||||
entries=$ENTRIES$ entries
|
||||
unknownLength=Unknown length
|
||||
temporaryCollection=Temporary
|
||||
entrySettings=Settings
|
||||
pipe=Pipe
|
||||
openDir=Open Directory
|
||||
failedToLoad=Failed to Load
|
||||
stores=Stores
|
||||
# Dialogs
|
||||
confirmCollectionDeletionTitle=Confirm collection deletion
|
||||
confirmCollectionDeletionHeader=Do you really want to delete the collection $NAME$?
|
||||
confirmCollectionDeletionContent=This will delete all ($COUNT$) contained data sources as well.
|
||||
retrieveDataSource=Retrieve Data Source
|
||||
# Tooltips
|
||||
addCollectionFolder=Create new collection folder
|
||||
collectionOptions=Collection options
|
||||
addStreamDataSource=Add stream data source
|
||||
addDatabaseDataSource=Add database data source
|
||||
displayList=Display as list
|
||||
displayTiles=Display as tiles
|
||||
sortLastUsed=Sort by last used date
|
||||
sortAlphabetical=Sort alphabetical by name
|
||||
temporaryCollectionNote=All data sources inside the temporary collection are only stored while until the next system restart.
|
|
@ -1,25 +0,0 @@
|
|||
.step {
|
||||
-fx-padding: 0;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
-fx-padding: 1em 0 1em 0;
|
||||
}
|
||||
|
||||
.data-input-creation-step .jfx-tab-pane {
|
||||
-fx-spacing: 1em;
|
||||
-fx-padding: 1.5em;
|
||||
}
|
||||
|
||||
.data-input-creation-step .jfx-tab-pane {
|
||||
-fx-padding: 0.4em 0 0 0;
|
||||
}
|
||||
|
||||
.data-input-type {
|
||||
-fx-padding: 0 0 1.25em 0;
|
||||
}
|
||||
|
||||
.data-input-creation-step .store-local-file-chooser {
|
||||
-fx-padding: 1em 0 1em 0;
|
||||
-fx-spacing: 1em;
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
.multi-step-comp > .top .line {
|
||||
-fx-max-height: 3px;
|
||||
-fx-background-color: -color-accent-fg;
|
||||
}
|
||||
|
||||
.multi-step-comp > .entry {
|
||||
-fx-spacing: 0.2em;
|
||||
-fx-padding: 0.6em 0 1em 0;
|
||||
}
|
||||
|
||||
.multi-step-comp > .top {
|
||||
-fx-border-color: -color-neutral-emphasis;
|
||||
-fx-border-width: 0 0 0.1em 0;
|
||||
-fx-background-color: -color-neutral-muted;
|
||||
}
|
||||
|
||||
.multi-step-comp > .top .name {
|
||||
-fx-text-fill: -color-accent-fg;
|
||||
}
|
||||
|
||||
.multi-step-comp .entry:next .name {
|
||||
-fx-text-fill: -color-accent-fg;
|
||||
}
|
||||
|
||||
.multi-step-comp .buttons {
|
||||
-fx-border-color: -color-neutral-emphasis;
|
||||
-fx-border-width: 0.1em 0 0 0;
|
||||
-fx-padding: 1em;
|
||||
-fx-background-color: -color-neutral-muted;
|
||||
}
|
||||
|
||||
.multi-step-comp .circle {
|
||||
-fx-max-width: 17px;
|
||||
-fx-max-height: 17px;
|
||||
-fx-min-height: 17px;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-background-color: #073B4C;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-color:-color-accent-fg;
|
||||
-fx-border-radius: 4px;
|
||||
}
|
||||
|
||||
.multi-step-comp {
|
||||
-fx-background-color: -color-bg-default;
|
||||
}
|
||||
|
||||
.multi-step-comp .entry:completed .circle {
|
||||
-fx-background-color: #0B9F9B;
|
||||
}
|
||||
|
||||
.multi-step-comp .top .entry:completed .line {
|
||||
-fx-background-color: #0B9F9B;
|
||||
}
|
||||
|
||||
.multi-step-comp .entry:current .circle {
|
||||
-fx-background-color: #118AB2;
|
||||
}
|
||||
|
||||
.multi-step-comp .top .entry:current .line {
|
||||
-fx-background-color: #118AB2;
|
||||
}
|
||||
|
||||
.multi-step-comp .entry:next .circle {
|
||||
-fx-background-color: #0B566F;
|
||||
}
|
||||
|
||||
.multi-step-comp .top .entry:next .line {
|
||||
-fx-background-color: #0B566F;
|
||||
}
|
||||
|
||||
.multi-step-comp > .top .entry .number {
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.multi-step-comp > .top .entry:next .number {
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.multi-step-comp > .top {
|
||||
-fx-height: 4em;
|
||||
}
|
||||
|
||||
.multi-step-comp > .jfx-tab-pane .tab-header-area {
|
||||
-fx-pref-height: 0;
|
||||
}
|
||||
|
||||
.multi-step-comp > .jfx-tab-pane .tab-content-area {
|
||||
-fx-padding: 0;
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
.store-creator > .scroll-pane {
|
||||
-fx-padding: 0 10px 0 0;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
.tab-pane-comp .tab-header-area .jfx-rippler {
|
||||
-jfx-rippler-fill: #118AB210;
|
||||
}
|
||||
|
||||
.tab-pane-comp .tab-header-background {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.tab-pane-comp .tab-header-area .tab-selected-line {
|
||||
-fx-background-color: #073B4C43;
|
||||
-fx-pref-height: 1px;
|
||||
}
|
||||
|
||||
.tab-pane-comp .headers-region * {
|
||||
-fx-font-size: 1em;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
.jfx-tab-pane .tab-header-background { -fx-background-color: transparent; }
|
||||
|
||||
.jfx-tab-pane .tab-header-area .tab-selected-line {
|
||||
-fx-pref-height: 1px;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .headers-region * {
|
||||
-fx-font-size: 1em;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .tab-content-area {
|
||||
-fx-padding: 0.5em, 0, 0, 0;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package io.xpipe.beacon;
|
||||
|
||||
import io.xpipe.core.util.XPipeDaemonMode;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class BeaconDaemonController {
|
||||
|
||||
private static boolean alreadyStarted;
|
||||
|
||||
public static void start(XPipeDaemonMode mode) throws Exception {
|
||||
if (BeaconServer.isReachable()) {
|
||||
alreadyStarted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var custom = false;
|
||||
Process process;
|
||||
if ((process = BeaconServer.tryStartCustom()) != null) {
|
||||
custom = true;
|
||||
} else {
|
||||
var defaultBase = XPipeInstallation.getLocalDefaultInstallationBasePath();
|
||||
process = BeaconServer.start(defaultBase, mode);
|
||||
}
|
||||
|
||||
waitForStartup(process, custom);
|
||||
if (!BeaconServer.isReachable()) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop() throws Exception {
|
||||
if (alreadyStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BeaconServer.isReachable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var client = BeaconClient.establishConnection(BeaconClient.ApiClientInformation.builder()
|
||||
.version("?")
|
||||
.language("Java API Test")
|
||||
.build());
|
||||
if (!BeaconServer.tryStop(client)) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
waitForShutdown();
|
||||
}
|
||||
|
||||
private static void waitForStartup(Process process, boolean custom) throws IOException {
|
||||
for (int i = 0; i < 160; i++) {
|
||||
// Breaks when using nohup & disown
|
||||
// if (process != null && !custom && !process.isAlive()) {
|
||||
// throw new IOException("Daemon start failed");
|
||||
// }
|
||||
|
||||
if (process != null && custom && !process.isAlive() && process.exitValue() != 0) {
|
||||
throw new IOException("Custom launch command failed");
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
var s = BeaconClient.tryEstablishConnection(BeaconClient.ApiClientInformation.builder()
|
||||
.version("?")
|
||||
.language("Java")
|
||||
.build());
|
||||
if (s.isPresent()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IOException("Wait for daemon start up timed out");
|
||||
}
|
||||
|
||||
private static void waitForShutdown() {
|
||||
for (int i = 0; i < 40; i++) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
var r = BeaconServer.isReachable();
|
||||
if (!r) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* A store whose contents are stored in memory.
|
||||
*/
|
||||
@JsonTypeName("inMemory")
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InMemoryStore extends JacksonizedValue implements StreamDataStore {
|
||||
|
||||
private byte[] value;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value != null && value.length > 100 ? "<memory>" : (value != null ? new String(value) : "null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContentExclusivelyAccessible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInput() {
|
||||
return value != null ? new ByteArrayInputStream(value) : InputStream.nullInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutput() {
|
||||
return new ByteArrayOutputStream() {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
InMemoryStore.this.value = this.toByteArray();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package io.xpipe.core.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Random;
|
||||
|
||||
@JsonTypeName("default")
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DefaultSecretValue extends AesSecretValue {
|
||||
|
||||
public DefaultSecretValue(char[] secret) {
|
||||
super(secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretValue inPlace() {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected SecretKey getAESKey(int keysize) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
var salt = new byte[16];
|
||||
new Random(keysize).nextBytes(salt);
|
||||
KeySpec spec = new PBEKeySpec(new char[] {'X', 'P', 'E' << 1}, salt, 2048, keysize);
|
||||
return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
package io.xpipe.core.util;
|
||||
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class XPipeExecTempDirectory {
|
||||
|
||||
private static final Set<UUID> usedSystems = new CopyOnWriteArraySet<>();
|
||||
|
||||
public static String getSystemTempDirectory(ShellControl proc) throws Exception {
|
||||
return proc.getOsType().getTempDirectory(proc);
|
||||
}
|
||||
|
||||
public static synchronized String initExecTempDirectory(ShellControl proc) throws Exception {
|
||||
var d = proc.getShellDialect();
|
||||
|
||||
// We assume that this exists now as the systemid should have been created in this
|
||||
var xpipeHome = XPipeInstallation.getDataDir(proc);
|
||||
var targetTemp = FileNames.join(xpipeHome, "temp");
|
||||
|
||||
var systemTemp = proc.getOsType().getTempDirectory(proc);
|
||||
var legacyTemp = FileNames.join(systemTemp, "xpipe");
|
||||
var legacyExecTemp = FileNames.join(legacyTemp, "exec");
|
||||
|
||||
// Always delete legacy directory and do not care whether it partially fails
|
||||
d.deleteFileOrDirectory(proc, legacyExecTemp).executeAndCheck();
|
||||
|
||||
// Check permissions for home directory
|
||||
// If this is somehow messed up, we can still default back to the system directory
|
||||
if (!checkDirectoryPermissions(proc, xpipeHome)) {
|
||||
if (!d.directoryExists(proc, systemTemp).executeAndCheck() || !checkDirectoryPermissions(proc, systemTemp)) {
|
||||
throw new IOException("No permissions to create scripts in either %s or %s".formatted(systemTemp, targetTemp));
|
||||
}
|
||||
|
||||
targetTemp = systemTemp;
|
||||
} else {
|
||||
// Create and set all access permissions if not existent
|
||||
if (!d.directoryExists(proc, targetTemp).executeAndCheck()) {
|
||||
d.prepareUserTempDirectory(proc, targetTemp).execute();
|
||||
} else if (!usedSystems.contains(proc.getSystemId())) {
|
||||
// Try to clear directory and do not care about errors
|
||||
d.deleteFileOrDirectory(proc, targetTemp).executeAndCheck();
|
||||
d.prepareUserTempDirectory(proc, targetTemp).executeAndCheck();
|
||||
} else {
|
||||
// Still attempt to properly set permissions every time
|
||||
d.prepareUserTempDirectory(proc, targetTemp).executeAndCheck();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
usedSystems.add(proc.getSystemId());
|
||||
return targetTemp;
|
||||
}
|
||||
|
||||
private static boolean checkDirectoryPermissions(ShellControl proc, String dir) throws Exception {
|
||||
if (proc.getOsType().equals(OsType.WINDOWS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var d = proc.getShellDialect();
|
||||
return proc.executeSimpleBooleanCommand("test -r %s && test -w %s && test -x %s"
|
||||
.formatted(d.fileArgument(dir), d.fileArgument(dir), d.fileArgument(dir)));
|
||||
}
|
||||
|
||||
public static synchronized void occupyXPipeTempDirectory(ShellControl proc) {
|
||||
usedSystems.add(proc.getSystemId());
|
||||
}
|
||||
|
||||
public static String getSubDirectory(ShellControl proc, String... sub) throws Exception {
|
||||
var base = proc.getSubTemporaryDirectory();
|
||||
var arr = Stream.concat(Stream.of(base), Arrays.stream(sub))
|
||||
.toArray(String[]::new);
|
||||
var dir = FileNames.join(arr);
|
||||
|
||||
// We assume that this directory does not exist yet and therefore don't perform any checks
|
||||
proc.getShellDialect().prepareUserTempDirectory(proc, dir).execute();
|
||||
|
||||
return dir;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package io.xpipe.core.util;
|
||||
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.util.UUID;
|
||||
|
||||
public class XPipeSystemId {
|
||||
|
||||
private static UUID localId;
|
||||
|
||||
public static void init() {
|
||||
try {
|
||||
var file =
|
||||
XPipeInstallation.getDataDir().resolve("system_id");
|
||||
if (!Files.exists(file)) {
|
||||
Files.writeString(file, UUID.randomUUID().toString());
|
||||
}
|
||||
localId = UUID.fromString(Files.readString(file).trim());
|
||||
} catch (Exception ex) {
|
||||
localId = UUID.randomUUID();
|
||||
}
|
||||
}
|
||||
|
||||
public static UUID getLocal() {
|
||||
return localId;
|
||||
}
|
||||
|
||||
public static UUID getSystemId(ShellControl proc) throws Exception {
|
||||
var file = FileNames.join(XPipeInstallation.getDataDir(proc), "system_id");
|
||||
if (file == null) {
|
||||
return UUID.randomUUID();
|
||||
}
|
||||
|
||||
if (!proc.getShellDialect().createFileExistsCommand(proc, file).executeAndCheck()) {
|
||||
return writeRandom(proc, file);
|
||||
}
|
||||
|
||||
try {
|
||||
return UUID.fromString(proc.getShellDialect().getFileReadCommand(proc, file).readStdoutOrThrow()
|
||||
.trim());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Handle invalid UUID content case
|
||||
return writeRandom(proc, file);
|
||||
}
|
||||
}
|
||||
|
||||
private static UUID writeRandom(ShellControl proc, String file) throws Exception {
|
||||
proc.executeSimpleCommand(
|
||||
proc.getShellDialect().getMkdirsCommand(FileNames.getParent(file)),
|
||||
"Unable to access or create directory " + file);
|
||||
var id = UUID.randomUUID();
|
||||
proc.getShellDialect()
|
||||
.createTextFileWriteCommand(proc, id.toString(), file)
|
||||
.execute();
|
||||
return id;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package io.xpipe.core.test;
|
||||
|
||||
import io.xpipe.core.store.DataStoreId;
|
||||
import io.xpipe.core.source.DataSourceReference;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
public class DataSourceReferenceTest {
|
||||
|
||||
@Test
|
||||
public void parseValidParameters() {
|
||||
Assertions.assertEquals(DataSourceReference.parse(" ").getType(), DataSourceReference.Type.LATEST);
|
||||
Assertions.assertEquals(DataSourceReference.parse(null).getType(), DataSourceReference.Type.LATEST);
|
||||
|
||||
Assertions.assertEquals(DataSourceReference.parse("abc").getType(), DataSourceReference.Type.NAME);
|
||||
Assertions.assertEquals(DataSourceReference.parse(" abc_ d e").getName(), "abc_ d e");
|
||||
|
||||
Assertions.assertEquals(DataSourceReference.parse("ab:c").getId(), DataStoreId.fromString(" AB: C "));
|
||||
Assertions.assertEquals(DataSourceReference.parse(" ab:c ").getId(), DataStoreId.fromString("ab:c "));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"abc:", "ab::c", "::abc"})
|
||||
public void parseInvalidParameters(String arg) {
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||
DataSourceReference.parse(arg);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
package io.xpipe.core.test;
|
||||
|
||||
import io.xpipe.core.data.generic.GenericDataStreamParser;
|
||||
import io.xpipe.core.data.generic.GenericDataStreamWriter;
|
||||
import io.xpipe.core.data.generic.GenericDataStructureNodeReader;
|
||||
import io.xpipe.core.data.node.ArrayNode;
|
||||
import io.xpipe.core.data.node.DataStructureNode;
|
||||
import io.xpipe.core.data.node.TupleNode;
|
||||
import io.xpipe.core.data.node.ValueNode;
|
||||
import io.xpipe.core.data.typed.TypedDataStreamParser;
|
||||
import io.xpipe.core.data.typed.TypedDataStreamWriter;
|
||||
import io.xpipe.core.data.typed.TypedDataStructureNodeReader;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class DataStructureTest {
|
||||
|
||||
public static DataStructureNode createTestData() {
|
||||
var val = ValueNode.of("value");
|
||||
var flatArray = ArrayNode.of(List.of(ValueNode.of(1), ValueNode.of(2)));
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
var nestedArray = ArrayNode.of(List.of(flatArray, flatTuple));
|
||||
return TupleNode.builder()
|
||||
.add("key1", val)
|
||||
.add("key2", flatArray)
|
||||
.add("key3", flatTuple)
|
||||
.add("key4", nestedArray)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicOperations() {
|
||||
var obj = createTestData();
|
||||
Assertions.assertEquals(obj.size(), 4);
|
||||
Assertions.assertTrue(obj.isTuple());
|
||||
|
||||
var objCopy = createTestData();
|
||||
Assertions.assertEquals(obj, objCopy);
|
||||
|
||||
var key1 = obj.forKey("key1").asString();
|
||||
Assertions.assertEquals(key1, "value");
|
||||
|
||||
var key2 = obj.forKey("key2");
|
||||
Assertions.assertTrue(key2.isArray());
|
||||
Assertions.assertEquals(key2.at(0), ValueNode.of(1));
|
||||
Assertions.assertEquals(key2.at(0).asString(), "1");
|
||||
Assertions.assertEquals(key2.at(0).asInt(), 1);
|
||||
|
||||
var key3 = obj.forKey("key3");
|
||||
Assertions.assertTrue(key3.isTuple());
|
||||
Assertions.assertEquals(key3.forKey("key1"), ValueNode.of("value"));
|
||||
Assertions.assertEquals(key3.forKey("key1").asString(), "value");
|
||||
|
||||
var key4 = obj.forKey("key4");
|
||||
Assertions.assertTrue(key4.isArray());
|
||||
Assertions.assertEquals(key4.at(0), ArrayNode.of(ValueNode.of(1), ValueNode.of(2)));
|
||||
Assertions.assertEquals(key4.at(0).at(0).asInt(), 1);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(DataStructureTests.TypedDataset.class)
|
||||
public void testTypes(DataStructureTests.TypedDataset ds) throws IOException {
|
||||
for (var el : ds.nodes) {
|
||||
Assertions.assertTrue(ds.type.matches(el));
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(DataStructureTests.TypedDataset.class)
|
||||
public void testGenericIo(DataStructureTests.TypedDataset ds) throws IOException {
|
||||
for (var el : ds.nodes) {
|
||||
var dataOut = new ByteArrayOutputStream();
|
||||
GenericDataStreamWriter.writeStructure(dataOut, el);
|
||||
var data = dataOut.toByteArray();
|
||||
var reader = new GenericDataStructureNodeReader();
|
||||
GenericDataStreamParser.parse(new ByteArrayInputStream(data), reader);
|
||||
var readNode = reader.create();
|
||||
|
||||
Assertions.assertEquals(el, readNode);
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(DataStructureTests.TypedDataset.class)
|
||||
public void testTypedIo(DataStructureTests.TypedDataset ds) throws IOException {
|
||||
for (var node : ds.nodes) {
|
||||
var dataOut = new ByteArrayOutputStream();
|
||||
TypedDataStreamWriter.writeStructure(dataOut, node, ds.type);
|
||||
var data = dataOut.toByteArray();
|
||||
|
||||
var reader = TypedDataStructureNodeReader.of(ds.type);
|
||||
new TypedDataStreamParser(ds.type).parseStructure(new ByteArrayInputStream(data), reader);
|
||||
var readNode = reader.create();
|
||||
|
||||
Assertions.assertEquals(node, readNode);
|
||||
if (readNode.isTuple() || readNode.isArray()) {
|
||||
Assertions.assertEquals(readNode.size(), node.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,184 +0,0 @@
|
|||
package io.xpipe.core.test;
|
||||
|
||||
import io.xpipe.core.data.node.ArrayNode;
|
||||
import io.xpipe.core.data.node.DataStructureNode;
|
||||
import io.xpipe.core.data.node.TupleNode;
|
||||
import io.xpipe.core.data.node.ValueNode;
|
||||
import io.xpipe.core.data.type.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DataStructureTests {
|
||||
|
||||
private static DataStructureNode createTestData11() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
var flatArray = ArrayNode.of(List.of(ValueNode.of(1), ValueNode.of(2)));
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
var nestedArray = ArrayNode.of(List.of(flatArray, flatTuple));
|
||||
return TupleNode.builder()
|
||||
.add("key1", val)
|
||||
.add("key2", flatArray)
|
||||
.add("key3", flatTuple)
|
||||
.add("key4", nestedArray)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static DataStructureNode createTestData12() {
|
||||
var val = ValueNode.nullValue();
|
||||
var flatArray = ArrayNode.of();
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
var nestedArray = ArrayNode.of(List.of(flatArray, flatTuple));
|
||||
return TupleNode.builder()
|
||||
.add("key1", val)
|
||||
.add("key2", flatArray)
|
||||
.add("key3", flatTuple)
|
||||
.add("key4", nestedArray)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static DataType createTestDataType1() {
|
||||
return createTestData11().determineDataType();
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData21() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
var flatArray = ArrayNode.of(List.of(ValueNode.of(1), ValueNode.of(2)));
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
var nestedArray = ArrayNode.of(List.of(flatArray, flatTuple));
|
||||
var doubleNested = ArrayNode.of(val, flatArray, flatTuple, nestedArray);
|
||||
return doubleNested;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData22() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
return ArrayNode.of(val);
|
||||
}
|
||||
|
||||
public static DataType createTestDataType2() {
|
||||
return ArrayType.of(WildcardType.of());
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData31() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
var flatArray = ArrayNode.of(List.of(val, flatTuple));
|
||||
return flatArray;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData32() {
|
||||
var val = ValueNode.of("value2".getBytes(StandardCharsets.UTF_8));
|
||||
var flatTuple = TupleNode.builder()
|
||||
.add("key1", ValueNode.nullValue())
|
||||
.add("key2", ValueNode.nullValue())
|
||||
.build();
|
||||
var flatArray = ArrayNode.of(List.of(val, flatTuple));
|
||||
return flatArray;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData41() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
return val;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData42() {
|
||||
var val = ValueNode.nullValue();
|
||||
return val;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData51() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
var flatArray = ArrayNode.of(List.of(val, ValueNode.nullValue()));
|
||||
var array1 = ArrayNode.of(List.of(flatArray));
|
||||
var array2 = ArrayNode.of(List.of(array1, array1));
|
||||
return array2;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData52() {
|
||||
var val = ValueNode.of("value2".getBytes(StandardCharsets.UTF_8));
|
||||
var flatArray = ArrayNode.of(List.of(val));
|
||||
return flatArray;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData53() {
|
||||
var val = ValueNode.of("value2".getBytes(StandardCharsets.UTF_8));
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
var flatArray = ArrayNode.of(List.of(flatTuple, val));
|
||||
return flatArray;
|
||||
}
|
||||
|
||||
public static DataType createTestDataType5() {
|
||||
return ArrayType.of(WildcardType.of());
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData61() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
var array = ArrayNode.of(List.of(val, ValueNode.nullValue()));
|
||||
var tuple = TupleNode.builder().add(val).add("key2", array).build();
|
||||
return tuple;
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData62() {
|
||||
var val = ValueNode.of("value2".getBytes(StandardCharsets.UTF_8));
|
||||
var flatTuple = TupleNode.builder().add("key1", val).build();
|
||||
|
||||
var tuple = TupleNode.builder().add(flatTuple).add("key2", val).build();
|
||||
return tuple;
|
||||
}
|
||||
|
||||
public static DataType createTestDataType6() {
|
||||
var keys = new ArrayList<String>();
|
||||
keys.add(null);
|
||||
keys.add("key2");
|
||||
return TupleType.of(keys, List.of(WildcardType.of(), WildcardType.of()));
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData71() {
|
||||
return ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData72() {
|
||||
var val = ValueNode.of("value2".getBytes(StandardCharsets.UTF_8));
|
||||
return TupleNode.builder().add("key1", val).build();
|
||||
}
|
||||
|
||||
public static DataStructureNode createTestData73() {
|
||||
var val = ValueNode.of("value".getBytes(StandardCharsets.UTF_8));
|
||||
var array = ArrayNode.of(List.of(val, ValueNode.nullValue()));
|
||||
return array;
|
||||
}
|
||||
|
||||
public static DataType createTestDataType7() {
|
||||
return WildcardType.of();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static enum TypedDataset {
|
||||
|
||||
// Variety
|
||||
DATA_1(createTestDataType1(), List.of(createTestData11(), createTestData12())),
|
||||
|
||||
// Multiple nested arrays
|
||||
DATA_2(createTestDataType2(), List.of(createTestData21(), createTestData22())),
|
||||
|
||||
// Array with wildcard type
|
||||
DATA_3(createTestData31().determineDataType(), List.of(createTestData31(), createTestData32())),
|
||||
|
||||
// Simple values
|
||||
DATA_4(ValueType.of(), List.of(createTestData41(), createTestData42())),
|
||||
|
||||
// Array with wildcard type
|
||||
DATA_5(createTestDataType5(), List.of(createTestData51(), createTestData52(), createTestData53())),
|
||||
|
||||
// Tuple with wildcard type
|
||||
DATA_6(createTestDataType6(), List.of(createTestData61(), createTestData62())),
|
||||
|
||||
// Wildcard type
|
||||
DATA_7(createTestDataType7(), List.of(createTestData71(), createTestData72(), createTestData73()));
|
||||
|
||||
public DataType type;
|
||||
public List<DataStructureNode> nodes;
|
||||
}
|
||||
}
|
47
dist/changelogs/1.7.12_augmented.md
vendored
47
dist/changelogs/1.7.12_augmented.md
vendored
|
@ -1,47 +0,0 @@
|
|||
## New professional features
|
||||
|
||||
- Add ability to open files and directories in VSCode SSH remote environment in file browser
|
||||
- Added support for fully offline licenses. You can obtain them via email request
|
||||
in case you're running it on a system without internet connectivity or restricted proxy settings
|
||||
|
||||
## Changes
|
||||
|
||||
- Make current default shell also show up in shell environments to prevent confusion about missing bash environment
|
||||
- Improve error messages when an additional password was requested by the connection
|
||||
when none was provided instead of just showing permission denied
|
||||
- Make SSH connection starting from a WSL environment use the native Windows key helper for FIDO2 keys
|
||||
- Rework insights button for connection creation across the board
|
||||
|
||||
## Additions
|
||||
|
||||
- Add warning message if git vault URL was an HTTP URL and you are trying to use an SSH identity
|
||||
- Add ability to clone existing connections to make the process of adding similar connections easier
|
||||
- Add ability to debug local background shell in developer options
|
||||
- Add notice when a professional feature is available in preview mode
|
||||
- Add some more OS logos
|
||||
- Add check to verify whether font loading with fontconfig works on Linux on startup
|
||||
- Add more extensive note on first startup for potential issues when Malwarebytes, McAfee, or Bitdefender are installed
|
||||
|
||||
## Fixes
|
||||
|
||||
- Fix application not starting on Asahi Linux due to executable page size issue
|
||||
- Fix file existence check for SSH key files reporting wrong results on Windows in directory links/junctions
|
||||
- Fix k8s integration not working when user did not have permission to list nodes
|
||||
- Fix rare error when switching to tray operation mode on Linux
|
||||
- Fix connection state not being preserved when being added the first time
|
||||
- Fix application failing to start up if OS reported invalid screen size bounds
|
||||
- Fix VMware VM not being able to be parsed if configuration file did not specify an encoding or name
|
||||
- Fix startup failing when installation was located on a ramdisk
|
||||
- Fix some miscellaneous cache data being stored in the user home directory
|
||||
- Fix error handling when jump host chain formed a loop
|
||||
- Fix PowerShell remote sessions being blocked by execution policy
|
||||
- Fix race condition when locking user data directory
|
||||
- Fix some CLI commands not starting daemon correctly if it is not already running
|
||||
- Fix text field when showing askpass window not being focused automatically
|
||||
- Fix combobox selections not working well with keyboard-only workflows
|
||||
- Fix many possible small NullPointerExceptions
|
||||
|
||||
## Preview pro features
|
||||
|
||||
For anyone interested in giving any new professional features a try without having to commit to buying a full license,
|
||||
there is now a special preview mode available: Simply enter the license key `D18D1C9F-D3CB-49CA-A909-FF385DECD948` and get full access to newly released professional features for two weeks after their initial release date. In fact, you can try it out right now to get access to the new vscode file browser integration.
|
38
dist/changelogs/1.7.15_augmented.md
vendored
38
dist/changelogs/1.7.15_augmented.md
vendored
|
@ -1,38 +0,0 @@
|
|||
## Changes
|
||||
|
||||
- Add support to create customized SSH connections using arbitrary options.
|
||||
This can be done using the SSH config format but without having to create an actual file.
|
||||
- Unify all SSH connection types to support the same functionality.
|
||||
I.e. they all now support host key and identity file fixes plus can be used with SSH tunnels.
|
||||
- Make it possible to specify any identity to be used for SSH config connections
|
||||
- Properly detect when an active connection has unexpectedly reset during a file browser session.
|
||||
It will now be automatically restarted when any action is performed and fails.
|
||||
- Rework connection creation menu layout to give a better overview
|
||||
- Make the connection timeout value in the settings properly apply to ssh connections as well.
|
||||
This should help with SSH connections that take a long time to connect.
|
||||
- Include pre-rasterized images for various sizes to reduce the render load at runtime
|
||||
- Implement various performance improvements
|
||||
- Rework some UI elements to better work with keyboard navigation and screen readers
|
||||
- Add unsupported shell notice when restricted bash is detected
|
||||
- The daemon now properly reports any startup failure causes when started from the CLI via `xpipe open`
|
||||
- Regularly clean logs directory to free up older log files
|
||||
- Improve file browser handling in smaller window sizes
|
||||
- Add support for WezTerm and Windows Terminal Preview
|
||||
|
||||
## Fixes
|
||||
|
||||
- Fix application windows on Linux not initializing with the correct size
|
||||
- Fix connections to pfSense systems not working (This time properly)
|
||||
- Fix NullPointerException when a Linux system did not provide any release name
|
||||
- Fix startup errors when operating system reported invalid window sizes
|
||||
- Fix various Exceptions caused by race conditions
|
||||
|
||||
## Error reporter
|
||||
|
||||
It seems like the current built-in error reporter service is broken right now, so I might not receive your written user feedback from it.
|
||||
If you want to report any issues, please use another way until that is fixed.
|
||||
|
||||
## Future updates
|
||||
|
||||
The next upcoming update will probably be 1.8 with many new features and changes across the board.
|
||||
The first test versions will be announced on Discord and Slack if you are interested.
|
34
dist/changelogs/1.7.16_augmented.md
vendored
34
dist/changelogs/1.7.16_augmented.md
vendored
|
@ -1,34 +0,0 @@
|
|||
## SSH Timeouts and connection time
|
||||
|
||||
Over time, there have always been a few complaints about SSH connection timeout errors and slow SSH connection startup. These especially popped up in the latest release even though no obvious code was changed.
|
||||
|
||||
As it turns out, increasing the value for `ConnectTimeout` in SSH does not actually only change the timeout after which an error is thrown, it is also used by some servers as a guideline for their response time. E.g. if you specify a 10s timeout, some servers will always take 10s to respond. This is of course not mentioned in any of the spec but is more of an implementation choice.
|
||||
|
||||
In the latest release this caused more errors as the timeout was set higher. It should also have affected many SSH connections basically since the release of XPipe. I don't know how many people have been affected by this, it heavily depends on which ssh server and configuration your server runs. It happens for example on my proxmox instances and AWS EC2 instances. If your connections now start up much faster than before, then you were probably affected by it.
|
||||
|
||||
This release should fix all of these issues simply by not specifying a connect timeout at all. Great work there.
|
||||
|
||||
If you are using `ConnectTimeout` in your SSH configs, just remove it as it makes everything slower without having the effect of a timeout.
|
||||
|
||||
I would like to exchange a few words with whoever thought: *A newly connected SSH client specified a 10s connect timeout? That means our SSH server can sit around idle for 9 seconds. That is a great idea.*
|
||||
|
||||
## Fixes
|
||||
|
||||
- Fix annoying log directory errors that occurred on first startup
|
||||
- Fix SSH connections failing on Windows systems where the username contained non-ASCII characters due to an OpenSSH client bug by working around it
|
||||
- Fix SSH connection failing when another RemoteCommand was set in a config file
|
||||
- Fix child connection validity not updating when parent is changed from invalid to valid
|
||||
- Fix some applications launched on Windows, e.g. some terminals and editors, starting in minimized mode
|
||||
- Fix SSH config importer not handling file wildcards correctly when they also contained a file extension
|
||||
- Fix actions that shut down XPipe, e.g. automatic updates and debug mode, not correctly executing if it exited too fast
|
||||
- Fix error about nonexistent logs directory on first startup
|
||||
- Fix possible NullPointers when checking whether current SSH session has died
|
||||
|
||||
## Error reporter
|
||||
|
||||
It seems like the current built-in error reporter service is broken right now, so I might not receive your written user feedback from it.
|
||||
If you want to report any issues, please use another way until that is fixed.
|
||||
|
||||
## Previous changes in 1.7.15
|
||||
|
||||
- [1.7.15 changelog](https://github.com/xpipe-io/xpipe/releases/tag/1.7.15)
|
22
dist/licenses/checkerqual.license
vendored
22
dist/licenses/checkerqual.license
vendored
|
@ -1,22 +0,0 @@
|
|||
Checker Framework qualifiers
|
||||
Copyright 2004-present by the Checker Framework developers
|
||||
|
||||
MIT License:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
4
dist/licenses/checkerqual.properties
vendored
4
dist/licenses/checkerqual.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=checker-qual
|
||||
version=3.5.0
|
||||
license=MIT License
|
||||
link=https://github.com/typetools/checker-framework/blob/master/checker-qual/
|
177
dist/licenses/commons-lang.license
vendored
177
dist/licenses/commons-lang.license
vendored
|
@ -1,177 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
4
dist/licenses/commons-lang.properties
vendored
4
dist/licenses/commons-lang.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=Commons Lang
|
||||
version=3.12.0
|
||||
license=Apache License 2.0
|
||||
link=https://commons.apache.org/proper/commons-lang/
|
201
dist/licenses/formsfx.license
vendored
201
dist/licenses/formsfx.license
vendored
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
4
dist/licenses/formsfx.properties
vendored
4
dist/licenses/formsfx.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=FormsFX
|
||||
version=11.5.0
|
||||
license=Apache License 2.0
|
||||
link=https://github.com/dlsc-software-consulting-gmbh/FormsFX
|
177
dist/licenses/jfa.license
vendored
177
dist/licenses/jfa.license
vendored
|
@ -1,177 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
4
dist/licenses/jfa.properties
vendored
4
dist/licenses/jfa.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=Java Foundation Access
|
||||
version=1.2.0
|
||||
license=Apache License 2.0
|
||||
link=https://github.com/0x4a616e/jfa
|
18
dist/licenses/jfoenix.license
vendored
18
dist/licenses/jfoenix.license
vendored
|
@ -1,18 +0,0 @@
|
|||
Copyright (c) 2016 JFoenix
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
4
dist/licenses/jfoenix.properties
vendored
4
dist/licenses/jfoenix.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=JFoenix
|
||||
version=9.0.10
|
||||
license=MIT License
|
||||
link=https://github.com/sshahine/JFoenix
|
177
dist/licenses/jsystemthemedetector.license
vendored
177
dist/licenses/jsystemthemedetector.license
vendored
|
@ -1,177 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -1,4 +0,0 @@
|
|||
name=jSystemThemeDetector
|
||||
version=3.8
|
||||
license=Apache License 2.0
|
||||
link=https://github.com/Dansoftowner/jSystemThemeDetector
|
347
dist/licenses/openjdk.license
vendored
347
dist/licenses/openjdk.license
vendored
|
@ -1,347 +0,0 @@
|
|||
The GNU General Public License (GPL)
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public License is intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users. This General Public License applies to
|
||||
most of the Free Software Foundation's software and to any other program whose
|
||||
authors commit to using it. (Some other Free Software Foundation software is
|
||||
covered by the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom to
|
||||
distribute copies of free software (and charge for this service if you wish),
|
||||
that you receive source code or can get it if you want it, that you can change
|
||||
the software or use pieces of it in new free programs; and that you know you
|
||||
can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to deny
|
||||
you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of the
|
||||
software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that you have. You must
|
||||
make sure that they, too, receive or can get the source code. And you must
|
||||
show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If the
|
||||
software is modified by someone else and passed on, we want its recipients to
|
||||
know that what they have is not the original, so that any problems introduced
|
||||
by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that redistributors of a free program will
|
||||
individually obtain patent licenses, in effect making the program proprietary.
|
||||
To prevent this, we have made it clear that any patent must be licensed for
|
||||
everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the terms of
|
||||
this General Public License. The "Program", below, refers to any such program
|
||||
or work, and a "work based on the Program" means either the Program or any
|
||||
derivative work under copyright law: that is to say, a work containing the
|
||||
Program or a portion of it, either verbatim or with modifications and/or
|
||||
translated into another language. (Hereinafter, translation is included
|
||||
without limitation in the term "modification".) Each licensee is addressed as
|
||||
"you".
|
||||
|
||||
Activities other than copying, distribution and modification are not covered by
|
||||
this License; they are outside its scope. The act of running the Program is
|
||||
not restricted, and the output from the Program is covered only if its contents
|
||||
constitute a work based on the Program (independent of having been made by
|
||||
running the Program). Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source code as
|
||||
you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||
and to the absence of any warranty; and give any other recipients of the
|
||||
Program a copy of this License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you may
|
||||
at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of it, thus
|
||||
forming a work based on the Program, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all of
|
||||
these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in whole or
|
||||
in part contains or is derived from the Program or any part thereof, to be
|
||||
licensed as a whole at no charge to all third parties under the terms of
|
||||
this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively when run,
|
||||
you must cause it, when started running for such interactive use in the
|
||||
most ordinary way, to print or display an announcement including an
|
||||
appropriate copyright notice and a notice that there is no warranty (or
|
||||
else, saying that you provide a warranty) and that users may redistribute
|
||||
the program under these conditions, and telling the user how to view a copy
|
||||
of this License. (Exception: if the Program itself is interactive but does
|
||||
not normally print such an announcement, your work based on the Program is
|
||||
not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License, and
|
||||
its terms, do not apply to those sections when you distribute them as separate
|
||||
works. But when you distribute the same sections as part of a whole which is a
|
||||
work based on the Program, the distribution of the whole must be on the terms
|
||||
of this License, whose permissions for other licensees extend to the entire
|
||||
whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise the
|
||||
right to control the distribution of derivative or collective works based on
|
||||
the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program with the
|
||||
Program (or with a work based on the Program) on a volume of a storage or
|
||||
distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it, under
|
||||
Section 2) in object code or executable form under the terms of Sections 1 and
|
||||
2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2 above
|
||||
on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three years, to
|
||||
give any third party, for a charge no more than your cost of physically
|
||||
performing source distribution, a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of Sections 1
|
||||
and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer to
|
||||
distribute corresponding source code. (This alternative is allowed only
|
||||
for noncommercial distribution and only if you received the program in
|
||||
object code or executable form with such an offer, in accord with
|
||||
Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable work, complete source code means all
|
||||
the source code for all modules it contains, plus any associated interface
|
||||
definition files, plus the scripts used to control compilation and installation
|
||||
of the executable. However, as a special exception, the source code
|
||||
distributed need not include anything that is normally distributed (in either
|
||||
source or binary form) with the major components (compiler, kernel, and so on)
|
||||
of the operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the source
|
||||
code from the same place counts as distribution of the source code, even though
|
||||
third parties are not compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program except as
|
||||
expressly provided under this License. Any attempt otherwise to copy, modify,
|
||||
sublicense or distribute the Program is void, and will automatically terminate
|
||||
your rights under this License. However, parties who have received copies, or
|
||||
rights, from you under this License will not have their licenses terminated so
|
||||
long as such parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not signed it.
|
||||
However, nothing else grants you permission to modify or distribute the Program
|
||||
or its derivative works. These actions are prohibited by law if you do not
|
||||
accept this License. Therefore, by modifying or distributing the Program (or
|
||||
any work based on the Program), you indicate your acceptance of this License to
|
||||
do so, and all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the Program),
|
||||
the recipient automatically receives a license from the original licensor to
|
||||
copy, distribute or modify the Program subject to these terms and conditions.
|
||||
You may not impose any further restrictions on the recipients' exercise of the
|
||||
rights granted herein. You are not responsible for enforcing compliance by
|
||||
third parties to this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues), conditions
|
||||
are imposed on you (whether by court order, agreement or otherwise) that
|
||||
contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot distribute so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not distribute the Program at all.
|
||||
For example, if a patent license would not permit royalty-free redistribution
|
||||
of the Program by all those who receive copies directly or indirectly through
|
||||
you, then the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system, which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose that
|
||||
choiceElement.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original
|
||||
copyright holder who places the Program under this License may add an explicit
|
||||
geographical distribution limitation excluding those countries, so that
|
||||
distribution is permitted only in or among countries not thus excluded. In
|
||||
such case, this License incorporates the limitation as if written in the body
|
||||
of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions of the
|
||||
General Public License from time to time. Such new versions will be similar in
|
||||
spirit to the present version, but may differ in detail to address new problems
|
||||
or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any later
|
||||
version", you have the option of following the terms and conditions either of
|
||||
that version or of any later version published by the Free Software Foundation.
|
||||
If the Program does not specify a version number of this License, you may
|
||||
choose any version ever published by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free programs
|
||||
whose distribution conditions are different, write to the author to ask for
|
||||
permission. For software which is copyrighted by the Free Software Foundation,
|
||||
write to the Free Software Foundation; we sometimes make exceptions for this.
|
||||
Our decision will be guided by the two goals of preserving the free status of
|
||||
all derivatives of our free software and of promoting the sharing and reuse of
|
||||
software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
|
||||
PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
|
||||
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
|
||||
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
|
||||
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
|
||||
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
|
||||
OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest possible
|
||||
use to the public, the best way to achieve this is to make it free software
|
||||
which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach
|
||||
them to the start of each source file to most effectively convey the exclusion
|
||||
of warranty; and each file should have at least the "copyright" line and a
|
||||
pointer to where the full notice is found.
|
||||
|
||||
One line to give the program's name and a brief idea of what it does.
|
||||
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this when it
|
||||
starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
|
||||
with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
|
||||
software, and you are welcome to redistribute it under certain conditions;
|
||||
type 'show c' for details.
|
||||
|
||||
The hypothetical commands 'show w' and 'show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may be
|
||||
called something other than 'show w' and 'show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
|
||||
is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
'Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
signature of Ty Coon, 1 April 1989
|
||||
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General Public
|
||||
License instead of this License.
|
||||
|
||||
|
||||
"CLASSPATH" EXCEPTION TO THE GPL
|
||||
|
||||
Certain source files distributed by Oracle America and/or its affiliates are
|
||||
subject to the following clarification and special exception to the GPL, but
|
||||
only where Oracle has expressly included in the particular source file's header
|
||||
the words "Oracle designates this particular file as subject to the "Classpath"
|
||||
exception as provided by Oracle in the LICENSE file that accompanied this code."
|
||||
|
||||
Linking this library statically or dynamically with other modules is making
|
||||
a combined work based on this library. Thus, the terms and conditions of
|
||||
the GNU General Public License cover the whole combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent modules,
|
||||
and to copy and distribute the resulting executable under terms of your
|
||||
choiceElement, provided that you also meet, for each linked independent module,
|
||||
the terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library. If
|
||||
you modify this library, you may extend this exception to your version of
|
||||
the library, but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version.
|
4
dist/licenses/openjdk.properties
vendored
4
dist/licenses/openjdk.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=OpenJDK
|
||||
version=21.0.1
|
||||
license=GPL2 with the Classpath Exception
|
||||
link=https://jdk.java.net/21/
|
21
dist/licenses/oshi.license
vendored
21
dist/licenses/oshi.license
vendored
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2010-2023 The OSHI Project Contributors: https://github.com/oshi/oshi/graphs/contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
4
dist/licenses/oshi.properties
vendored
4
dist/licenses/oshi.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=oshi
|
||||
version=6.4.2
|
||||
license=MIT License
|
||||
link=https://github.com/oshi/oshi
|
201
dist/licenses/preferencesfx.license
vendored
201
dist/licenses/preferencesfx.license
vendored
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
4
dist/licenses/preferencesfx.properties
vendored
4
dist/licenses/preferencesfx.properties
vendored
|
@ -1,4 +0,0 @@
|
|||
name=PreferencesFX
|
||||
version=11.9.0
|
||||
license=Apache License 2.0
|
||||
link=https://github.com/dlsc-software-consulting-gmbh/PreferencesFX
|
|
@ -1,39 +0,0 @@
|
|||
package io.xpipe.ext.base;
|
||||
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.core.dialog.Dialog;
|
||||
import io.xpipe.core.dialog.QueryConverter;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.InMemoryStore;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
public class InMemoryStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public Dialog dialogForStore(DataStore store) {
|
||||
InMemoryStore s = store.asNeeded();
|
||||
var userQ = Dialog.query(
|
||||
"Value", true, true, false, new String(s.getValue(), StandardCharsets.UTF_8), QueryConverter.STRING);
|
||||
return userQ.evaluateTo(() -> {
|
||||
byte[] bytes = ((String) userQ.getResult()).getBytes(StandardCharsets.UTF_8);
|
||||
return new InMemoryStore(bytes);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
return new InMemoryStore(new byte[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleNames() {
|
||||
return List.of("inMemory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getStoreClasses() {
|
||||
return List.of(InMemoryStore.class);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
module io.xpipe.ext.base.test {
|
||||
requires io.xpipe.ext.base;
|
||||
requires org.junit.jupiter.api;
|
||||
requires org.junit.jupiter.params;
|
||||
requires io.xpipe.core;
|
||||
requires io.xpipe.api;
|
||||
requires io.xpipe.app;
|
||||
|
||||
exports test;
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
package test;
|
||||
|
||||
import io.xpipe.api.DataSource;
|
||||
import io.xpipe.app.test.DaemonExtensionTest;
|
||||
import io.xpipe.core.charsetter.NewLine;
|
||||
import io.xpipe.core.charsetter.StreamCharset;
|
||||
import io.xpipe.app.util.FileReference;
|
||||
import io.xpipe.core.impl.TextSource;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
public class TextFileTest extends DaemonExtensionTest {
|
||||
|
||||
static Path utf8File =
|
||||
Path.of("ext/base/src/test/resources/utf8-bom-lf.txt").toAbsolutePath();
|
||||
static Path utf16File =
|
||||
Path.of("ext/base/src/test/resources/utf16-crlf.txt").toAbsolutePath();
|
||||
static Path appendReferenceFile =
|
||||
Path.of("ext/base/src/test/resources/append-reference.txt").toAbsolutePath();
|
||||
static Path appendOutputFile;
|
||||
static Path writeReferenceFile =
|
||||
Path.of("ext/base/src/test/resources/write-reference.txt").toAbsolutePath();
|
||||
static Path writeOutputFile;
|
||||
|
||||
static DataSource utf8;
|
||||
static DataSource utf16;
|
||||
static DataSource appendReference;
|
||||
static DataSource writeReference;
|
||||
static DataSource appendOutput;
|
||||
static DataSource writeOutput;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupStorage() throws Exception {
|
||||
utf8 = getSource("text", "utf8-bom-lf.txt");
|
||||
utf16 = DataSource.create(null, "text", FileReference.local(utf16File));
|
||||
appendReference = DataSource.create(null, "text", FileReference.local(appendReferenceFile));
|
||||
writeReference = DataSource.create(null, "text", FileReference.local(writeReferenceFile));
|
||||
|
||||
appendOutputFile = Files.createTempFile(null, null);
|
||||
appendOutput = DataSource.create(
|
||||
null,
|
||||
TextSource.builder()
|
||||
.store(FileReference.local(appendOutputFile))
|
||||
.charset(StreamCharset.get("windows-1252"))
|
||||
.newLine(NewLine.LF)
|
||||
.build());
|
||||
|
||||
writeOutputFile = Files.createTempFile(null, null);
|
||||
writeOutput = DataSource.create(
|
||||
null,
|
||||
TextSource.builder()
|
||||
.store(FileReference.local(writeOutputFile))
|
||||
.charset(StreamCharset.UTF16_LE_BOM)
|
||||
.newLine(NewLine.CRLF)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetection() throws IOException {
|
||||
TextSource first = (TextSource) utf8.getInternalSource();
|
||||
Assertions.assertEquals(StreamCharset.UTF8_BOM, first.getCharset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() throws IOException {
|
||||
var first = utf8.asText();
|
||||
var firstText = first.readAll();
|
||||
var firstTextLines = first.readLines(5);
|
||||
|
||||
Assertions.assertEquals(firstText, "hello\nworld");
|
||||
Assertions.assertEquals(firstTextLines, List.of("hello", "world"));
|
||||
|
||||
var second = utf16.asText();
|
||||
var secondText = second.readAll();
|
||||
var secondTextLines = second.readLines(5);
|
||||
|
||||
Assertions.assertEquals(secondText, "how\nis\nit\ngoing");
|
||||
Assertions.assertEquals(secondTextLines, List.of("how", "is", "it", "going"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrite() throws IOException {
|
||||
var empty = Files.createTempFile(null, null);
|
||||
var emptySource = DataSource.create(
|
||||
null,
|
||||
TextSource.builder()
|
||||
.store(FileReference.local(empty))
|
||||
.charset(StreamCharset.UTF32_BE)
|
||||
.newLine(NewLine.CRLF)
|
||||
.build());
|
||||
emptySource.asText().forwardTo(writeOutput);
|
||||
|
||||
var first = utf8.asText();
|
||||
first.forwardTo(writeOutput);
|
||||
var second = utf16.asText();
|
||||
second.forwardTo(writeOutput);
|
||||
|
||||
var text = writeOutput.asText().readAll();
|
||||
var referenceText = writeReference.asText().readAll();
|
||||
Assertions.assertEquals(referenceText, text);
|
||||
|
||||
var bytes = Files.readAllBytes(writeOutputFile);
|
||||
var referenceBytes = Files.readAllBytes(writeReferenceFile);
|
||||
Assertions.assertArrayEquals(bytes, referenceBytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppend() throws IOException {
|
||||
var first = utf8.asText();
|
||||
first.appendTo(appendOutput);
|
||||
var second = utf16.asText();
|
||||
second.appendTo(appendOutput);
|
||||
|
||||
var text = appendOutput.asText().readAll();
|
||||
var referenceText = appendReference.asText().readAll();
|
||||
Assertions.assertEquals(referenceText, text);
|
||||
|
||||
var bytes = Files.readAllBytes(appendOutputFile);
|
||||
var referenceBytes = Files.readAllBytes(appendReferenceFile);
|
||||
Assertions.assertArrayEquals(bytes, referenceBytes);
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
hello
|
||||
world
|
||||
how
|
||||
is
|
||||
it
|
||||
going
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
hello
|
||||
world
|
Binary file not shown.
|
@ -1,43 +0,0 @@
|
|||
configurations {
|
||||
dep
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dep files("${project.layout.buildDirectory.get()}/generated-modules/commons-lang3-3.12.0.jar")
|
||||
dep files("${project.layout.buildDirectory.get()}/generated-modules/commons-io-2.11.0.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact 'org.apache.commons:commons-lang3:3.12.0'
|
||||
moduleInfoSource = '''
|
||||
module org.apache.commons.lang3 {
|
||||
exports org.apache.commons.lang3;
|
||||
exports org.apache.commons.lang3.function;
|
||||
exports org.apache.commons.lang3.arch;
|
||||
exports org.apache.commons.lang3.reflect;
|
||||
exports org.apache.commons.lang3.builder;
|
||||
exports org.apache.commons.lang3.text;
|
||||
exports org.apache.commons.lang3.tuple;
|
||||
exports org.apache.commons.lang3.math;
|
||||
}
|
||||
'''
|
||||
}
|
||||
module {
|
||||
artifact 'commons-io:commons-io:2.11.0'
|
||||
moduleInfoSource = '''
|
||||
module org.apache.commons.io {
|
||||
exports org.apache.commons.io;
|
||||
exports org.apache.commons.io.file;
|
||||
exports org.apache.commons.io.input;
|
||||
exports org.apache.commons.io.filefilter;
|
||||
exports org.apache.commons.io.output;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
|
||||
|
||||
apply from: "$buildscript.sourceFile/../junit.gradle"
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':api')
|
||||
testImplementation project(':core')
|
||||
testImplementation project(':app')
|
||||
|
||||
testImplementation "org.openjfx:javafx-base:${javafxVersion}:win"
|
||||
testImplementation "org.openjfx:javafx-controls:${javafxVersion}:win"
|
||||
testImplementation "org.openjfx:javafx-graphics:${javafxVersion}:win"
|
||||
}
|
||||
|
||||
def attachDebugger = System.getProperty('idea.debugger.dispatch.addr') != null
|
||||
def daemonCommand = attachDebugger ? ':app:runAttachedDebugger' : ':app:run'
|
||||
|
||||
test {
|
||||
workingDir = rootDir
|
||||
|
||||
jvmArgs += ["-Xmx2g"]
|
||||
|
||||
// Daemon properties
|
||||
systemProperty "io.xpipe.beacon.daemonArgs",
|
||||
" -Dio.xpipe.beacon.port=21725" +
|
||||
" -Dio.xpipe.app.mode=tray" +
|
||||
" -Dio.xpipe.app.dataDir=$projectDir/local/" +
|
||||
" -Dio.xpipe.storage.persist=false" +
|
||||
" -Dio.xpipe.app.writeSysOut=true" +
|
||||
" -Dio.xpipe.app.writeLogs=false" +
|
||||
" -Dio.xpipe.beacon.printMessages=false" +
|
||||
" -Dio.xpipe.app.logLevel=trace"
|
||||
|
||||
// Use cmd window for tests
|
||||
if (!rootProject.ci && DefaultNativePlatform.currentOperatingSystem.isWindows()) {
|
||||
systemProperty "io.xpipe.beacon.customDaemonCommand",
|
||||
"cmd.exe /c start \"\"XPipe Debug\"\" /i \"$rootDir\\gradlew.bat\" --console=plain $daemonCommand"
|
||||
}
|
||||
|
||||
|
||||
// Client properties
|
||||
// systemProperty 'io.xpipe.beacon.printMessages', "true"
|
||||
systemProperty 'io.xpipe.beacon.printDaemonOutput', "false"
|
||||
systemProperty "io.xpipe.beacon.port", "21725"
|
||||
systemProperty "io.xpipe.beacon.launchDebugDaemon", "true"
|
||||
systemProperty "io.xpipe.beacon.attachDebuggerToDaemon", "$daemonCommand"
|
||||
}
|
||||
|
||||
task productionTest(type: Test) {
|
||||
classpath = sourceSets.test.runtimeClasspath
|
||||
useJUnitPlatform()
|
||||
workingDir = rootDir
|
||||
|
||||
jvmArgs += ["-Xmx2g"]
|
||||
|
||||
// Daemon properties
|
||||
systemProperty "io.xpipe.beacon.daemonArgs",
|
||||
" -Dio.xpipe.beacon.port=21725" +
|
||||
" -Dio.xpipe.app.dataDir=$projectDir/local/" +
|
||||
" -Dio.xpipe.storage.persist=false" +
|
||||
" -Dio.xpipe.app.writeSysOut=true" +
|
||||
" -Dio.xpipe.app.writeLogs=false" +
|
||||
" -Dio.xpipe.beacon.printMessages=false" +
|
||||
" -Dio.xpipe.app.logLevel=trace"
|
||||
|
||||
// Client properties
|
||||
systemProperty 'io.xpipe.beacon.printMessages', "true"
|
||||
systemProperty 'io.xpipe.beacon.printDaemonOutput', "true"
|
||||
systemProperty "io.xpipe.beacon.port", "21725"
|
||||
}
|
Binary file not shown.
|
@ -1,31 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/markdowngenerator-1.3.1.1.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact (name: "markdowngenerator-1.3.1.1")
|
||||
moduleInfoSource = '''
|
||||
module net.steppschuh.markdowngenerator {
|
||||
exports net.steppschuh.markdowngenerator;
|
||||
exports net.steppschuh.markdowngenerator.image;
|
||||
exports net.steppschuh.markdowngenerator.link;
|
||||
exports net.steppschuh.markdowngenerator.list;
|
||||
exports net.steppschuh.markdowngenerator.progress;
|
||||
exports net.steppschuh.markdowngenerator.rule;
|
||||
exports net.steppschuh.markdowngenerator.table;
|
||||
exports net.steppschuh.markdowngenerator.text;
|
||||
exports net.steppschuh.markdowngenerator.text.code;
|
||||
exports net.steppschuh.markdowngenerator.text.emphasis;
|
||||
exports net.steppschuh.markdowngenerator.text.heading;
|
||||
exports net.steppschuh.markdowngenerator.text.quote;
|
||||
exports net.steppschuh.markdowngenerator.util;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
compileJava {
|
||||
options.compilerArgs += ["-Aproject=${project.name}"]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'info.picocli:picocli:4.7.0'
|
||||
annotationProcessor 'info.picocli:picocli-codegen:4.7.0'
|
||||
testImplementation 'info.picocli:picocli:4.7.0'
|
||||
testAnnotationProcessor 'info.picocli:picocli-codegen:4.7.0'
|
||||
}
|
Binary file not shown.
|
@ -1,22 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/prettytime-5.0.2.Final.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact 'org.ocpsoft.prettytime:prettytime:5.0.2.Final'
|
||||
moduleInfoSource = '''
|
||||
module org.ocpsoft.prettytime {
|
||||
exports org.ocpsoft.prettytime;
|
||||
exports org.ocpsoft.prettytime.format;
|
||||
exports org.ocpsoft.prettytime.i18n;
|
||||
exports org.ocpsoft.prettytime.units;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
dependencies {
|
||||
implementation files("${project.layout.buildDirectory.get()}/generated-modules/versioncompare-1.5.0.jar")
|
||||
}
|
||||
|
||||
addDependenciesModuleInfo {
|
||||
overwriteExistingFiles = true
|
||||
jdepsExtraArgs = ['-q']
|
||||
outputDirectory = file("${project.layout.buildDirectory.get()}/generated-modules")
|
||||
modules {
|
||||
module {
|
||||
artifact "io.github.g00fy2:versioncompare:1.5.0"
|
||||
moduleInfoSource = '''
|
||||
module versioncompare {
|
||||
exports io.github.g00fy2.versioncompare;
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue