mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +00:00
Many small fixes
This commit is contained in:
parent
537a73589d
commit
20a334912a
20 changed files with 117 additions and 47 deletions
|
@ -41,8 +41,17 @@ public interface DataSource {
|
|||
*
|
||||
* @return the generator data source
|
||||
*/
|
||||
@Deprecated
|
||||
static DataSource supplySource() {
|
||||
static DataSource drain() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT YET IMPLEMENTED!
|
||||
* <p>
|
||||
* Creates a data source sink that will block with any read operations
|
||||
* until an external data producer routes the output into this sink.
|
||||
*/
|
||||
static DataSource sink() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.api.test;
|
||||
|
||||
import io.xpipe.beacon.BeaconDaemonController;
|
||||
import io.xpipe.core.util.XPipeDaemonMode;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
|
@ -8,7 +9,7 @@ public class ApiTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
BeaconDaemonController.start();
|
||||
BeaconDaemonController.start(XPipeDaemonMode.TRAY);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
|
|
@ -46,7 +46,7 @@ public class BeaconServer {
|
|||
command = XPipeInstallation.createExternalAsyncLaunchCommand(installationBase, mode, BeaconConfig.getDaemonArguments());
|
||||
} else {
|
||||
command = XPipeInstallation.createExternalLaunchCommand(
|
||||
getDaemonDebugExecutable(installationBase), BeaconConfig.getDaemonArguments());
|
||||
getDaemonDebugExecutable(installationBase), BeaconConfig.getDaemonArguments(), mode);
|
||||
}
|
||||
|
||||
var fullCommand = ShellTypes.getPlatformDefault().executeCommandListWithShell(command);
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.core.charsetter;
|
|||
import io.xpipe.core.util.Identifiers;
|
||||
import lombok.Value;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
@ -56,20 +55,10 @@ public class StreamCharset {
|
|||
Identifiers.get("utf", "16", "le", "bom")
|
||||
);
|
||||
|
||||
public static final StreamCharset UTF16 =
|
||||
new StreamCharset(StandardCharsets.UTF_16, null, Identifiers.get("utf", "16"));
|
||||
public static final StreamCharset UTF16 = UTF16_LE;
|
||||
|
||||
public static final StreamCharset UTF16_BOM = new StreamCharset(
|
||||
StandardCharsets.UTF_16,
|
||||
ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
|
||||
? UTF16_BE_BOM.getByteOrderMark()
|
||||
: UTF16_LE_BOM.getByteOrderMark(),
|
||||
Identifiers.get("utf", "16", "bom")
|
||||
);
|
||||
public static final StreamCharset UTF16_BOM = UTF16_LE_BOM;
|
||||
|
||||
// ======
|
||||
// UTF-32
|
||||
// ======
|
||||
public static final List<StreamCharset> COMMON = List.of(
|
||||
UTF8,
|
||||
UTF8_BOM,
|
||||
|
@ -101,6 +90,10 @@ public class StreamCharset {
|
|||
Identifiers.join(Identifiers.get("windows", "1252"), Identifiers.get("1252"))
|
||||
)
|
||||
);
|
||||
|
||||
// ======
|
||||
// UTF-32
|
||||
// ======
|
||||
public static final StreamCharset UTF32_LE =
|
||||
new StreamCharset(Charset.forName("utf-32le"), null, Identifiers.get("utf", "32", "le"));
|
||||
public static final StreamCharset UTF32_LE_BOM = new StreamCharset(
|
||||
|
|
|
@ -57,6 +57,7 @@ public abstract class ArrayNode extends DataStructureNode {
|
|||
return "array node";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final String toString(int indent) {
|
||||
var content = getNodes().stream().map(n -> n.toString(indent)).collect(Collectors.joining(", "));
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package io.xpipe.core.data.node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class TupleNode extends DataStructureNode {
|
||||
|
||||
|
@ -41,6 +40,21 @@ public abstract class TupleNode extends DataStructureNode {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<DataStructureNode> stream() {
|
||||
return getNodes().stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<DataStructureNode> spliterator() {
|
||||
return stream().spliterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<DataStructureNode> iterator() {
|
||||
return stream().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(int indent) {
|
||||
var is = " ".repeat(indent);
|
||||
|
|
|
@ -66,43 +66,57 @@ public abstract class ValueNode extends DataStructureNode {
|
|||
|
||||
public static ValueNode ofBytes(byte[] data) {
|
||||
var created = of(data);
|
||||
created.tag(IS_BINARY);
|
||||
if (data != null) {
|
||||
created.tag(IS_BINARY);}
|
||||
return created;
|
||||
}
|
||||
|
||||
public static ValueNode ofText(String text) {
|
||||
var created = of(text);
|
||||
created.tag(IS_TEXT);
|
||||
if (text != null) {
|
||||
created.tag(IS_TEXT);
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
public static ValueNode ofInteger(int integer) {
|
||||
var created = of(integer);
|
||||
created.tag(IS_INTEGER);
|
||||
created.tag(INTEGER_VALUE, integer);
|
||||
return created;
|
||||
}
|
||||
|
||||
public static ValueNode ofInteger(BigInteger integer) {
|
||||
var created = of(integer);
|
||||
created.tag(IS_INTEGER);
|
||||
if (integer != null) {
|
||||
created.tag(IS_INTEGER);
|
||||
created.tag(INTEGER_VALUE, integer);
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
public static ValueNode ofDecimal(double decimal) {
|
||||
var created = of(decimal);
|
||||
created.tag(IS_DECIMAL);
|
||||
created.tag(DECIMAL_VALUE, decimal);
|
||||
return created;
|
||||
}
|
||||
|
||||
public static ValueNode ofDecimal(BigDecimal decimal) {
|
||||
var created = of(decimal);
|
||||
created.tag(IS_DECIMAL);
|
||||
if (decimal != null) {
|
||||
created.tag(IS_DECIMAL);
|
||||
created.tag(DECIMAL_VALUE, decimal);
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
public static ValueNode ofBoolean(Boolean bool) {
|
||||
var created = of(bool);
|
||||
created.tag(IS_BOOLEAN);
|
||||
if (bool != null) {
|
||||
created.tag(IS_BOOLEAN);
|
||||
created.tag(bool ? BOOLEAN_TRUE : BOOLEAN_FALSE);
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
|
@ -17,13 +18,15 @@ import java.io.*;
|
|||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InMemoryStore extends JacksonizedValue implements StreamDataStore {
|
||||
|
||||
private byte[] value;
|
||||
|
||||
@JsonCreator
|
||||
public InMemoryStore(byte[] value) {
|
||||
this.value = value;
|
||||
@Override
|
||||
public String toString() {
|
||||
return value != null && value.length > 100 ? "<memory>" : (value != null ? new String(value) : "null");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,7 +36,7 @@ public class InMemoryStore extends JacksonizedValue implements StreamDataStore {
|
|||
|
||||
@Override
|
||||
public InputStream openInput() throws Exception {
|
||||
return new ByteArrayInputStream(value);
|
||||
return value != null ? new ByteArrayInputStream(value) : InputStream.nullInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,10 +20,10 @@ public abstract class LocalProcessControlProvider {
|
|||
INSTANCE = layer != null
|
||||
? ServiceLoader.load(layer, LocalProcessControlProvider.class)
|
||||
.findFirst()
|
||||
.orElseThrow()
|
||||
.orElse(null)
|
||||
: ServiceLoader.load(LocalProcessControlProvider.class)
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static ShellProcessControl create() {
|
||||
|
|
|
@ -22,7 +22,16 @@ public final class TextSource extends TextDataSource<StreamDataStore> implements
|
|||
|
||||
@Override
|
||||
protected io.xpipe.core.source.TextWriteConnection newWriteConnection(WriteMode mode) {
|
||||
return new TextWriteConnection(this);
|
||||
var sup = super.newWriteConnection(mode);
|
||||
if (sup != null) {
|
||||
return sup;
|
||||
}
|
||||
|
||||
if (mode.equals(WriteMode.REPLACE)) {
|
||||
return new TextWriteConnection(this);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException(mode.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,7 +15,7 @@ public class JacksonizedValue {
|
|||
}
|
||||
|
||||
@SneakyThrows
|
||||
public final String toString() {
|
||||
public String toString() {
|
||||
var tree = JacksonMapper.getDefault().valueToTree(this);
|
||||
return tree.toPrettyString();
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ public class XPipeInstallation {
|
|||
return "\"" + FileNames.join(installationBase, XPipeInstallation.getDaemonExecutablePath(OsType.getLocal())) + "\" --mode " + mode.getDisplayName() + suffix;
|
||||
}
|
||||
|
||||
public static String createExternalLaunchCommand(String command, String arguments) {
|
||||
public static String createExternalLaunchCommand(String command, String arguments, XPipeDaemonMode mode) {
|
||||
var suffix = (arguments != null ? " " + arguments : "");
|
||||
return "\"" + command + "\" --external" + suffix;
|
||||
return "\"" + command + "\" --mode " + mode.getDisplayName() + suffix;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
|
|
|
@ -24,6 +24,7 @@ dependencies {
|
|||
api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0"
|
||||
api group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: "2.13.0"
|
||||
|
||||
compileOnly 'org.hamcrest:hamcrest:2.2'
|
||||
compileOnly 'net.java.dev.jna:jna-jpms:5.12.1'
|
||||
compileOnly 'net.java.dev.jna:jna-platform-jpms:5.12.1'
|
||||
compileOnly group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.xpipe.extension.fxcomps.util;
|
||||
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
|
@ -15,12 +14,12 @@ public class BindingsHelper {
|
|||
/*
|
||||
TODO: Proper cleanup. Maybe with a separate thread?
|
||||
*/
|
||||
private static final Map<WeakReference<Object>, Set<ObservableValue<?>>> BINDINGS = new ConcurrentHashMap<>();
|
||||
private static final Map<WeakReference<Object>, Set<javafx.beans.Observable>> BINDINGS = new ConcurrentHashMap<>();
|
||||
|
||||
public static <T extends Binding<?>> T persist(T binding) {
|
||||
var dependencies = new HashSet<ObservableValue<?>>();
|
||||
var dependencies = new HashSet<javafx.beans.Observable>();
|
||||
while (dependencies.addAll(binding.getDependencies().stream()
|
||||
.map(o -> (ObservableValue<?>) o)
|
||||
.map(o -> (javafx.beans.Observable) o)
|
||||
.toList())) {
|
||||
}
|
||||
dependencies.add(binding);
|
||||
|
|
|
@ -4,13 +4,18 @@ import io.xpipe.core.data.node.DataStructureNode;
|
|||
import io.xpipe.core.data.node.ValueNode;
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DataTypeParser {
|
||||
|
||||
private static final Map<String, Currency> currencies =
|
||||
Currency.getAvailableCurrencies().stream().collect(Collectors.toMap(currency -> currency.getSymbol(), currency -> currency));
|
||||
|
||||
public static Optional<ValueNode> parseMonetary(String val) {
|
||||
for (Currency availableCurrency : Currency.getAvailableCurrencies()) {
|
||||
if (val.contains(availableCurrency.getSymbol())) {
|
||||
for (var availableCurrency : currencies.entrySet()) {
|
||||
if (val.contains(availableCurrency.getKey())) {
|
||||
String newStr = DataTypeParserInternal.cleanseNumberString(val);
|
||||
var node = DataTypeParserInternal.parseDecimalFromCleansed(newStr);
|
||||
if (node.isEmpty()) {
|
||||
|
@ -18,7 +23,7 @@ public class DataTypeParser {
|
|||
}
|
||||
|
||||
return Optional.of(ValueNode.ofCurrency(
|
||||
val, node.get().getMetaAttribute(DataStructureNode.DECIMAL_VALUE), availableCurrency));
|
||||
val, node.get().getMetaAttribute(DataStructureNode.DECIMAL_VALUE), availableCurrency.getValue()));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
package io.xpipe.extension.util;
|
||||
|
||||
import io.xpipe.core.data.node.DataStructureNode;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ExtensionTest {
|
||||
|
||||
public static void assertNodeEquals(DataStructureNode expected, DataStructureNode actual) {
|
||||
if (expected.isValue() || actual.isValue()) {
|
||||
Assertions.assertEquals(expected, actual);
|
||||
} else {
|
||||
for (int i = 0; i < Math.min(expected.size(), actual.size()); i++) {
|
||||
Assertions.assertEquals(expected.getNodes().get(i), actual.getNodes().get(i));
|
||||
}
|
||||
Assertions.assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static Path getResourcePath(Class<?> c, String name) {
|
||||
var url = c.getResource(name);
|
||||
|
|
|
@ -34,8 +34,10 @@ public class TypeConverter {
|
|||
var number = NumberUtils.createNumber(string);
|
||||
if (number instanceof Float || number instanceof Double) {
|
||||
node.tag(DataStructureNode.IS_DECIMAL);
|
||||
node.tag(DataStructureNode.DECIMAL_VALUE, number.doubleValue());
|
||||
} else {
|
||||
node.tag(DataStructureNode.IS_INTEGER);
|
||||
node.tag(DataStructureNode.INTEGER_VALUE, number.intValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,11 +74,11 @@ public class TypeConverter {
|
|||
}
|
||||
|
||||
if (node.hasMetaAttribute(DataStructureNode.BOOLEAN_FALSE)) {
|
||||
return Boolean.parseBoolean(node.getMetaAttribute(DataStructureNode.BOOLEAN_FALSE));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node.hasMetaAttribute(DataStructureNode.BOOLEAN_TRUE)) {
|
||||
return Boolean.parseBoolean(node.getMetaAttribute(DataStructureNode.BOOLEAN_TRUE));
|
||||
return true;
|
||||
}
|
||||
|
||||
var string = node.asString();
|
||||
|
|
|
@ -17,6 +17,7 @@ open module io.xpipe.extension {
|
|||
requires transitive io.xpipe.core;
|
||||
requires io.xpipe.beacon;
|
||||
requires io.xpipe.api;
|
||||
requires static org.hamcrest;
|
||||
requires com.fasterxml.jackson.databind;
|
||||
requires static com.sun.jna;
|
||||
requires static com.sun.jna.platform;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
|
||||
|
||||
apply from: "$buildscript.sourceFile/../junit.gradle"
|
||||
|
||||
def useExtension = System.getProperty('excludeExtensionLibrary') == null
|
||||
|
@ -33,8 +35,10 @@ test {
|
|||
" -Dio.xpipe.beacon.printMessages=false" +
|
||||
" -Dio.xpipe.app.logLevel=trace"
|
||||
|
||||
if (findProject(':app') != null) {
|
||||
systemProperty "io.xpipe.beacon.customDaemonCommand", "cmd.exe /c start \"\"X-Pipe Debug\"\" /i \"$rootDir\\gradlew.bat\" --console=plain $daemonCommand"
|
||||
// Use cmd window for tests
|
||||
if (findProject(':app') != null && System.getenv("XPIPE_MAPPING") != null && DefaultNativePlatform.currentOperatingSystem.isWindows()) {
|
||||
systemProperty "io.xpipe.beacon.customDaemonCommand",
|
||||
"cmd.exe /c start \"\"X-Pipe Debug\"\" /i \"$rootDir\\gradlew.bat\" --console=plain $daemonCommand"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
dependencies {
|
||||
testImplementation 'org.hamcrest:hamcrest:2.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
|
||||
|
|
Loading…
Reference in a new issue