mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-02 18:17:27 +13:00
Various small fixes
This commit is contained in:
parent
71b5d2d716
commit
9a2a1a8745
18 changed files with 415 additions and 137 deletions
|
@ -42,10 +42,8 @@ public abstract class DataSourceImpl implements DataSource {
|
||||||
case RAW -> {
|
case RAW -> {
|
||||||
yield new DataRawImpl(res.getId(), config, res.getInternalSource());
|
yield new DataRawImpl(res.getId(), config, res.getInternalSource());
|
||||||
}
|
}
|
||||||
case COLLECTION -> throw new UnsupportedOperationException(
|
case COLLECTION -> throw new UnsupportedOperationException("Unimplemented case: " + res.getType());
|
||||||
"Unimplemented case: " + res.getType());
|
default -> throw new IllegalArgumentException("Unexpected value: " + res.getType());
|
||||||
default -> throw new IllegalArgumentException(
|
|
||||||
"Unexpected value: " + res.getType());
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -64,17 +62,18 @@ public abstract class DataSourceImpl implements DataSource {
|
||||||
|
|
||||||
public static DataSource create(DataSourceId id, String type, DataStore store) {
|
public static DataSource create(DataSourceId id, String type, DataStore store) {
|
||||||
if (store instanceof StreamDataStore s && s.isContentExclusivelyAccessible()) {
|
if (store instanceof StreamDataStore s && s.isContentExclusivelyAccessible()) {
|
||||||
var res = XPipeApiConnection.execute(con -> {
|
store = XPipeApiConnection.execute(con -> {
|
||||||
var req = StoreStreamExchange.Request.builder().build();
|
var internal = con.createInternalStreamStore();
|
||||||
StoreStreamExchange.Response r = con.performOutputExchange(req, out -> {
|
var req = WriteStreamExchange.Request.builder()
|
||||||
|
.name(internal.getUuid().toString())
|
||||||
|
.build();
|
||||||
|
con.performOutputExchange(req, out -> {
|
||||||
try (InputStream inputStream = s.openInput()) {
|
try (InputStream inputStream = s.openInput()) {
|
||||||
inputStream.transferTo(out);
|
inputStream.transferTo(out);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return r;
|
return internal;
|
||||||
});
|
});
|
||||||
|
|
||||||
store = res.getStore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var startReq = ReadExchange.Request.builder()
|
var startReq = ReadExchange.Request.builder()
|
||||||
|
@ -96,13 +95,16 @@ public abstract class DataSourceImpl implements DataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataSource create(DataSourceId id, String type, InputStream in) {
|
public static DataSource create(DataSourceId id, String type, InputStream in) {
|
||||||
var res = XPipeApiConnection.execute(con -> {
|
var store = XPipeApiConnection.execute(con -> {
|
||||||
var req = StoreStreamExchange.Request.builder().build();
|
var internal = con.createInternalStreamStore();
|
||||||
StoreStreamExchange.Response r = con.performOutputExchange(req, out -> in.transferTo(out));
|
var req = WriteStreamExchange.Request.builder()
|
||||||
return r;
|
.name(internal.getUuid().toString())
|
||||||
|
.build();
|
||||||
|
con.performOutputExchange(req, out -> {
|
||||||
|
in.transferTo(out);
|
||||||
|
});
|
||||||
|
return internal;
|
||||||
});
|
});
|
||||||
|
|
||||||
var store = res.getStore();
|
|
||||||
|
|
||||||
var startReq = ReadExchange.Request.builder()
|
var startReq = ReadExchange.Request.builder()
|
||||||
.provider(type)
|
.provider(type)
|
||||||
|
|
|
@ -7,12 +7,15 @@ import io.xpipe.api.connector.XPipeApiConnection;
|
||||||
import io.xpipe.api.util.TypeDescriptor;
|
import io.xpipe.api.util.TypeDescriptor;
|
||||||
import io.xpipe.beacon.BeaconException;
|
import io.xpipe.beacon.BeaconException;
|
||||||
import io.xpipe.beacon.exchange.ReadExchange;
|
import io.xpipe.beacon.exchange.ReadExchange;
|
||||||
import io.xpipe.beacon.exchange.StoreStreamExchange;
|
import io.xpipe.beacon.exchange.WriteStreamExchange;
|
||||||
|
import io.xpipe.beacon.exchange.cli.StoreAddExchange;
|
||||||
|
import io.xpipe.beacon.util.QuietDialogHandler;
|
||||||
import io.xpipe.core.data.node.DataStructureNode;
|
import io.xpipe.core.data.node.DataStructureNode;
|
||||||
import io.xpipe.core.data.node.DataStructureNodeAcceptor;
|
import io.xpipe.core.data.node.DataStructureNodeAcceptor;
|
||||||
import io.xpipe.core.data.node.TupleNode;
|
import io.xpipe.core.data.node.TupleNode;
|
||||||
import io.xpipe.core.data.type.TupleType;
|
import io.xpipe.core.data.type.TupleType;
|
||||||
import io.xpipe.core.data.typed.TypedDataStreamWriter;
|
import io.xpipe.core.data.typed.TypedDataStreamWriter;
|
||||||
|
import io.xpipe.core.impl.InternalStreamStore;
|
||||||
import io.xpipe.core.source.DataSourceId;
|
import io.xpipe.core.source.DataSourceId;
|
||||||
import io.xpipe.core.source.DataSourceReference;
|
import io.xpipe.core.source.DataSourceReference;
|
||||||
|
|
||||||
|
@ -25,13 +28,20 @@ public class DataTableAccumulatorImpl implements DataTableAccumulator {
|
||||||
private final XPipeApiConnection connection;
|
private final XPipeApiConnection connection;
|
||||||
private final TupleType type;
|
private final TupleType type;
|
||||||
private int rows;
|
private int rows;
|
||||||
|
private InternalStreamStore store;
|
||||||
private TupleType writtenDescriptor;
|
private TupleType writtenDescriptor;
|
||||||
private OutputStream bodyOutput;
|
private OutputStream bodyOutput;
|
||||||
|
|
||||||
public DataTableAccumulatorImpl(TupleType type) {
|
public DataTableAccumulatorImpl(TupleType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
connection = XPipeApiConnection.open();
|
connection = XPipeApiConnection.open();
|
||||||
connection.sendRequest(StoreStreamExchange.Request.builder().build());
|
|
||||||
|
store = new InternalStreamStore();
|
||||||
|
var addReq = StoreAddExchange.Request.builder().storeInput(store).name(store.getUuid().toString()).build();
|
||||||
|
StoreAddExchange.Response addRes = connection.performSimpleExchange(addReq);
|
||||||
|
QuietDialogHandler.handle(addRes.getConfig(), connection);
|
||||||
|
|
||||||
|
connection.sendRequest(WriteStreamExchange.Request.builder().name(store.getUuid().toString()).build());
|
||||||
bodyOutput = connection.sendBody();
|
bodyOutput = connection.sendBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +53,12 @@ public class DataTableAccumulatorImpl implements DataTableAccumulator {
|
||||||
throw new BeaconException(e);
|
throw new BeaconException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoreStreamExchange.Response res = connection.receiveResponse();
|
WriteStreamExchange.Response res = connection.receiveResponse();
|
||||||
connection.close();
|
connection.close();
|
||||||
|
|
||||||
var req = ReadExchange.Request.builder()
|
var req = ReadExchange.Request.builder()
|
||||||
.target(id)
|
.target(id)
|
||||||
.store(res.getStore())
|
.store(store)
|
||||||
.provider("xpbt")
|
.provider("xpbt")
|
||||||
.configureAll(false)
|
.configureAll(false)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package io.xpipe.beacon;
|
package io.xpipe.beacon;
|
||||||
|
|
||||||
|
import io.xpipe.beacon.exchange.cli.StoreAddExchange;
|
||||||
|
import io.xpipe.beacon.util.QuietDialogHandler;
|
||||||
|
import io.xpipe.core.impl.InternalStreamStore;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -169,6 +173,14 @@ public abstract class BeaconConnection implements AutoCloseable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InternalStreamStore createInternalStreamStore() {
|
||||||
|
var store = new InternalStreamStore();
|
||||||
|
var addReq = StoreAddExchange.Request.builder().storeInput(store).name(store.getUuid().toString()).build();
|
||||||
|
StoreAddExchange.Response addRes = performSimpleExchange(addReq);
|
||||||
|
QuietDialogHandler.handle(addRes.getConfig(), this);
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
private BeaconException unwrapException(Exception exception) {
|
private BeaconException unwrapException(Exception exception) {
|
||||||
if (exception instanceof ServerException s) {
|
if (exception instanceof ServerException s) {
|
||||||
return new BeaconException("An internal server error occurred", s);
|
return new BeaconException("An internal server error occurred", s);
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package io.xpipe.beacon.exchange;
|
|
||||||
|
|
||||||
import io.xpipe.beacon.RequestMessage;
|
|
||||||
import io.xpipe.beacon.ResponseMessage;
|
|
||||||
import io.xpipe.core.impl.FileStore;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Value;
|
|
||||||
import lombok.extern.jackson.Jacksonized;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores a stream of data in a storage.
|
|
||||||
*/
|
|
||||||
public class StoreStreamExchange implements MessageExchange {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "storeStream";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
|
||||||
@Builder
|
|
||||||
@Value
|
|
||||||
public static class Request implements RequestMessage {}
|
|
||||||
|
|
||||||
@Jacksonized
|
|
||||||
@Builder
|
|
||||||
@Value
|
|
||||||
public static class Response implements ResponseMessage {
|
|
||||||
FileStore store;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.xpipe.beacon.util;
|
package io.xpipe.beacon.util;
|
||||||
|
|
||||||
import io.xpipe.beacon.BeaconConnection;
|
import io.xpipe.beacon.BeaconConnection;
|
||||||
import io.xpipe.beacon.ClientException;
|
import io.xpipe.beacon.BeaconException;
|
||||||
import io.xpipe.beacon.exchange.cli.DialogExchange;
|
import io.xpipe.beacon.exchange.cli.DialogExchange;
|
||||||
import io.xpipe.core.dialog.BaseQueryElement;
|
import io.xpipe.core.dialog.BaseQueryElement;
|
||||||
import io.xpipe.core.dialog.ChoiceElement;
|
import io.xpipe.core.dialog.ChoiceElement;
|
||||||
|
@ -13,7 +13,7 @@ import java.util.UUID;
|
||||||
|
|
||||||
public class QuietDialogHandler {
|
public class QuietDialogHandler {
|
||||||
|
|
||||||
public static void handle(DialogReference ref, BeaconConnection connection) throws ClientException {
|
public static void handle(DialogReference ref, BeaconConnection connection) {
|
||||||
new QuietDialogHandler(ref, connection, Map.of()).handle();
|
new QuietDialogHandler(ref, connection, Map.of()).handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public class QuietDialogHandler {
|
||||||
this.overrides = overrides;
|
this.overrides = overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle() throws ClientException {
|
public void handle() {
|
||||||
String response = null;
|
String response = null;
|
||||||
|
|
||||||
if (element instanceof ChoiceElement c) {
|
if (element instanceof ChoiceElement c) {
|
||||||
|
@ -45,7 +45,7 @@ public class QuietDialogHandler {
|
||||||
.value(response)
|
.value(response)
|
||||||
.build());
|
.build());
|
||||||
if (res.getElement() != null && element.equals(res.getElement())) {
|
if (res.getElement() != null && element.equals(res.getElement())) {
|
||||||
throw new ClientException(
|
throw new BeaconException(
|
||||||
"Invalid value for key " + res.getElement().toDisplayString());
|
"Invalid value for key " + res.getElement().toDisplayString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,6 @@ module io.xpipe.beacon {
|
||||||
ListStoresExchange,
|
ListStoresExchange,
|
||||||
DialogExchange,
|
DialogExchange,
|
||||||
QueryDataSourceExchange,
|
QueryDataSourceExchange,
|
||||||
StoreStreamExchange,
|
|
||||||
EditExchange,
|
EditExchange,
|
||||||
RemoveEntryExchange,
|
RemoveEntryExchange,
|
||||||
RemoveCollectionExchange,
|
RemoveCollectionExchange,
|
||||||
|
|
|
@ -1,49 +1,111 @@
|
||||||
package io.xpipe.core.charsetter;
|
package io.xpipe.core.charsetter;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import io.xpipe.core.util.Identifiers;
|
||||||
import com.fasterxml.jackson.annotation.JsonValue;
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
public class StreamCharset {
|
public class StreamCharset {
|
||||||
|
|
||||||
public static final StreamCharset UTF8 = new StreamCharset(StandardCharsets.UTF_8, null);
|
public static final StreamCharset UTF8 =
|
||||||
public static final StreamCharset UTF8_BOM =
|
new StreamCharset(StandardCharsets.UTF_8, null, Identifiers.get("utf", "8"));
|
||||||
new StreamCharset(StandardCharsets.UTF_8, new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
|
|
||||||
public static final StreamCharset UTF16_BE = new StreamCharset(StandardCharsets.UTF_16BE, null);
|
|
||||||
public static final StreamCharset UTF16_BE_BOM =
|
|
||||||
new StreamCharset(StandardCharsets.UTF_16BE, new byte[] {(byte) 0xFE, (byte) 0xFF});
|
|
||||||
public static final StreamCharset UTF16_LE = new StreamCharset(StandardCharsets.UTF_16LE, null);
|
|
||||||
public static final StreamCharset UTF16_LE_BOM =
|
|
||||||
new StreamCharset(StandardCharsets.UTF_16LE, new byte[] {(byte) 0xFF, (byte) 0xFE});
|
|
||||||
|
|
||||||
public static final StreamCharset UTF32_LE = new StreamCharset(Charset.forName("utf-32le"), null);
|
public static final StreamCharset UTF8_BOM = new StreamCharset(
|
||||||
public static final StreamCharset UTF32_LE_BOM =
|
StandardCharsets.UTF_8,
|
||||||
new StreamCharset(Charset.forName("utf-32le"), new byte[] {0x00, 0x00, (byte) 0xFE, (byte) 0xFF});
|
new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF},
|
||||||
public static final StreamCharset UTF32_BE = new StreamCharset(Charset.forName("utf-32be"), null);
|
Identifiers.get("utf", "8", "bom"));
|
||||||
public static final StreamCharset UTF32_BE_BOM =
|
|
||||||
new StreamCharset(Charset.forName("utf-32be"), new byte[] {(byte) 0xFF, (byte) 0xFE, 0x00, 0x00, });
|
// ======
|
||||||
|
// UTF-16
|
||||||
|
// ======
|
||||||
|
|
||||||
|
public static final StreamCharset UTF16_BE =
|
||||||
|
new StreamCharset(StandardCharsets.UTF_16BE, null, Identifiers.get("utf", "16", "be"));
|
||||||
|
|
||||||
|
public static final StreamCharset UTF16_BE_BOM = new StreamCharset(
|
||||||
|
StandardCharsets.UTF_16BE,
|
||||||
|
new byte[] {(byte) 0xFE, (byte) 0xFF},
|
||||||
|
Identifiers.get("utf", "16", "be", "bom"));
|
||||||
|
|
||||||
|
public static final StreamCharset UTF16_LE =
|
||||||
|
new StreamCharset(StandardCharsets.UTF_16LE, null, Identifiers.get("utf", "16", "le"));
|
||||||
|
|
||||||
|
public static final StreamCharset UTF16_LE_BOM = new StreamCharset(
|
||||||
|
StandardCharsets.UTF_16LE,
|
||||||
|
new byte[] {(byte) 0xFF, (byte) 0xFE},
|
||||||
|
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_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"));
|
||||||
|
|
||||||
|
// ======
|
||||||
|
// 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(
|
||||||
|
Charset.forName("utf-32le"),
|
||||||
|
new byte[] {0x00, 0x00, (byte) 0xFE, (byte) 0xFF},
|
||||||
|
Identifiers.get("utf", "32", "le", "bom"));
|
||||||
|
|
||||||
|
public static final StreamCharset UTF32_BE =
|
||||||
|
new StreamCharset(Charset.forName("utf-32be"), null, Identifiers.get("utf", "32", "be"));
|
||||||
|
|
||||||
|
public static final StreamCharset UTF32_BE_BOM = new StreamCharset(
|
||||||
|
Charset.forName("utf-32be"),
|
||||||
|
new byte[] {
|
||||||
|
(byte) 0xFF, (byte) 0xFE, 0x00, 0x00,
|
||||||
|
},
|
||||||
|
Identifiers.get("utf", "32", "be", "bom"));
|
||||||
|
|
||||||
public static final List<StreamCharset> COMMON = List.of(
|
public static final List<StreamCharset> COMMON = List.of(
|
||||||
UTF8,
|
UTF8,
|
||||||
UTF8_BOM,
|
UTF8_BOM,
|
||||||
UTF16_BE,
|
UTF16,
|
||||||
UTF16_BE_BOM,
|
UTF16_BOM,
|
||||||
UTF16_LE,
|
new StreamCharset(
|
||||||
UTF16_LE_BOM,
|
StandardCharsets.US_ASCII,
|
||||||
new StreamCharset(StandardCharsets.US_ASCII, null),
|
null,
|
||||||
new StreamCharset(StandardCharsets.ISO_8859_1, null),
|
Identifiers.join(Identifiers.get("ascii"), Identifiers.get("us", "ascii"))),
|
||||||
new StreamCharset(Charset.forName("Windows-1251"), null),
|
new StreamCharset(
|
||||||
new StreamCharset(Charset.forName("Windows-1252"), null));
|
StandardCharsets.ISO_8859_1,
|
||||||
private static final List<StreamCharset> RARE_KNOWN = List.of(UTF32_LE, UTF32_LE_BOM, UTF32_BE, UTF32_BE_BOM);
|
null,
|
||||||
|
Identifiers.join(
|
||||||
|
Identifiers.get("iso", "8859"),
|
||||||
|
Identifiers.get("iso", "8859", "1"),
|
||||||
|
Identifiers.get("8859"),
|
||||||
|
Identifiers.get("8859", "1"))),
|
||||||
|
new StreamCharset(
|
||||||
|
Charset.forName("Windows-1251"),
|
||||||
|
null,
|
||||||
|
Identifiers.join(Identifiers.get("windows", "1251"), Identifiers.get("1251"))),
|
||||||
|
new StreamCharset(
|
||||||
|
Charset.forName("Windows-1252"),
|
||||||
|
null,
|
||||||
|
Identifiers.join(Identifiers.get("windows", "1252"), Identifiers.get("1252"))));
|
||||||
|
|
||||||
|
private static final List<StreamCharset> RARE_NAMED =
|
||||||
|
List.of(UTF16_LE, UTF16_LE_BOM, UTF16_BE, UTF16_BE_BOM, UTF32_LE, UTF32_LE_BOM, UTF32_BE, UTF32_BE_BOM);
|
||||||
|
|
||||||
public static final List<StreamCharset> RARE = Stream.concat(
|
public static final List<StreamCharset> RARE = Stream.concat(
|
||||||
RARE_KNOWN.stream(),
|
RARE_NAMED.stream(),
|
||||||
Charset.availableCharsets().values().stream()
|
Charset.availableCharsets().values().stream()
|
||||||
.filter(charset -> !charset.equals(StandardCharsets.UTF_16)
|
.filter(charset -> !charset.equals(StandardCharsets.UTF_16)
|
||||||
&& !charset.equals(Charset.forName("utf-32"))
|
&& !charset.equals(Charset.forName("utf-32"))
|
||||||
|
@ -52,31 +114,59 @@ public class StreamCharset {
|
||||||
&& !charset.displayName().endsWith("-BOM")
|
&& !charset.displayName().endsWith("-BOM")
|
||||||
&& COMMON.stream()
|
&& COMMON.stream()
|
||||||
.noneMatch(c -> c.getCharset().equals(charset))
|
.noneMatch(c -> c.getCharset().equals(charset))
|
||||||
&& RARE_KNOWN.stream()
|
&& RARE_NAMED.stream()
|
||||||
.noneMatch(c -> c.getCharset().equals(charset)))
|
.noneMatch(c -> c.getCharset().equals(charset)))
|
||||||
.map(charset -> new StreamCharset(charset, null)))
|
.map(charset -> new StreamCharset(
|
||||||
|
charset,
|
||||||
|
null,
|
||||||
|
Identifiers.get(charset.name().split("-")))))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
public static final List<StreamCharset> ALL = Stream.concat(COMMON.stream(), RARE.stream()).toList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Charset charset;
|
Charset charset;
|
||||||
byte[] byteOrderMark;
|
byte[] byteOrderMark;
|
||||||
|
List<String> names;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof StreamCharset that)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return charset.equals(that.charset) && Arrays.equals(byteOrderMark, that.byteOrderMark);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = Objects.hash(charset);
|
||||||
|
result = 31 * result + Arrays.hashCode(byteOrderMark);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static StreamCharset get(Charset charset, boolean byteOrderMark) {
|
public static StreamCharset get(Charset charset, boolean byteOrderMark) {
|
||||||
return Stream.concat(COMMON.stream(), RARE.stream())
|
return ALL.stream()
|
||||||
.filter(streamCharset ->
|
.filter(streamCharset ->
|
||||||
streamCharset.getCharset().equals(charset) && streamCharset.hasByteOrderMark() == byteOrderMark)
|
streamCharset.getCharset().equals(charset) && streamCharset.hasByteOrderMark() == byteOrderMark)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow();
|
.orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public static StreamCharset get(String s) {
|
public static StreamCharset get(String s) {
|
||||||
var byteOrderMark = s.endsWith("-bom");
|
var found = ALL.stream().filter(streamCharset -> streamCharset.getNames().contains(s.toLowerCase(Locale.ROOT))).findFirst();
|
||||||
var charset = Charset.forName(s.substring(0, s.length() - (byteOrderMark ? 4 : 0)));
|
if (found.isEmpty()) {
|
||||||
return StreamCharset.get(charset, byteOrderMark);
|
throw new IllegalArgumentException("Unknown charset name: " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return found.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonValue
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getCharset().name().toLowerCase(Locale.ROOT) + (hasByteOrderMark() ? "-bom" : "");
|
return getNames().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasByteOrderMark() {
|
public boolean hasByteOrderMark() {
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package io.xpipe.core.impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import io.xpipe.core.store.DataFlow;
|
||||||
|
import io.xpipe.core.store.StreamDataStore;
|
||||||
|
import io.xpipe.core.util.DataStateProvider;
|
||||||
|
import io.xpipe.core.util.JacksonizedValue;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@JsonTypeName("internalStream")
|
||||||
|
@SuperBuilder
|
||||||
|
@Jacksonized
|
||||||
|
@Getter
|
||||||
|
public class InternalStreamStore extends JacksonizedValue implements StreamDataStore {
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
public InternalStreamStore() {
|
||||||
|
this.uuid = UUID.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataFlow getFlow() {
|
||||||
|
return DataFlow.INPUT_OUTPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> determineDefaultName() {
|
||||||
|
return Optional.of(uuid.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getFile() {
|
||||||
|
return DataStateProvider.get().getInternalStreamStore(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Instant> determineLastModified() throws IOException {
|
||||||
|
return Optional.of(Files.getLastModifiedTime(getFile()).toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream openInput() throws Exception {
|
||||||
|
return Files.newInputStream(getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream openOutput() throws Exception {
|
||||||
|
return Files.newOutputStream(getFile());
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import io.xpipe.core.impl.StdinDataStore;
|
||||||
import io.xpipe.core.impl.StdoutDataStore;
|
import io.xpipe.core.impl.StdoutDataStore;
|
||||||
import io.xpipe.core.source.DataSource;
|
import io.xpipe.core.source.DataSource;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ public interface DataStore {
|
||||||
/**
|
/**
|
||||||
* Determines the last modified of this data store if this data store supports it.
|
* Determines the last modified of this data store if this data store supports it.
|
||||||
*/
|
*/
|
||||||
default Optional<Instant> determineLastModified() {
|
default Optional<Instant> determineLastModified() throws IOException {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ package io.xpipe.core.util;
|
||||||
|
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public abstract class DataStateProvider {
|
public abstract class DataStateProvider {
|
||||||
|
@ -22,4 +24,6 @@ public abstract class DataStateProvider {
|
||||||
public abstract void putState(DataStore store, String key, Object value);
|
public abstract void putState(DataStore store, String key, Object value);
|
||||||
|
|
||||||
public abstract <T> T getState(DataStore store, String key, Class<T> c, Supplier<T> def);
|
public abstract <T> T getState(DataStore store, String key, Class<T> c, Supplier<T> def);
|
||||||
|
|
||||||
|
public abstract Path getInternalStreamStore(UUID id);
|
||||||
}
|
}
|
||||||
|
|
25
core/src/main/java/io/xpipe/core/util/Identifiers.java
Normal file
25
core/src/main/java/io/xpipe/core/util/Identifiers.java
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package io.xpipe.core.util;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Identifiers {
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static List<String> join(List<String>... s) {
|
||||||
|
return Arrays.stream(s).flatMap(Collection::stream).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> get(String... s) {
|
||||||
|
return nameAlternatives(Arrays.asList(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> nameAlternatives(List<String> split) {
|
||||||
|
return List.of(
|
||||||
|
String.join("", split),
|
||||||
|
String.join(" ", split),
|
||||||
|
String.join("_", split),
|
||||||
|
String.join("-", split));
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,11 +8,16 @@ import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
@Getter
|
@Getter
|
||||||
public class TrackEvent {
|
public class TrackEvent {
|
||||||
|
|
||||||
|
public static TrackEventBuilder storage() {
|
||||||
|
return TrackEvent.builder().category("storage");
|
||||||
|
}
|
||||||
|
|
||||||
private final Thread thread = Thread.currentThread();
|
private final Thread thread = Thread.currentThread();
|
||||||
private final Instant instant = Instant.now();
|
private final Instant instant = Instant.now();
|
||||||
private String type;
|
private String type;
|
||||||
|
@ -107,10 +112,17 @@ public class TrackEvent {
|
||||||
if (tags.size() > 0) {
|
if (tags.size() > 0) {
|
||||||
s.append(" {\n");
|
s.append(" {\n");
|
||||||
for (var e : tags.entrySet()) {
|
for (var e : tags.entrySet()) {
|
||||||
|
var value = e.toString().contains("\n")
|
||||||
|
? "\n"
|
||||||
|
+ (e.toString()
|
||||||
|
.lines()
|
||||||
|
.map(line -> " | " + line)
|
||||||
|
.collect(Collectors.joining("\n")))
|
||||||
|
: e.toString();
|
||||||
s.append(" ")
|
s.append(" ")
|
||||||
.append(e.getKey())
|
.append(e.getKey())
|
||||||
.append("=")
|
.append("=")
|
||||||
.append(e.getValue())
|
.append(value)
|
||||||
.append("\n");
|
.append("\n");
|
||||||
}
|
}
|
||||||
s.append("}");
|
s.append("}");
|
||||||
|
@ -120,6 +132,11 @@ public class TrackEvent {
|
||||||
|
|
||||||
public static class TrackEventBuilder {
|
public static class TrackEventBuilder {
|
||||||
|
|
||||||
|
public TrackEventBuilder trace() {
|
||||||
|
this.type("trace");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public TrackEventBuilder windowCategory() {
|
public TrackEventBuilder windowCategory() {
|
||||||
this.category("window");
|
this.category("window");
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -47,6 +47,10 @@ public abstract class Comp<S extends CompStructure<?>> {
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Comp<S> visible(ObservableValue<Boolean> o) {
|
||||||
|
return apply(struc -> struc.get().visibleProperty().bind(o));
|
||||||
|
}
|
||||||
|
|
||||||
public Comp<S> disable(ObservableValue<Boolean> o) {
|
public Comp<S> disable(ObservableValue<Boolean> o) {
|
||||||
return apply(struc -> struc.get().disableProperty().bind(o));
|
return apply(struc -> struc.get().disableProperty().bind(o));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,19 @@ package io.xpipe.extension.fxcomps.impl;
|
||||||
import io.xpipe.extension.fxcomps.Comp;
|
import io.xpipe.extension.fxcomps.Comp;
|
||||||
import io.xpipe.extension.fxcomps.CompStructure;
|
import io.xpipe.extension.fxcomps.CompStructure;
|
||||||
import io.xpipe.extension.fxcomps.SimpleCompStructure;
|
import io.xpipe.extension.fxcomps.SimpleCompStructure;
|
||||||
|
import io.xpipe.extension.fxcomps.util.PlatformThread;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.geometry.Orientation;
|
import javafx.geometry.Orientation;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.FlowPane;
|
import javafx.scene.layout.*;
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class DynamicOptionsComp extends Comp<CompStructure<FlowPane>> {
|
public class DynamicOptionsComp extends Comp<CompStructure<Pane>> {
|
||||||
|
|
||||||
private final List<Entry> entries;
|
private final List<Entry> entries;
|
||||||
private final boolean wrap;
|
private final boolean wrap;
|
||||||
|
@ -27,12 +25,28 @@ public class DynamicOptionsComp extends Comp<CompStructure<FlowPane>> {
|
||||||
this.wrap = wrap;
|
this.wrap = wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Entry queryEntry(String key) {
|
||||||
|
return entries.stream()
|
||||||
|
.filter(entry -> entry.key != null && entry.key.equals(key))
|
||||||
|
.findAny()
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompStructure<FlowPane> createBase() {
|
public CompStructure<Pane> createBase() {
|
||||||
var flow = new FlowPane(Orientation.HORIZONTAL);
|
Pane pane;
|
||||||
flow.setAlignment(Pos.CENTER);
|
if (wrap) {
|
||||||
flow.setHgap(14);
|
var content = new FlowPane(Orientation.HORIZONTAL);
|
||||||
flow.setVgap(7);
|
content.setAlignment(Pos.CENTER);
|
||||||
|
content.setHgap(14);
|
||||||
|
content.setVgap(7);
|
||||||
|
pane = content;
|
||||||
|
} else {
|
||||||
|
var content = new VBox();
|
||||||
|
content.setAlignment(Pos.CENTER);
|
||||||
|
content.setSpacing(7);
|
||||||
|
pane = content;
|
||||||
|
}
|
||||||
|
|
||||||
var nameRegions = new ArrayList<Region>();
|
var nameRegions = new ArrayList<Region>();
|
||||||
var compRegions = new ArrayList<Region>();
|
var compRegions = new ArrayList<Region>();
|
||||||
|
@ -41,30 +55,38 @@ public class DynamicOptionsComp extends Comp<CompStructure<FlowPane>> {
|
||||||
var line = new HBox();
|
var line = new HBox();
|
||||||
line.setFillHeight(true);
|
line.setFillHeight(true);
|
||||||
if (!wrap) {
|
if (!wrap) {
|
||||||
line.prefWidthProperty().bind(flow.widthProperty());
|
line.prefWidthProperty().bind(pane.widthProperty());
|
||||||
}
|
}
|
||||||
line.setSpacing(8);
|
line.setSpacing(8);
|
||||||
|
|
||||||
|
Region compRegion = null;
|
||||||
|
if (entry.comp() != null) {
|
||||||
|
compRegion = entry.comp().createRegion();
|
||||||
|
}
|
||||||
|
|
||||||
if (entry.name() != null) {
|
if (entry.name() != null) {
|
||||||
var name = new Label();
|
var name = new Label();
|
||||||
name.textProperty().bind(entry.name());
|
name.textProperty().bind(entry.name());
|
||||||
name.prefHeightProperty().bind(line.heightProperty());
|
name.prefHeightProperty().bind(line.heightProperty());
|
||||||
name.setMinWidth(Region.USE_PREF_SIZE);
|
name.setMinWidth(Region.USE_PREF_SIZE);
|
||||||
name.setAlignment(Pos.CENTER_LEFT);
|
name.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
if (compRegion != null) {
|
||||||
|
name.visibleProperty().bind(PlatformThread.sync(compRegion.visibleProperty()));
|
||||||
|
name.managedProperty().bind(PlatformThread.sync(compRegion.managedProperty()));
|
||||||
|
}
|
||||||
nameRegions.add(name);
|
nameRegions.add(name);
|
||||||
line.getChildren().add(name);
|
line.getChildren().add(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.comp() != null) {
|
if (entry.comp() != null) {
|
||||||
var r = entry.comp().createRegion();
|
compRegions.add(compRegion);
|
||||||
compRegions.add(r);
|
line.getChildren().add(compRegion);
|
||||||
line.getChildren().add(r);
|
|
||||||
if (!wrap) {
|
if (!wrap) {
|
||||||
HBox.setHgrow(r, Priority.ALWAYS);
|
HBox.setHgrow(compRegion, Priority.ALWAYS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flow.getChildren().add(line);
|
pane.getChildren().add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
|
@ -101,12 +123,12 @@ public class DynamicOptionsComp extends Comp<CompStructure<FlowPane>> {
|
||||||
nameRegions.forEach(r -> r.prefWidthProperty().bind(nameWidthBinding));
|
nameRegions.forEach(r -> r.prefWidthProperty().bind(nameWidthBinding));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SimpleCompStructure<>(flow);
|
return new SimpleCompStructure<>(pane);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Entry> getEntries() {
|
public List<Entry> getEntries() {
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Entry(ObservableValue<String> name, Comp<?> comp) {}
|
public record Entry(String key, ObservableValue<String> name, Comp<?> comp) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package io.xpipe.extension.fxcomps.impl;
|
||||||
|
|
||||||
|
import io.xpipe.extension.fxcomps.Comp;
|
||||||
|
import io.xpipe.extension.fxcomps.CompStructure;
|
||||||
|
import io.xpipe.extension.fxcomps.SimpleCompStructure;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GrowPaneComp extends Comp<CompStructure<Pane>> {
|
||||||
|
|
||||||
|
private final List<Comp<?>> comps;
|
||||||
|
|
||||||
|
public GrowPaneComp(List<Comp<?>> comps) {
|
||||||
|
this.comps = List.copyOf(comps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompStructure<Pane> createBase() {
|
||||||
|
var pane = new BorderPane();
|
||||||
|
for (var c : comps) {
|
||||||
|
pane.setCenter(c.createRegion());
|
||||||
|
}
|
||||||
|
pane.setPickOnBounds(false);
|
||||||
|
return new SimpleCompStructure<>(pane);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package io.xpipe.extension.fxcomps.impl;
|
||||||
|
|
||||||
|
import io.xpipe.extension.fxcomps.Comp;
|
||||||
|
import io.xpipe.extension.fxcomps.CompStructure;
|
||||||
|
import io.xpipe.extension.fxcomps.SimpleCompStructure;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PaneComp extends Comp<CompStructure<Pane>> {
|
||||||
|
|
||||||
|
private final List<Comp<?>> comps;
|
||||||
|
|
||||||
|
public PaneComp(List<Comp<?>> comps) {
|
||||||
|
this.comps = List.copyOf(comps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompStructure<Pane> createBase() {
|
||||||
|
var pane = new Pane();
|
||||||
|
for (var c : comps) {
|
||||||
|
pane.getChildren().add(c.createRegion());
|
||||||
|
}
|
||||||
|
pane.setPickOnBounds(false);
|
||||||
|
return new SimpleCompStructure<>(pane);
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,10 +43,14 @@ public class ToggleGroupComp<T> extends Comp<CompStructure<HBox>> {
|
||||||
box.getChildren().add(b);
|
box.getChildren().add(b);
|
||||||
b.setToggleGroup(group);
|
b.setToggleGroup(group);
|
||||||
value.addListener((c, o, n) -> {
|
value.addListener((c, o, n) -> {
|
||||||
PlatformThread.runLaterIfNeeded(() -> b.setSelected(entry.equals(n)));
|
PlatformThread.runLaterIfNeeded(() -> {
|
||||||
|
if (entry.getKey().equals(n)) {
|
||||||
|
group.selectToggle(b);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
if (entry.getKey().equals(value.getValue())) {
|
if (entry.getKey().equals(value.getValue())) {
|
||||||
b.setSelected(true);
|
group.selectToggle(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.core.charsetter.StreamCharset;
|
||||||
import io.xpipe.core.util.SecretValue;
|
import io.xpipe.core.util.SecretValue;
|
||||||
import io.xpipe.extension.I18n;
|
import io.xpipe.extension.I18n;
|
||||||
import io.xpipe.extension.fxcomps.Comp;
|
import io.xpipe.extension.fxcomps.Comp;
|
||||||
import io.xpipe.extension.fxcomps.CompStructure;
|
|
||||||
import io.xpipe.extension.fxcomps.impl.*;
|
import io.xpipe.extension.fxcomps.impl.*;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
@ -43,12 +42,14 @@ public class DynamicOptionsBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addTitle(String titleKey) {
|
public DynamicOptionsBuilder addTitle(String titleKey) {
|
||||||
return addTitle(I18n.observable(titleKey));
|
entries.add(new DynamicOptionsComp.Entry(
|
||||||
|
titleKey, null, new LabelComp(I18n.observable(titleKey)).styleClass("title-header")));
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addTitle(ObservableValue<String> title) {
|
public DynamicOptionsBuilder addTitle(ObservableValue<String> title) {
|
||||||
entries.add(new DynamicOptionsComp.Entry(
|
entries.add(new DynamicOptionsComp.Entry(
|
||||||
null, Comp.of(() -> new Label(title.getValue())).styleClass("title-header")));
|
null, null, Comp.of(() -> new Label(title.getValue())).styleClass("title-header")));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public class DynamicOptionsBuilder {
|
||||||
map.put(e, I18n.observable("extension." + e.getId()));
|
map.put(e, I18n.observable("extension." + e.getId()));
|
||||||
}
|
}
|
||||||
var comp = new ChoiceComp<>(prop, map, false);
|
var comp = new ChoiceComp<>(prop, map, false);
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable("extension.newLine"), comp));
|
entries.add(new DynamicOptionsComp.Entry("newLine", I18n.observable("extension.newLine"), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,7 @@ public class DynamicOptionsBuilder {
|
||||||
public DynamicOptionsBuilder addCharacter(
|
public DynamicOptionsBuilder addCharacter(
|
||||||
Property<Character> prop, ObservableValue<String> name, Map<Character, ObservableValue<String>> names) {
|
Property<Character> prop, ObservableValue<String> name, Map<Character, ObservableValue<String>> names) {
|
||||||
var comp = new CharChoiceComp(prop, names, null);
|
var comp = new CharChoiceComp(prop, names, null);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +89,7 @@ public class DynamicOptionsBuilder {
|
||||||
Map<Character, ObservableValue<String>> names,
|
Map<Character, ObservableValue<String>> names,
|
||||||
ObservableValue<String> customName) {
|
ObservableValue<String> customName) {
|
||||||
var comp = new CharChoiceComp(prop, names, customName);
|
var comp = new CharChoiceComp(prop, names, customName);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +97,7 @@ public class DynamicOptionsBuilder {
|
||||||
public DynamicOptionsBuilder addToggle(String nameKey,
|
public DynamicOptionsBuilder addToggle(String nameKey,
|
||||||
Property<Boolean> prop) {
|
Property<Boolean> prop) {
|
||||||
var comp = new ToggleGroupComp<>(prop, new SimpleObjectProperty<>(Map.of(Boolean.TRUE, I18n.observable("extension.yes"), Boolean.FALSE, I18n.observable("extension.no"))));
|
var comp = new ToggleGroupComp<>(prop, new SimpleObjectProperty<>(Map.of(Boolean.TRUE, I18n.observable("extension.yes"), Boolean.FALSE, I18n.observable("extension.no"))));
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable(nameKey), comp));
|
entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +105,7 @@ public class DynamicOptionsBuilder {
|
||||||
public <V> DynamicOptionsBuilder addToggle(
|
public <V> DynamicOptionsBuilder addToggle(
|
||||||
Property<V> prop, ObservableValue<String> name, Map<V, ObservableValue<String>> names) {
|
Property<V> prop, ObservableValue<String> name, Map<V, ObservableValue<String>> names) {
|
||||||
var comp = new ToggleGroupComp<>(prop, new SimpleObjectProperty<>(names));
|
var comp = new ToggleGroupComp<>(prop, new SimpleObjectProperty<>(names));
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ public class DynamicOptionsBuilder {
|
||||||
Property<V> prop, ObservableValue<String> name, Map<V, ObservableValue<String>> names, boolean includeNone
|
Property<V> prop, ObservableValue<String> name, Map<V, ObservableValue<String>> names, boolean includeNone
|
||||||
) {
|
) {
|
||||||
var comp = new ChoiceComp<>(prop, names, includeNone);
|
var comp = new ChoiceComp<>(prop, names, includeNone);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -122,49 +123,49 @@ public class DynamicOptionsBuilder {
|
||||||
Property<V> prop, ObservableValue<String> name, ObservableValue<Map<V, ObservableValue<String>>> names, boolean includeNone
|
Property<V> prop, ObservableValue<String> name, ObservableValue<Map<V, ObservableValue<String>>> names, boolean includeNone
|
||||||
) {
|
) {
|
||||||
var comp = new ChoiceComp<>(prop, names, includeNone);
|
var comp = new ChoiceComp<>(prop, names, includeNone);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addCharset(Property<StreamCharset> prop) {
|
public DynamicOptionsBuilder addCharset(Property<StreamCharset> prop) {
|
||||||
var comp = new CharsetChoiceComp(prop);
|
var comp = new CharsetChoiceComp(prop);
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable("extension.charset"), comp));
|
entries.add(new DynamicOptionsComp.Entry("charset", I18n.observable("extension.charset"), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addStringArea(String nameKey, Property<String> prop, boolean lazy) {
|
public DynamicOptionsBuilder addStringArea(String nameKey, Property<String> prop, boolean lazy) {
|
||||||
var comp = new TextAreaComp(prop, lazy);
|
var comp = new TextAreaComp(prop, lazy);
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable(nameKey), comp));
|
entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addString(String nameKey, Property<String> prop) {
|
public DynamicOptionsBuilder addString(String nameKey, Property<String> prop) {
|
||||||
var comp = new TextFieldComp(prop);
|
var comp = new TextFieldComp(prop);
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable(nameKey), comp));
|
entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addString(String nameKey, Property<String> prop, boolean lazy) {
|
public DynamicOptionsBuilder addString(String nameKey, Property<String> prop, boolean lazy) {
|
||||||
var comp = new TextFieldComp(prop, lazy);
|
var comp = new TextFieldComp(prop, lazy);
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable(nameKey), comp));
|
entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addString(ObservableValue<String> name, Property<String> prop) {
|
public DynamicOptionsBuilder addString(ObservableValue<String> name, Property<String> prop) {
|
||||||
var comp = new TextFieldComp(prop);
|
var comp = new TextFieldComp(prop);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addString(ObservableValue<String> name, Property<String> prop, boolean lazy) {
|
public DynamicOptionsBuilder addString(ObservableValue<String> name, Property<String> prop, boolean lazy) {
|
||||||
var comp = new TextFieldComp(prop, lazy);
|
var comp = new TextFieldComp(prop, lazy);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -178,11 +179,13 @@ public class DynamicOptionsBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addComp(String nameKey, Comp<?> comp, Property<?> prop) {
|
public DynamicOptionsBuilder addComp(String nameKey, Comp<?> comp, Property<?> prop) {
|
||||||
return addComp(I18n.observable(nameKey), comp, prop);
|
entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp));
|
||||||
|
if (prop != null) props.add(prop);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addComp(ObservableValue<String> name, Comp<?> comp, Property<?> prop) {
|
public DynamicOptionsBuilder addComp(ObservableValue<String> name, Comp<?> comp, Property<?> prop) {
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
if (prop != null) props.add(prop);
|
if (prop != null) props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -193,21 +196,21 @@ public class DynamicOptionsBuilder {
|
||||||
|
|
||||||
public DynamicOptionsBuilder addSecret(ObservableValue<String> name, Property<SecretValue> prop) {
|
public DynamicOptionsBuilder addSecret(ObservableValue<String> name, Property<SecretValue> prop) {
|
||||||
var comp = new SecretFieldComp(prop);
|
var comp = new SecretFieldComp(prop);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addInteger(ObservableValue<String> name, Property<Integer> prop) {
|
public DynamicOptionsBuilder addInteger(ObservableValue<String> name, Property<Integer> prop) {
|
||||||
var comp = new IntFieldComp(prop);
|
var comp = new IntFieldComp(prop);
|
||||||
entries.add(new DynamicOptionsComp.Entry(name, comp));
|
entries.add(new DynamicOptionsComp.Entry(null, name, comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicOptionsBuilder addInteger(String nameKey, Property<Integer> prop) {
|
public DynamicOptionsBuilder addInteger(String nameKey, Property<Integer> prop) {
|
||||||
var comp = new IntFieldComp(prop);
|
var comp = new IntFieldComp(prop);
|
||||||
entries.add(new DynamicOptionsComp.Entry(I18n.observable(nameKey), comp));
|
entries.add(new DynamicOptionsComp.Entry(nameKey, I18n.observable(nameKey), comp));
|
||||||
props.add(prop);
|
props.add(prop);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -239,12 +242,12 @@ public class DynamicOptionsBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Comp<? extends CompStructure<?>> buildComp() {
|
public DynamicOptionsComp buildComp() {
|
||||||
if (title != null) {
|
if (title != null) {
|
||||||
entries.add(
|
entries.add(
|
||||||
0,
|
0,
|
||||||
new DynamicOptionsComp.Entry(
|
new DynamicOptionsComp.Entry(
|
||||||
null, Comp.of(() -> new Label(title.getValue())).styleClass("title-header")));
|
null, null, Comp.of(() -> new Label(title.getValue())).styleClass("title-header")));
|
||||||
}
|
}
|
||||||
return new DynamicOptionsComp(entries, wrap);
|
return new DynamicOptionsComp(entries, wrap);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue