Remove leftover merge files

This commit is contained in:
crschnick 2024-02-28 07:52:21 +00:00
parent 3e7fbe89ac
commit d2d0df9789
89 changed files with 0 additions and 5460 deletions

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
'''
}
}
}

View file

@ -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;
}
'''
}
}
}

View file

@ -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;
}
'''
}
}
}

View file

@ -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;
}
'''
}
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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) {}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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) {}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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));
});
}
}

View file

@ -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"));
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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));
}
}

View file

@ -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;
});
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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()));
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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");
}
}

View file

@ -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());
}
}

View file

@ -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);
}
});
}
}

View file

@ -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);
}
}
}

View file

@ -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.

View file

@ -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:

View file

@ -1,2 +0,0 @@
appearance=Aussehen
uiOptions=UI Optionen

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}

View file

@ -1,3 +0,0 @@
.store-creator > .scroll-pane {
-fx-padding: 0 10px 0 0;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}
}
}

View file

@ -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();
}
};
}
}

View file

@ -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");
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
});
}
}

View file

@ -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());
}
}
}
}

View file

@ -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;
}
}

View file

@ -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.

View file

@ -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.

View file

@ -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)

View file

@ -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.

View file

@ -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/

View file

@ -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

View file

@ -1,4 +0,0 @@
name=Commons Lang
version=3.12.0
license=Apache License 2.0
link=https://commons.apache.org/proper/commons-lang/

View file

@ -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.

View file

@ -1,4 +0,0 @@
name=FormsFX
version=11.5.0
license=Apache License 2.0
link=https://github.com/dlsc-software-consulting-gmbh/FormsFX

View file

@ -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

View file

@ -1,4 +0,0 @@
name=Java Foundation Access
version=1.2.0
license=Apache License 2.0
link=https://github.com/0x4a616e/jfa

View file

@ -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.

View file

@ -1,4 +0,0 @@
name=JFoenix
version=9.0.10
license=MIT License
link=https://github.com/sshahine/JFoenix

View file

@ -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

View file

@ -1,4 +0,0 @@
name=jSystemThemeDetector
version=3.8
license=Apache License 2.0
link=https://github.com/Dansoftowner/jSystemThemeDetector

View file

@ -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.

View file

@ -1,4 +0,0 @@
name=OpenJDK
version=21.0.1
license=GPL2 with the Classpath Exception
link=https://jdk.java.net/21/

View file

@ -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.

View file

@ -1,4 +0,0 @@
name=oshi
version=6.4.2
license=MIT License
link=https://github.com/oshi/oshi

View file

@ -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.

View file

@ -1,4 +0,0 @@
name=PreferencesFX
version=11.9.0
license=Apache License 2.0
link=https://github.com/dlsc-software-consulting-gmbh/PreferencesFX

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -1,6 +0,0 @@
hello
world
how
is
it
going

View file

@ -1,2 +0,0 @@
hello
world

View file

@ -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;
}
'''
}
}
}

View file

@ -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"
}

View file

@ -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;
}
'''
}
}
}

View file

@ -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'
}

View file

@ -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;
}
'''
}
}
}

View file

@ -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;
}
'''
}
}
}